计算机图形学-直线,圆,椭圆扫描转换算法

1. 直线的扫描转换

1.1 DDA算法

增量算法,每一步都需要进行舍入取整,不利于硬件实现

使用C++代码:

void DDALine(int x0,int y0,int x1,int y1)
{
    int dx,dy,epsl,k;
    float x,y,xIncre,yIncre;
    dx=x1-x0;
    dy=y1-y0;
    x=x0;
    y=y0;
    if(abs(dx)>abs(dy))   //abs()函数为取绝对值函数
        espl=abs(dx);
    else
        espl=abs(dy);
    xIncre=(float)dx/(float)epsl;
    yIncre=(float)dy/(float)epsl;
    
    for(k=0;k<=epsl;k++)
    {
        putpixel(int(x+0.5),int(y+0.5);   //画点
        x+=xIncre; 
        y+=yIncre;   //寻找下一个点
    }
}

1.2 中点Bresenham算法

每次在最大位移方向上走一步,另一个方向是否走步取决于误差项的判别

当0

void MidBresenhamLine(int x0,int y0,int x1,int y1,int color)
{
    int dx,dy,d,UpIncre,DownIncre,x,y;
    if(x0

1.3 Bresenham算法

在误差项上进行替换

仍旧是0

void BresenhamLine(int x0, int y0; int x1, int y1)
{
	int x, y, dx, dy, e;
	dx = x1 - x0;
	dy = y1 - y0;
	e = -dx;  x = x0; y = y0;
	while (x <= x1)
	{
		putpixel(x, y, color);
		x++;
		e = e + 2 * dy;
		if (e > 0)
		{
			y++;
			e = e - 2 * dx;
		}
	}
}

2. 圆的扫描转换

2.1 八分法画圆

只要扫描转换圆的八分之一即可根据圆的对称性画出整个圆。

八分法画圆程序(以原点为坐标):

void Circle(int x, int y, int color)
{
	putpixel(x, y, color);
	putpixel(-x, y, color);
	putpixel(x, -y, color);
	putpixel(-x, -y, color);
	putpixel(y, x, color);
	putpixel(-y, x, color);
	putpixel(y, -x, color);
	putpixel(-y, -x, color);
	
}

以任意点为原点时:

void Circle(int x0,int y0,int x, int y, int color)
{
	putpixel(x0+x, y0+y, color);
	putpixel(x0-x, y0+y, color);
	putpixel(x0+x, y0-y, color);
	putpixel(x0-x, y0-y, color);
	putpixel(y0+y, x0+x, color);
	putpixel(y0-y, x0+x, color);
	putpixel(y0+y, x0-x, color);
	putpixel(y0-y, x0-x, color);
	
}

2.2 中点Bresenham画圆算法

步骤如下:

① 输入圆的半径R

② 计算初始值 d=1-R, x=0, y=R

③ 绘制点(x,y)及其在八分圆中的另外7个对称点

④ 判断d的符号。若d<0,则先将d更新为d+2x+3,再将(x,y)更新为(x+1,y);否则,先将d更新为d+2(x-y)+5;再将(x,y)更新为(x+1.y-1)

⑤ 当x

代码如下:

void MidBresenhamCircle(int r, int color)
{
	int x, y, d;
	x = 0; y = r; d = 1 - r;
	while (x <= y)   //判断是否结束
	{
		Circle(x, y, color);//调用八分法画圆
		if (d < 0)
			d += 2 * x + 3;
		else
		{
			d += 2 * (x - y) + 5;
			y--;
		}
		x++;
	}
}

3. 椭圆的扫描转换

3.1 椭圆的中点Bresenham算法

与圆的扫描转换方法类似,但是需要判断切线的斜率

代码如下:

void Ellipse(int x, int y, int color)  //四分法画椭圆
{
	putpixel(x, y, color);
	putpixel(-x, y, color);
	putpixel(x, -y, color);
	putpixel(-x, -y, color);
}

void MidBresenhamEllipse(int a, int b, int color)
{
	int x, y;
	float d1, d2;
	x = 0; y = b;
	d1 = b * b + a * a * (-b + 0.25);
	Ellipse(x, y, color);   //调用四分法画圆
	while (b * b * (x + 1) < a * a * (y - 0.5))   //椭圆上半部分
	{
		if (d1 <= 0)
		{
			d1 += b * b * (2 * x + 3);
			x++;
		}
		else
		{
			d1 += b * b * (2 * x + 3) + a * a * (-2 * y + 2);
			x++;
			y--;
		}
		Ellipse(x, y, color);
	}
	//椭圆的下半部分
	d2 = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
	while (y > 0)
	{
		if (d2 <= 0)
		{
			d2 += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
			x++;
			y--;
		}
		else
		{
			d2 += a * a * (-2 * y + 3);
			y--;
		}
		Ellipse(x, y, color);
	}
}

 

你可能感兴趣的:(#,计算机图形学,c++,图形学,算法)