第三讲:基本图元输出
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
y
d2 d1
yk
xk
Xk+1 Xk+2
3.2 画线算法
引入参数 △x=xb-xa △y=yb-ya m= △y/ △x pk= △x△d = △x(d1-d2)= △x( 2m(xk+1)-2yk+2b-1 )= 2△yxk-2△xyk+ 2△y+△x(2b-1) ,① 因△x >0,所以pk和△d同号,可作为判断△d 正负 号的参数。这里2△y+△x(2b-1)是常数,设 c= 2△y+△x(2b-1) 由① 得 pk= △x△d =2△yxk-2△xyk+c ② 同样 : pk+1=2△yxk+1-2△xyk+1+c pk+1 – pk= 2△y(xk+1-xk)-2△x(yk+1-yk)
3.3 贞缓冲的写入
前面我们用setpixel(x,y)函数在贞缓存的(x,y)处写入颜 色亮度。贞缓存在逻辑上是一个二维数组,物理上是 一个一维的连续空间,所以在setpixel(x,y)中要计算具 体的内存地址。下面介绍在扫描过程中贞缓存的内存 地址计算。 设(xmax,ymax)是光栅显示器的最大横坐标和最 大纵坐标(也是贞缓存矩阵的宽度和高度)。任意点 (x,y)的地址为: addr(x,y)=addr(0,0)+y(xmax+1)+x 沿扫描线移动,像素(x+1,y)处的帧缓冲器地址可从位 置(x,y)的地址做偏移来计算: addr(x+1,y)= addr(x,y)+1
P0=2△y-△x
3.2 画线算法
while(x<xEnd){ x++; if(p<0 ) p+=twoDy; else{ y++; * p+=twoDyDx; } setpixel(x,y);
} }
对于斜率大于1的情况下,将此算法调换x,y次序 即可,对于m<0的情况下,将*处的y++改为y-即可,而对于垂直和水平线可直接 画出线
3.1点和线
点在屏幕上的位置坐标用像素为单位,点的像素坐标只 能是整数。 所以,通过计算得到的中间点在屏幕上的坐标 都要取整数,如在线段上某点上计算的坐标是(10.48, 20.51),则点在屏幕上的位置是(10,21)。
线的离散化表示
3.2 画线算法
任何图元的绘制算法都要遵循的一个原则:尽量使绘 制速度加快,加快绘制速度的一个途径就是尽量减少 浮点运算和乘除运算。绘制线的基本思想是沿水平或 垂直方向,依次增加一个像素的长度,计算出相应的 另一个方向个上的增量,从而确定线上的某一个点的 屏幕坐标,电子枪点亮该点。
3.4圆的生成算法
起始位置(x0,y0)=(0,r)处的决策参数为 p0= fcircle(1,r-0.5)=5/4 –r 如果r为整数的话,可以舍入 p0= 1 –r 这是因为其后计算pk时增量都是整数,所以这样的 舍入不影响pk的符号。 中点画圆算法的步骤: 1. 输入圆半径r和圆心(xc,yc),并得到圆心在原点的圆周 上的第一点为:(x0,y0)=(0,r) 2. 计算决策参数的初始值: p0=5/4 –r
int dx=xb-xa,dy=yb-ya; int p=2*dy-dx; int twoDy=2*dy; int twoDyDx=2*(dy-dx); int x=xa,y=ya, xEnd; xEnd=xb; setpixel(x,y);
pk>0时, pk+1=pk+2(△y-△x) 当pk<0时, pk+1=pk+2△y
3.1点和线
在CRT显示器中,点的绘制是将程序中点的坐标转化 为屏幕上确定的位置,当扫描至该位置点时,开启电 子枪点亮该点荧光。在随即扫描显示器中,点在显示 列表中定义,根据点的坐标产生偏转电压,控制电子 枪的偏转并点亮该点的荧光。 线的绘制是根据定义线的两个端点,插值计算中间点 的位置,并点亮这些中间点。在随即扫描设备中,可 以产生连续的中间点绘制出光滑的线段。在CRT设备 中,需要将直线离散化成若干个点,根据线段的直线 方程计算出这些离散的中间点位置,并在扫描这些点 的位置上开启电子枪点亮荧光屏。
3.2 .1 DDA算法(digital drflerential analyzer)
假设定义直线段的两个端点的坐标为(x1,y1), (x2,y2),直线的斜截方程为
y=mx+b
3.2 画线算法
得:m=(y2-y1 )/(x2-x1) b=y1-mx1 设 在x方向上的增量为⊿x,则 ⊿y= m⊿x ① ⊿x = ⊿y/m ②
5 4 3 2 1 1 2 3 4 5 6 7
3.2 画线算法
以m<1为例,如下图所示。在Xk+1处 y=m Xk+1+b=m(Xk+1)+b; d1=y-yk =m(xk+1)+b-yk ; d2=yk+1 –y=yk+1-m(xk+1)-b ; ⊿d =d1-d2=2m(xk+1)-2yk+2b-1 ;
3.3 贞缓冲的写入
从(x,y)对角跳到下一条扫描线,(x+1,y+1)的帧缓冲 器地址的计算公式为: addr(x+1,y+1)=addr(x,y)+xmax+2 从(x,y)对竖直方向跳到下一条扫描线(x,y+1)的帧缓 冲器地址的计算公式为: addr(x,y+1)=addr(x,y)+xmax+1 这样,在光栅扫描过程中按扫描顺序,以增量的 方式计算贞缓存地址,就避免了乘法计算。
3.4圆的生成算法
3. 在每个xk位置处,从k=0开始,完成下列检测: 假如pk <0,中心在(0,0)的圆的下一个点为(xk+1,yk),且 pk+1= pk+2xk+1+1 否则,圆的下一个点为(xk+1, yk-1),且 pk+1= pk+2xk+1+1-2yk+1 其中:2xk+1=2xk+1,2yk+1=2yk-2 4. 确定在其它7个8分圆中的对称点 5. 将每个计算出的像素位置(x,y)移动到中心在(xc, yc)的 圆路径上,并画坐标值: x=xc+x y=yc+y 6. 重复步骤3到5,直至x≥y。
DDA算法的特点?——消除了乘法,但是有误差积累 和浮点计算。
3.2 画线算法
3.2.2 Bresenham算法
Bresenham算法的优点是指使用整形的增量来计算 点的坐标,所以速度更快,也易于硬件实现。
以斜率小于1的直线为例,如右 图是(1,1)到(6,4)的一条直 线段,当我们沿x轴每次递增1采样像 素,在绘制第二个点时,需要选择是 (2,2)还是(2,1),Bresenham 算法就是计算一个决策参数用于判断 哪一个像素点离直线最近。
3.4圆的生成算法
如图,为了求下一个扫描点的位置, 将下一个扫描点的两个候选点(xk+1,yk), (xk+1,yk-1)的中点坐标(xk+1,yk-0.5) 代入①式,如果在在圆外或圆上,则 选择(xk+1,yk),否则选(xk+1,yk-1) 引入决策参数pk pk= fcircle(xk+1,yk-0.5) =xk+12+ (yk-0.5)2-r2 ② 同样: pk+1=( xk+1+1)2+ (yk+1-0.5)2-r2 ③
3.2 画线算法
xk+1=xk+1 pk+1 – pk= 2△y(xk+1-xk)-2△x(yk+1-yk) pk+1=pk+ 2△y-2△x(yk+1-yk) 当pk>0时,yk+1-yk=1 pk+1=pk+2(△y-△x) 当pk<0时,yk+1-yk=0 pk+1=pk+2△y 根据②式可得 p0= 2△yxa-2△x(mxa+b)+ 2△y+△x(2b-1) = = 2△yxa-2 △x(△y/ △x )xa- 2△x b + 2△y+2△xb △x = 2△y-△x p0是从线段的起点x0 后的第一个采样点的决策值
Computer graphics
第三讲: 基本图元的光栅化(1) Output Primitives
山东师范大学传播学院 李大锦
2008.9.16
图像可以有多种方式来描述,在光栅设备上,任何的 图形都可以用一个指定亮度的各位置点的集合来表示。另 一方面我们也可以用一系列基本的图形对象来表示,这些 图形对象的的颜色和形状可以用像素点阵或一系列基本的 几何结构来描述。例如线段和内部填充颜色的多边形,显 示场景的时候,可以将像素点阵装入贞缓存,或者将定义 的基本几何结构扫描转换为像素的形式写入贞缓存。一些 图形软件包提供了一些基本函数用于描述输出基本几何结 构,这样的基本几何结构叫做基本输出图元。利用这些基 本输出图元可以组成复杂物体的显示。最简单的基本图元 是点和线,基本图元的是通过指定图元的坐标、颜色等要 显示的信息来定义的。将这样定义的基本图元按照其属性 转换为像素点阵的过程称为光栅化
3.4圆的生成算法
只考虑1/8圆,x从0到(R/2)1/2结束.、 首先,定义一个圆函数: fcircle(x,y)=x2+y2-r2 ① 则可按如下规则判断任意点(x,y)在圆上的位置 <0 (x,y)位于圆边界内 fcircle(x,y) =0 (x,y)位于圆边界上 >0 (x,y)位于圆边界外
候选点中点
3.4圆的生成算法
②-③ 得 pk+1=pk+2xk+1+(y2k+1-y2k)-(yk+1-yk)+1 很明显,yk+1的值取决于pk的符号。 pk>0 时yk+1=yk-1 pk<0 时yk+1=yk 所以 pk+2xk+1+1 pk<0 (增量为2xk+1+1 ) pk+1= pk+2xk+1+1-2yk+1 pk≥0 (增量为2xk+1-2yk+1 +1 )
y
x |m|<=1,按x轴方向采样
若|m|<=1则以⊿x作为步进的基础,取⊿x=1,计算相 应的y坐标,由①得 yk+1=yk+m
3.2 画线算法
若|m|>1,则以⊿y为步进的基础,取⊿y=1,计算相应 的x坐标,由②得 xk+1=xk+1/m 假设已经定义了底层函数 Setpixel(x,y),此函数用于向 贞缓存中坐标为(x,y)处按 指定的颜色写入颜色值,则DDA 算法可描述如下。
3.4圆的生成算法
另一种方法是采用极坐标法 x=rcosθ y=rsinθ 0≤θ≤360 θ按一定的增量步进,θ较大时,可以用沿着圆弧 画直线来代替圆弧。为了减少计算量,可以只画出 1/4圆或1/8圆,其他部分按对称计算得到。但是这种 方法同样计算量非常来自百度文库。
3.4.1中点画圆算法
和光栅画线算法中一样,以单位间隔取样并在每 个步长中确定离指定圆最近的像素位置。
|m|>1,按y轴方向采样
3.2 画线算法
void lineDDA (int xa, int ya, int xb, int yb) { int dx = xb - xa,; int dy = yb - ya,;int steps, k; float xincrement, yincrement;float x = xa,; float y = ya; if (abs (dx) > abs(dy) steps = abs (dx) ; else steps = abs (dy); xIncrement = dx / (float) steps; yIncrement = dy /(float) steps; setpixel (xa, ya ) ; for (k=0; k<steps; k++) { x += xIncrment; y += yIncrement; setpixel (round(x), round(y));//函数round(x)为将x四舍五入 } }
3.4圆的生成算法
圆是图形中常用的图形元素,多数的图形软件中都包 含了生成圆和圆弧的过程。 圆的方程: (x-xc)2+(y-yc)2=r2 圆的最简单的绘制方法是沿一个方向递增,计算出另 一个方向上的坐标。 y=(r2- (x-xc)2) ½ +yc 但是这样画出来的原在某些 位置有很多断点,计算量也 很大。
当 m<1时 yk+1
y
d2
d1
yk xk
Xk+1 Xk+2
3.2 画线算法
如果△d>0则在处选择点( Xk+1, yk+1),否则选择 (Xk+1, yk)。 取△x=xb-xa △y=yb-ya 则m= △y/ △x (xa , ya)和(xb , yb)是线段的两个端点。
当 m<1时
yk+1
3.2 画线算法
Bresenham算法的优点 从pk的计算公式可以看出, Bresenham算法只进行 加减运算,并且只进行的整数的运算,所以运算速度 很高,并且易于用硬件实现。
3.2 画线算法
Bresenham算法的实现(0<m<1,xb>xa)
void LineBres(int xa,int ya,int xb,int yb) {
d2 d1
yk
xk
Xk+1 Xk+2
3.2 画线算法
引入参数 △x=xb-xa △y=yb-ya m= △y/ △x pk= △x△d = △x(d1-d2)= △x( 2m(xk+1)-2yk+2b-1 )= 2△yxk-2△xyk+ 2△y+△x(2b-1) ,① 因△x >0,所以pk和△d同号,可作为判断△d 正负 号的参数。这里2△y+△x(2b-1)是常数,设 c= 2△y+△x(2b-1) 由① 得 pk= △x△d =2△yxk-2△xyk+c ② 同样 : pk+1=2△yxk+1-2△xyk+1+c pk+1 – pk= 2△y(xk+1-xk)-2△x(yk+1-yk)
3.3 贞缓冲的写入
前面我们用setpixel(x,y)函数在贞缓存的(x,y)处写入颜 色亮度。贞缓存在逻辑上是一个二维数组,物理上是 一个一维的连续空间,所以在setpixel(x,y)中要计算具 体的内存地址。下面介绍在扫描过程中贞缓存的内存 地址计算。 设(xmax,ymax)是光栅显示器的最大横坐标和最 大纵坐标(也是贞缓存矩阵的宽度和高度)。任意点 (x,y)的地址为: addr(x,y)=addr(0,0)+y(xmax+1)+x 沿扫描线移动,像素(x+1,y)处的帧缓冲器地址可从位 置(x,y)的地址做偏移来计算: addr(x+1,y)= addr(x,y)+1
P0=2△y-△x
3.2 画线算法
while(x<xEnd){ x++; if(p<0 ) p+=twoDy; else{ y++; * p+=twoDyDx; } setpixel(x,y);
} }
对于斜率大于1的情况下,将此算法调换x,y次序 即可,对于m<0的情况下,将*处的y++改为y-即可,而对于垂直和水平线可直接 画出线
3.1点和线
点在屏幕上的位置坐标用像素为单位,点的像素坐标只 能是整数。 所以,通过计算得到的中间点在屏幕上的坐标 都要取整数,如在线段上某点上计算的坐标是(10.48, 20.51),则点在屏幕上的位置是(10,21)。
线的离散化表示
3.2 画线算法
任何图元的绘制算法都要遵循的一个原则:尽量使绘 制速度加快,加快绘制速度的一个途径就是尽量减少 浮点运算和乘除运算。绘制线的基本思想是沿水平或 垂直方向,依次增加一个像素的长度,计算出相应的 另一个方向个上的增量,从而确定线上的某一个点的 屏幕坐标,电子枪点亮该点。
3.4圆的生成算法
起始位置(x0,y0)=(0,r)处的决策参数为 p0= fcircle(1,r-0.5)=5/4 –r 如果r为整数的话,可以舍入 p0= 1 –r 这是因为其后计算pk时增量都是整数,所以这样的 舍入不影响pk的符号。 中点画圆算法的步骤: 1. 输入圆半径r和圆心(xc,yc),并得到圆心在原点的圆周 上的第一点为:(x0,y0)=(0,r) 2. 计算决策参数的初始值: p0=5/4 –r
int dx=xb-xa,dy=yb-ya; int p=2*dy-dx; int twoDy=2*dy; int twoDyDx=2*(dy-dx); int x=xa,y=ya, xEnd; xEnd=xb; setpixel(x,y);
pk>0时, pk+1=pk+2(△y-△x) 当pk<0时, pk+1=pk+2△y
3.1点和线
在CRT显示器中,点的绘制是将程序中点的坐标转化 为屏幕上确定的位置,当扫描至该位置点时,开启电 子枪点亮该点荧光。在随即扫描显示器中,点在显示 列表中定义,根据点的坐标产生偏转电压,控制电子 枪的偏转并点亮该点的荧光。 线的绘制是根据定义线的两个端点,插值计算中间点 的位置,并点亮这些中间点。在随即扫描设备中,可 以产生连续的中间点绘制出光滑的线段。在CRT设备 中,需要将直线离散化成若干个点,根据线段的直线 方程计算出这些离散的中间点位置,并在扫描这些点 的位置上开启电子枪点亮荧光屏。
3.2 .1 DDA算法(digital drflerential analyzer)
假设定义直线段的两个端点的坐标为(x1,y1), (x2,y2),直线的斜截方程为
y=mx+b
3.2 画线算法
得:m=(y2-y1 )/(x2-x1) b=y1-mx1 设 在x方向上的增量为⊿x,则 ⊿y= m⊿x ① ⊿x = ⊿y/m ②
5 4 3 2 1 1 2 3 4 5 6 7
3.2 画线算法
以m<1为例,如下图所示。在Xk+1处 y=m Xk+1+b=m(Xk+1)+b; d1=y-yk =m(xk+1)+b-yk ; d2=yk+1 –y=yk+1-m(xk+1)-b ; ⊿d =d1-d2=2m(xk+1)-2yk+2b-1 ;
3.3 贞缓冲的写入
从(x,y)对角跳到下一条扫描线,(x+1,y+1)的帧缓冲 器地址的计算公式为: addr(x+1,y+1)=addr(x,y)+xmax+2 从(x,y)对竖直方向跳到下一条扫描线(x,y+1)的帧缓 冲器地址的计算公式为: addr(x,y+1)=addr(x,y)+xmax+1 这样,在光栅扫描过程中按扫描顺序,以增量的 方式计算贞缓存地址,就避免了乘法计算。
3.4圆的生成算法
3. 在每个xk位置处,从k=0开始,完成下列检测: 假如pk <0,中心在(0,0)的圆的下一个点为(xk+1,yk),且 pk+1= pk+2xk+1+1 否则,圆的下一个点为(xk+1, yk-1),且 pk+1= pk+2xk+1+1-2yk+1 其中:2xk+1=2xk+1,2yk+1=2yk-2 4. 确定在其它7个8分圆中的对称点 5. 将每个计算出的像素位置(x,y)移动到中心在(xc, yc)的 圆路径上,并画坐标值: x=xc+x y=yc+y 6. 重复步骤3到5,直至x≥y。
DDA算法的特点?——消除了乘法,但是有误差积累 和浮点计算。
3.2 画线算法
3.2.2 Bresenham算法
Bresenham算法的优点是指使用整形的增量来计算 点的坐标,所以速度更快,也易于硬件实现。
以斜率小于1的直线为例,如右 图是(1,1)到(6,4)的一条直 线段,当我们沿x轴每次递增1采样像 素,在绘制第二个点时,需要选择是 (2,2)还是(2,1),Bresenham 算法就是计算一个决策参数用于判断 哪一个像素点离直线最近。
3.4圆的生成算法
如图,为了求下一个扫描点的位置, 将下一个扫描点的两个候选点(xk+1,yk), (xk+1,yk-1)的中点坐标(xk+1,yk-0.5) 代入①式,如果在在圆外或圆上,则 选择(xk+1,yk),否则选(xk+1,yk-1) 引入决策参数pk pk= fcircle(xk+1,yk-0.5) =xk+12+ (yk-0.5)2-r2 ② 同样: pk+1=( xk+1+1)2+ (yk+1-0.5)2-r2 ③
3.2 画线算法
xk+1=xk+1 pk+1 – pk= 2△y(xk+1-xk)-2△x(yk+1-yk) pk+1=pk+ 2△y-2△x(yk+1-yk) 当pk>0时,yk+1-yk=1 pk+1=pk+2(△y-△x) 当pk<0时,yk+1-yk=0 pk+1=pk+2△y 根据②式可得 p0= 2△yxa-2△x(mxa+b)+ 2△y+△x(2b-1) = = 2△yxa-2 △x(△y/ △x )xa- 2△x b + 2△y+2△xb △x = 2△y-△x p0是从线段的起点x0 后的第一个采样点的决策值
Computer graphics
第三讲: 基本图元的光栅化(1) Output Primitives
山东师范大学传播学院 李大锦
2008.9.16
图像可以有多种方式来描述,在光栅设备上,任何的 图形都可以用一个指定亮度的各位置点的集合来表示。另 一方面我们也可以用一系列基本的图形对象来表示,这些 图形对象的的颜色和形状可以用像素点阵或一系列基本的 几何结构来描述。例如线段和内部填充颜色的多边形,显 示场景的时候,可以将像素点阵装入贞缓存,或者将定义 的基本几何结构扫描转换为像素的形式写入贞缓存。一些 图形软件包提供了一些基本函数用于描述输出基本几何结 构,这样的基本几何结构叫做基本输出图元。利用这些基 本输出图元可以组成复杂物体的显示。最简单的基本图元 是点和线,基本图元的是通过指定图元的坐标、颜色等要 显示的信息来定义的。将这样定义的基本图元按照其属性 转换为像素点阵的过程称为光栅化
3.4圆的生成算法
只考虑1/8圆,x从0到(R/2)1/2结束.、 首先,定义一个圆函数: fcircle(x,y)=x2+y2-r2 ① 则可按如下规则判断任意点(x,y)在圆上的位置 <0 (x,y)位于圆边界内 fcircle(x,y) =0 (x,y)位于圆边界上 >0 (x,y)位于圆边界外
候选点中点
3.4圆的生成算法
②-③ 得 pk+1=pk+2xk+1+(y2k+1-y2k)-(yk+1-yk)+1 很明显,yk+1的值取决于pk的符号。 pk>0 时yk+1=yk-1 pk<0 时yk+1=yk 所以 pk+2xk+1+1 pk<0 (增量为2xk+1+1 ) pk+1= pk+2xk+1+1-2yk+1 pk≥0 (增量为2xk+1-2yk+1 +1 )
y
x |m|<=1,按x轴方向采样
若|m|<=1则以⊿x作为步进的基础,取⊿x=1,计算相 应的y坐标,由①得 yk+1=yk+m
3.2 画线算法
若|m|>1,则以⊿y为步进的基础,取⊿y=1,计算相应 的x坐标,由②得 xk+1=xk+1/m 假设已经定义了底层函数 Setpixel(x,y),此函数用于向 贞缓存中坐标为(x,y)处按 指定的颜色写入颜色值,则DDA 算法可描述如下。
3.4圆的生成算法
另一种方法是采用极坐标法 x=rcosθ y=rsinθ 0≤θ≤360 θ按一定的增量步进,θ较大时,可以用沿着圆弧 画直线来代替圆弧。为了减少计算量,可以只画出 1/4圆或1/8圆,其他部分按对称计算得到。但是这种 方法同样计算量非常来自百度文库。
3.4.1中点画圆算法
和光栅画线算法中一样,以单位间隔取样并在每 个步长中确定离指定圆最近的像素位置。
|m|>1,按y轴方向采样
3.2 画线算法
void lineDDA (int xa, int ya, int xb, int yb) { int dx = xb - xa,; int dy = yb - ya,;int steps, k; float xincrement, yincrement;float x = xa,; float y = ya; if (abs (dx) > abs(dy) steps = abs (dx) ; else steps = abs (dy); xIncrement = dx / (float) steps; yIncrement = dy /(float) steps; setpixel (xa, ya ) ; for (k=0; k<steps; k++) { x += xIncrment; y += yIncrement; setpixel (round(x), round(y));//函数round(x)为将x四舍五入 } }
3.4圆的生成算法
圆是图形中常用的图形元素,多数的图形软件中都包 含了生成圆和圆弧的过程。 圆的方程: (x-xc)2+(y-yc)2=r2 圆的最简单的绘制方法是沿一个方向递增,计算出另 一个方向上的坐标。 y=(r2- (x-xc)2) ½ +yc 但是这样画出来的原在某些 位置有很多断点,计算量也 很大。
当 m<1时 yk+1
y
d2
d1
yk xk
Xk+1 Xk+2
3.2 画线算法
如果△d>0则在处选择点( Xk+1, yk+1),否则选择 (Xk+1, yk)。 取△x=xb-xa △y=yb-ya 则m= △y/ △x (xa , ya)和(xb , yb)是线段的两个端点。
当 m<1时
yk+1
3.2 画线算法
Bresenham算法的优点 从pk的计算公式可以看出, Bresenham算法只进行 加减运算,并且只进行的整数的运算,所以运算速度 很高,并且易于用硬件实现。
3.2 画线算法
Bresenham算法的实现(0<m<1,xb>xa)
void LineBres(int xa,int ya,int xb,int yb) {