Computer Graphics (3) - Experiment 3: Circle Generation Algorithm

Experiment 3: Circle Generation Algorithm

3.1 Experimental purpose

(1) Understand DDA algorithm, midpoint circle method, Bresenham algorithm
(2) Master the usage of CDC class in VC++

3.2 Experiment content

(1) Class writing
(2) Complete DDA algorithm, midpoint circle method, Bresenham algorithm

3.3 Algorithm ideas

In plane analytic geometry, the equation of a circle can be described as (x–x0)2+(y–y0)2=R2, where (x0,y0) is the center coordinate and R is the radius of the circle. In particular, when (x0 , y0) is the coordinate center point, the circle equation can be simplified to x2+y2=R2. In computer graphics, circles, like straight lines, also have the problem of displaying or outputting on dot matrix output devices, so a set of raster scan conversion algorithms is also required. In order to simplify, we first consider the generation of a circle whose center is at the origin. For a circle whose center is not the origin, the circle at the corresponding position can be obtained by translation transformation of coordinates.
Before scan conversion, it is necessary to understand the characteristics of a circle, that is, the octant of a circle. As shown in the following figure:
insert image description herethe circle whose center is at the origin has four symmetry axes x=0, y=0, x=y and x=-y. If the point P(x, y) on the arc is known, it can be Seven symmetry points of four symmetry axes: (x,-y), (-x,y), (-x,-y), (y,x), (y,-x), (-y,x) , (-y,-x), this property is called octant symmetry. Therefore, as long as one-eighth of the arc can be drawn, the whole circle can be obtained by using the principle of symmetry.
There are several easier ways to get the scan conversion of a circle, first of all, the Cartesian coordinate method. Known circle equation: x2+y2=R2, if x is taken as the independent variable, solve y.
When generating a circle, first scan and convert a quarter of the circumference, let the independent variable x increase from 0 to R in unit steps, and solve y at each step, and then call the point function to draw a circle point by point. But in doing so, due to the power and square root operations, and both are floating-point operations, the algorithm is not efficient. And when x is close to the value of R (the center of the circle is at the origin), near the point (R, 0) on the circumference, since the slope of the circle tends to infinity, because the floating point number needs to be rounded, there is a larger circle on the circumference. gap. Next, we will introduce the polar coordinate method. Assuming that the angle between a point P(x, y) on the arc on the Cartesian coordinate system and the x-axis is θ, the polar coordinate equation of the circle is:
x=Rcosθ
y=Rsinθ The
circle is generated by using The eighth symmetry of the circle makes it possible to draw a full circle if the value range of the independent variable θ is (0, 45°).
(1) Angle numerical differentiation method (DDA method):
The parametric equation of the circle in the rectangular coordinate system is:
{█(x=x0+Rcosθ@y=y0+Rsinθ)┤
Derived from the above formula
x-xc=-Rsinθdθ
y- yc=RcosθdθWhen
x-xc is incremented by 1 from -r to r, the y-coordinate of the corresponding circle point can be obtained. However, the points on the circle obtained in this way are not uniform, and the larger |x-xc| is, the longer the circle distance between the corresponding circle points is. Therefore, the resulting circle is not aesthetically pleasing.
(2) The method of drawing a circle at the midpoint:
consider the center of the circle at the origin, and the radius of R is an eighth arc in the first quadrant, clockwise from the point (0, R) to the point (R/, R/). Determine this arc. Assuming that a point Pi(xi,yi) is already the closest point on the arc to the actual arc, then the next point of Pi can only be either P1 on the right or P2 on the lower right, as shown in the following figure :
insert image description hereConstruct the discriminant function:
F(x,y)=x2+y2–R2
When F(x,y)=0, it means the point is on the circle, when F(x,y)>0, it means the point is outside the circle, when F(x,y)<0 means the point is inside the circle. If M is the midpoint of P1 and P2, then the coordinate of M is (xi+1, yi–0.5), when F(xi+1, yi–0.5) < 0, point M is inside the circle, indicating that point P1 is far from The actual arc is closer and should take P1 as the next point of the circle. In the same way, when F(xi+1,yi–0.5)>0, P2 is closer to the actual arc, and P2 should be taken as the next point. When F(xi+1,yi–0.5)=0, both P1 and P2 can be used as the next point of the circle, and the algorithm agrees to take P2 as the next point.
(3) Bresenham's circle drawing algorithm:
If the discriminant can be reduced to integer operations, the calculation can be simplified and the efficiency can be improved. So people have made various improvements to the midpoint circle method, one of which is to change the initial value of d from 1.25–R to 1–R, considering that the radius R of the circle is always greater than 2, so this modification will not affect The sign of the initial value of d, while avoiding floating-point operations. Another method is to double the calculation of d and change the initial value to 3-2R, which avoids floating-point operations, and the multiplication by two can also be quickly replaced by shifting, using 3-2R as the initial value of the improvement Algorithm, also known as Bresenham's algorithm.

3.4 Flowchart

(1) Angle numerical differentiation method (DDA method):
insert image description here(2) Midpoint circle drawing method:
insert image description here(3) Bresenham drawing circle algorithm:
insert image description here

3.5 Experimental steps

(1) Angle numerical differentiation method (DDA method):
The parametric equation of the circle in the rectangular coordinate system is:
{█(x=x0+Rcosθ@y=y0+Rsinθ)┤
Derived from the above formula
x-xc=-Rsinθdθ
y- yc=Rcosθdθ
Derivation:
xn+1=xn-(yn-y0)dθ
yn+1=yn-(xn-x0)dθ
(2) Midpoint circle method:
1) Construct the discriminant function: F(x,y)= x2+y2–R2.
When F(x,y)=0, it means the point is on the circle, when F(x,y)>0, it means the point is outside the circle, and when F(x,y)<0, it means the point is inside the circle.
If M is the midpoint of P1 and P2, then the coordinate of M is (xi+1, yi–0.5), when F(xi+1, yi–0.5) < 0, point M is inside the circle, indicating that point P1 is far from The actual arc is closer and should take P1 as the next point of the circle.
In the same way, when F(xi+1,yi–0.5)>0, P2 is closer to the actual arc, and P2 should be taken as the next point. When F(xi+1,yi–0.5)=0, both P1 and P2 can be used as the next point of the circle, and the algorithm agrees to take P2 as the next point.
2) Bring the coordinates of M point (xi+1, yi–0.5) into the discriminant function F(x,y) to obtain the discriminant d:
d=F(xi+1,yi–0.5)=(xi+1)2 +(yi–0.5)2–R2
3) If d<0, then take P1 as the next point, and the discriminant of the next point of P1 is:
d'=F(xi+2,yi–0.5)= (xi+2)2+(yi–0.5)2–R2
is expanded and d is brought into the recurrence relation of the discriminant:
d'=d+2xi+3
If d>0, then take P2 as the next point, and the discriminant of the next point of P2 is:
d'=F(xi+2,yi–1.5)=(xi+2)2+(yi–1.5 )2–R2
is expanded and d is brought into the recurrence relation to obtain the discriminant:
d'=d+2(xi-yi)+5
4) In particular, at the first point of the first quadrant (0, R), the initial value d0 of the discriminant d can be deduced:
d0=F(1,R–0.5)=1–(R–0.5)2–R2=1.25-R
Considering that the center of the circle is not at the origin, it is necessary to correct the The calculated coordinates are translated.
(3) Bresenham's circle drawing algorithm:
1) Construct the discriminant function: F(x,y)=x2+y2-R2.
When F(x,y)=0, it means the point is on the circle, when F(x,y)>0, it means the point is outside the circle, and when F(x,y)<0, it means the point is inside the circle.
If M is the midpoint of P1 and P2, then the coordinate of M is (xi+1, yi–0.5), when F(xi+1, yi–0.5) < 0, point M is inside the circle, indicating that point P1 is far from The actual arc is closer and should take P1 as the next point of the circle.
In the same way, when F(xi+1,yi–0.5)>0, P2 is closer to the actual arc, and P2 should be taken as the next point. When F(xi+1,yi–0.5)=0, both P1 and P2 can be used as the next point of the circle, and the algorithm agrees to take P2 as the next point.
2) Bring the coordinates of M point (xi+1, yi–0.5) into the discriminant function F(x,y) to obtain the discriminant d:
d=F(xi+1,yi–0.5)=(xi+1)2 +(yi–0.5)2–R2
3) If d<0, then take P1 as the next point, and the discriminant of the next point of P1 is:
d'=F(xi+2,yi–0.5)= (xi+2)2+(yi–0.5)2–R2
After expansion, bring d into the recurrence relation of the discriminant:
d'=d+4xi+6
If d>0, then take P2 as the next point, and the discriminant of the next point of P2 is:
d' =F(xi+2,yi–1.5)=(xi+2)2+(yi–1.5)2–R2 After
expansion, bring d into the recurrence relation to obtain the discriminant:
d'=d+4(xi -yi)+10
4) In particular, at the first point (0, R) of the first quadrant, the initial value d0 of the discriminant d can be deduced:
d0=F(1,R–0.5)=1 –(R–0.5)2–R2=3-2R
Considering that the center of the circle is not at the origin, it is necessary to translate the calculated coordinates.

3.6 Experimental code

(1) Angle DDA circle generation algorithm

/
//角度DDA圆生成算法
/
void CLiHuchenView::OnDdacircle() 
{
    
    
	// TODO: Add your command handler code here
	CDC *pDC=GetDC();//获取设备指针
	int xc=200,yc=200,r=50,c=RGB(0,0,255);///定义圆心,角度,半径,圆的颜色蓝色
    int x=0,y=r,n=r; //赋初值
	double rc = (double)r; //修改类型
    double z=1.0/rc; //得到微分角度
    double a=x,b=y; //将x,y分别赋予a,b
    double tmp; //定义变量
    while(n > 0)
	{
    
    
		//八个区域点,画点
	    pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
     	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
	    pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
    	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
    	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
    	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
    	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
    	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)

        tmp=a;
        a-=b*z; //计算下一点横坐标
        b+=tmp*z; //计算下一点纵坐标
        x = (int)(a);
        y = (int)(b);
        n--;
	}
    if(x == y)
	{
    
    
		//八个区域点,画点
        pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
     	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
	    pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
    	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
    	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
    	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
    	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
    	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)
	}
	
	ReleaseDC(pDC);//指针释放
}

(2) Midpoint circle generation algorithm:

/
//中点圆生成算法
/
void CLiHuchenView::OnMidpointcircle() 
{
    
    
	// TODO: Add your command handler code here
	CDC *pDC=GetDC();//获取设备指针
	int xc=300,yc=300,r=50,c=RGB(255,0,0);///定义圆心,半径,圆的颜色红色
	int x,y;//定义变量x,y
	float d;//定义中点带入圆的值d
	x=0;y=r;d=1.25-r;//赋初值

	//八个区域点,画点
    pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
	pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)

	//画圆
	while(x<=y)
	{
    
    
		//判断d的正负
		if(d<0)
		{
    
    
			d+=2*x+3;
		}
		else
		{
    
    
			d+=2*(x-y)+5;
			y--;
		}
		x++;
	    pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
     	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
	    pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
    	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
    	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
    	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
    	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
    	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)
	}
	ReleaseDC(pDC);//指针释放
}

(3) Bresenham circle generation algorithm:

/
//Bresenham圆生成算法
/
void CLiHuchenView::OnBresenhamcircle() 
{
    
    
	// TODO: Add your command handler code here
	CDC *pDC=GetDC();//获取设备指针
	int xc=100,yc=100,r=50,c=RGB(0,255,0);///定义圆心,半径,圆的颜色绿色
	int x=0,y=r,p=3-2*r;//赋初值

	//画圆
	while(x<y)
	{
    
    
		//八个区域点,画点
        pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
    	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
    	pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
    	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
    	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
    	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
    	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
    	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)

		//判断p的正负
		if(p<0)
		{
    
    
			p+=4*x+6;
		}
		else
		{
    
    
			p+=4*(x-y)+10;
			y--;
		}
		x++;
		if(x==y)
	    pDC->SetPixel((xc+x),(yc+y),c);//(x,y)
     	pDC->SetPixel((xc-x),(yc+y),c);//(-x,y)
	    pDC->SetPixel((xc+x),(yc-y),c);//(x,-y)
    	pDC->SetPixel((xc-x),(yc-y),c);//(-x,-y)
    	pDC->SetPixel((xc+y),(yc+x),c);//(y,x)
    	pDC->SetPixel((xc-y),(yc+x),c);//(-y,x)
    	pDC->SetPixel((xc+y),(yc-x),c);//(y,-x)
    	pDC->SetPixel((xc-y),(yc-x),c);//(-y,-x)
	}
	ReleaseDC(pDC);//指针释放	
}

3.7 Display of experimental results

insert image description hereRed: Midpoint Line Algorithm
Green: Bresenham's Algorithm
Blue: Angle Differentiation Method (DDA Method)

Guess you like

Origin blog.csdn.net/chengzilhc/article/details/106728757