原理分析与算法描述

  • 待绘制的圆弧

    圆心在原点,半径为R的第一象限上的一段圆弧。且取(0,R)为起点,按顺时针方向绘制该1/8圆弧。

  • 决策方程
    F(x,y)=x2+y2−R2 F(x,y)=x^2+y^2-R^2 F(x,y)=x2+y2R2
    对于圆上的点,有F(x,y)=0;

    对于圆外的点,F(x,y)>0;

    对于圆内的点,F(x,y)<0。

在这里插入图片描述

M的坐标为:M(xi+1,yi−0.5)M(x_i+1,y_i-0.5)M(xi+1,yi0.5)

•当F(xM,yM)<0F(x_M,y_M)<0F(xM,yM)<0时,取Pu(xi+1,yi)P_u(x_i+1,y_i)Pu(xi+1,yi)

•当F(xM,yM)>0F(x_M,y_M)>0F(xM,yM)>0时,取Pd(xi+1,yi−1)P_d(x_i+1,y_i-1)Pd(xi+1,yi1)

•当F(xM,yM)=0F(x_M,y_M)=0F(xM,yM)=0时,约定取PuP_uPu

  • 构造判别式
    di=F(xM,yM)=F(xi+1,yi−0.5)=(xi+1)2+(yi−0.5)2−R2 d_i=F(x_M,y_M)=F(x_i+1,y_i-0.5)=(x_i+1)^2+(y_i-0.5)^2-R^2 di=F(xM,yM)=F(xi+1,yi0.5)=(xi+1)2+(yi0.5)2R2
    •当di≤0d_i≤0di0时,下一点取Pu(xi+1,yi)P_u(x_i+1,y_i)Pu(xi+1,yi)

    •当di>0d_i>0di>0时,下一点取Pd(xi+1,yi−1)P_d(x_i+1,y_i-1)Pd(xi+1,yi1)

  • 误差项的递推

    di<=0,di+1=F(xi+2,yi−0.5)=di+2xi+3d_i<=0,d_{i+1}=F(x_i+2,y_i-0.5)=d_i+2x_i+3di<=0,di+1=F(xi+2,yi0.5)=di+2xi+3;

    di>0,di+1=F(xi+2,yi−1.5)=di+2(xi−yi)+5d_i>0,d_{i+1}=F(x_i+2,y_i-1.5)=d_i+2(x_i-y_i)+5di>0,di+1=F(xi+2,yi1.5)=di+2(xiyi)+5;

    d0=F(1,R−0.5)=1.25−Rd_0=F(1,R-0.5)=1.25-Rd0=F(1,R0.5)=1.25R

  • 算法步骤

    1.输入圆的半径R。

    2.计算初始值d=1.25-R、x=0、y=R。

    3.绘制点(x,y)及其在八分圆中的另外七个对称点。

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

    5.当x<=y时,重复步骤3和4。否则结束。

代码实现

std::vector<Point> DrawCircle(Point center, float radius)
{
	std::vector<Point> points;
    int x = 0, y = radius;
    int d = 1.25 - radius;//决策变量初始值
    int xc = center.x, yc = center.y;
    while (y >= x) {//八对称点
        points.push_back({ xc + x, yc + y });
        points.push_back({ xc + x, yc - y });
        points.push_back({ xc - x, yc + y });
        points.push_back({ xc - x, yc - y });
        points.push_back({ xc + y, yc + x });
        points.push_back({ xc + y, yc - x });
        points.push_back({ xc - y, yc + x });
        points.push_back({ xc - y, yc - x });
        if (d <= 0) {//更新决策变量和坐标
            d = d + 2 * x + 3;
            x += 1;
        }
        else {
            d = d + 2 * (x - y) + 5;
            x += 1, y -= 1;
        }
    }
	return points;
}

结果展示

在这里插入图片描述

算法优化

  • 改进:用d-0.25代替d,减少浮点数运算
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐