3.2 直线段光栅化
3.2.1 数值微分算法
void LineDDA(int x1, int y1, int xn, int yn)
{
int dm=0;
if (abs(xn-x1)>= abs(yn-y1)
dm=abs(xn-x1);
else
dm=abs(yn-y1);
float dx=(float)(xn-x1)/dm;
float dy=(float)(yn-y1)/dm;
float x=x1;
float y=y1;
for (int i=0; i< dm; i++)
{
putpixel( (int)(x+0.5), (int)(y+0.5));
x+=dx;
y+=dy;
}
}
3.2.2 Bresenham画线法
void BresenhamLine(int x1, int y1, int xn, int yn)
{
int x, y, dx, dy, d, d1, d2;
dx = xn-x1;
dy = yn-y1;
d = 2*dy - dx;
d1 = 2*dy;
d2 = 2*(dy – dx);
x = x1;
y = y1;
putpixel (x,y);
while (x<xn)
{
x++;
if (d<0)
d += d1;
else
{
y += 1;
d += d2;
}
putpixel (x,y);
}
}
3.2.3 中点画线算法
void MidPointLine(int x1, int y1, int xn, int yn)
{
int dx, dy, d1, d2, d, x, y;
dx = xn - x1;
dy = yn - y1;
d = dx - 2dy;
dt = 2dx - 2dy;
db = -2dy;
x = x1; y = y1;
putpixel(x, y);
while (x < xn)
{
if (d < 0)
{
x++;
y++;
d += dt;
}
else
{
x++;
d += db;
}
putpixel(x, y);
}
}
3.3 圆弧光栅化
3.3.1 圆的对称性及其应用
void CirclePoints(int x0, int y0, int x, int y, int color)
{
putpixel (x0+x, y0+y, color);
putpixel (x0+y, y0+x, color);
putpixel (x0-y, y0+x, color);
putpixel (x0-x, y0+y, color);
putpixel (x0-x, y0-y, color);
putpixel (x0-y, y0-x, color);
putpixel (x0+y, y0-x, color);
putpixel (x0+x, y0-y, color);
}
3.3.2 Bresenham画圆算法
void Bres_Circle(int x0, int y0, double r)
{
int x,y,d;
x=0;
y=(int)r;
d=int(3-2*r);
while(x<y)
{
CirclePoints( x0,y0,x,y, color);
if(d<0)
d+=4*x+6;
else
{
d+=4*(x-y)+10;
y--;
}
x++;
}
if(x==y)
CirclePoints( x0,y0,x,y, color);
}
3.3.3 中点画圆算法
void MidPoint_Circle (int x0, int y0, int r, int color)
{
int x=0;
int y=r;
int d=1- r;
CirclePoints(x0, y0, x, y, color);
while ( x<y)
{
if (d<0)
d+=2*x+3;
else
{
d+= 2(x-y) +5;
y--;
}
x++;
CirclePoints( x0, y0, x, y, color);
}
}
3.4 区 域 填 充
3.4.2 种子填充算法
void FloodFill4 (int x, int y, int oldColor, int newColor)
{
if (getpixel(x, y)==oldColor)
{
setpixel(x, y, newColor);
FloodFill4(x-1, y, oldColor, newColor);
FloodFill4(x, y+1, oldColor, newColor);
FloodFill4(x+1, y, oldColor, newColor);
FloodFill4(x, y-1, oldColor, newColor);
}
}
void BoundaryFill4(int x, int y, int boundaryColor, int newColor)
{
int color = GetPixel(x,y);
if(color!= newColor && color!= boundaryColor)
{
setpixel (x, y, newColor);
BoundaryFill4(x,y+1, boundaryColor, newColor);
BoundaryFill4(x,y-1, boundaryColor, newColor);
BoundaryFill4(x-1,y, boundaryColor, newColor);
BoundaryFill4(x+1,y, boundaryColor, newColor);
}
}
3.7 裁 剪
3.7.2 直线裁剪
1. Cohen-Sutherland编码裁剪算法
# define LEFT 1
# define RIGHT 2
# define BOTTOM 4
# define TOP 8
void encode(float x, float y, float XL, float XR, float YB, float YT, int* code)
{
int c = 0;
if (x<XL) c = c|LEFT;
else if (x>XR) c = c|RIGHT;
if (y<YB) c = c|BOTTOM;
else if(y>YT) c = c|TOP;
*code=c;
return;
}
void C_S_LineClip(float *x1, float *y1, float *x2, float *y2, float XL,
float XR, float YB, float YT)
{
int code1,code2,code;
float x, y;
encode(x1, y1, XL, XR, YB, YT, &code1);
encode(x2, y2, XL, XR, YB, YT, &code1);
while (code1!=0 || code2!=0)
{
if ((code1 & code2)!=0) return;
code = code1;
if (code1==0) code = code2;
if ((LEFT & code)!=0) {
x = XL;
y = y1+(y2-y1)*(XL-x1)/(x2-x1);
}
else if ((RIGHT & code)!=0)
{
x = XR;
y = y1+(y2-y1)*(XR-x1)/(x2-x1);
}
else if ((BOTTOM & code)!=0)
{
y = YB;
x= x1+(x2-x1)*(YB-y1)/(y2-y1);
}
else if ((TOP & code)!=0)
{
y = YT;
x= x1+(x2-x1)*(YT-y1)/(y2-y1);
}
if (code==code1){
*x1 = x; *y1 = y;
encode(x, y, XL, XR, YB, YT, &code1);
}
else{
*x2 = x; *y2 = y;
encode(x, y, XL, XR, YB, YT, &code2);
}
}
return;
}
2.Liang-Barsky参数化裁剪算法
int L_B_LineClip(float *x1, float *y1, float *x2, float *y2, float XL,float XR, float YB, float YT)
{
float u1 = 0, u2 = 1, dx = x2 – x1, dy;
if (clipTest(-dx, x1-XL, &u1, &u2))
if (clipTest(dx, XR-x1, &u1, &u2))
{
dy=y2-y1;
if(clipTest(-dy, y1-YB, &u1, &u2))
if (clipTest(dy, YT-y1, &u1, &u2))
{
if(u2 < 1){
*x2 = x1+u2*dx;
*y2 = y1+u2*dy;
}
if(u1 > 0){
*x1 += u1*dx;
*y1 += u1*dy;
}
return 1;
}
}
return 0;
}
int clipTest(float p, float q,float* u1,float* u2)
{
float r;
int retVal = 1;
if (p < 0){
r= q/p;
if (r>*u2) retVal = 0;
else if (r>*u1) *u1 = r;
}
else if (p > 0){
r= q/p;
if (r<*u1) retVal = 0;
else if (r < *u2) *u2 = r;
}
else if (q < 0) retVal = 0;
return retVal;
}