多边形画圆算法和正多边形生成算法的原理是类似的,因此本文也可以作为正多边形绘制的参考。
算法思路
所谓的多边形画圆算法就是利用圆内接正多边形去逼近圆,当正多边形的边数足够多的时候,图形看起来就会比较圆。那么我们的实现方案就可以假设我们利用正n边形去逼近圆,计算其每一顶点的坐标位置,然后将这个正多边形绘制出来就可以得到“圆形”对象了。
下面我们在假设正n变形逼近圆且圆心位于原点的情况进行顶点坐标推算的分析。对于圆心不再原点的对象进行简单的坐标变换即可。
由于是正n边形,那么将该图形各顶点和中心位置连接形成的夹角均为,我们将这个弧度值记为θ。假设我们现在已知的圆上一点为(xpos, ypos), 它和x轴正方向之间的夹角为α,那么,有如下结果成立:
,此时我们对下一个绘制点进行推算,那么就有:
按照上述方式进行依次各顶点的计算,然后对各边进行绘制即可。
代码实现
void PolygonCircle(const vector<pair<int, int>> center, int radius, unsigned long color)
{
CClientDC dc(mView); //如果hDC为0时使用
//实测多边形边数等于24时,画出来的图形已经非常接近圆了
int n = 24;
double cosn = cos(2.0*PI/n);
double sinn = sin(2.0*PI/n);
double xbase = 0, ybase = radius;
int cx = center.first, cy = center.second;
std::vector<pair<int, int>>> v;
v.push_back(pair<int, int>(xbase + cx, ybase + cy));
for (int i = 1; i < n; i++)
{
double tmp = xbase;
xbase = tmp * cosn - ybase * sinn;
ybase = tmp * sinn + ybase * cosn;
v.push_back(pair<int, int>(xbase + cx, ybase + cy));
}
for (int i = 1; i <= n; i++) BresenhamLine(v[i % n], v[i - 1], color);
//BresenhamLine是在之前的博客中实现过的直线绘制算法,需要可以到专栏中去找
}