椭圆绘制算法






2.18/5 (9投票s)
2007年10月25日
2分钟阅读

57799

737
在窗口上绘制椭圆的基本算法

引言
首先,我必须说明我英语水平有限,这篇文章可能包含许多错误!
我现在正在开发一个完全独立于系统的图形库。我已经编写了许多绘制线条、点、矩形等的操作。目前所有操作都是基础的,以便以后可以优化它们以提高性能和速度。
今天早上我正在寻找一个绘制椭圆的算法。我访问了 www.codeproject.com 并搜索了一篇文章,解释如何在不使用 Windows GDI 的情况下绘制椭圆。我什么也没找到!要么确实没有关于这个主题的文章,要么我在搜索过程中遗漏了什么。我想,为什么不写一篇文章来讨论这个主题,也许有人会阅读它并建议我改进方法!
使用代码
我上周编写的例程在屏幕上绘制一个由 N 段组成的椭圆。我将在这里展示基本版本。MyEllipseDraw 计算 N 个点的坐标并将它们用线条连接起来,最终形成一个椭圆。
MyDrawEllipse 有两个参数,分别是绘制椭圆的窗口句柄和用于在窗口上使用 GDI+ 绘制的设备上下文。
它首先准备绘制过程所需的对象和数据。nSeg 是一个全局变量,用于指定要绘制的椭圆的段数。
//A basic algorithm to draw an N segments ellipse on a window
// hWnd +> Handle to the window where the ellipse will be drawn
// hDC +> Device context to the window where the ellipse will be drawn
// nSeg +> A global variable contains the number of segments or points linked each other to form the ellipse
void MyDrawEllipse(HWND hWnd, HDC hDC)
{
double x, y, _x, _y, __x, __y, dx, dy, z, wx, hy;
RECT rc;
//Prepare objects and data
Graphics g(hDC);
Pen p(Color(0xff, 0, 0), 1.0); //Red
GetClientRect(hWnd, &rc);
z = 0.99; //Point coordinate affinity
dx = double(rc.right) / 2.0 - 1.0; //Half window height
dy = double(rc.bottom) / 2.0 - 1.0; //Half window width
wx = double(rc.right) / 2.0; //Ellipse center
hy = double(rc.bottom) / 2.0; //Ellipse center
for(int i = 0; i < int(nSeg); i++) {
x = wx * sin((double(i) / double(nSeg)) * (pi*2.0));
y = hy * cos((double(i) / double(nSeg)) * (pi*2.0));
if(i > 0) {
//Draw a line connecting the last point to the one being calculated now
g.DrawLine(&p, int(dx+_x+z), int(dy+-_y+z), int(dx+x+z), int(dy+-y+z));
} else {
//Save the first point coordinate to link it with the last one
__x = x;
__y = y;
}
//Save the actual point coordinate to link it with the next one
_x = x;
_y = y;
}
//Draw a line between the last point and the first one
g.DrawLine(&p, int(dx+x+z), int(dy+-y+z), int(dx+__x+z), int(dy+-__y+z));
/*
//I use the GDI+ DrawEllipse function to compare my algorithm with
//the one used by GDI+. Only the visual result is important for me now!
p.SetColor(Color(0, 0xff, 0));
g.DrawEllipse(&p, 0, 0, rc.right-1, rc.bottom-1);
*/
}
下载源代码后,将文件解压到目录中,查找 drwelpsalg.cpp 文件,该文件包含 MyDrawEllipse 例程。该文件包含 Win32 项目 AppWizard 生成的标准代码。我删除了所有注释,以便您能轻松阅读源代码。
当执行演示程序时,它会绘制一个调整后的椭圆,以填充主窗口的整个客户端区域。标题栏显示有关客户端区域和绘制椭圆的段数的信息。您可以单击左键来增加段数,或单击右键来减少段数。尝试小于 16 段的值。
最后,我必须为这篇文章中所有错误道歉,因为这是我第一次使用英语写作!
最后,我希望您在阅读这些文字时能找到一些有用的和有趣的东西!
最后,感谢您阅读到这里 :)
历史
目前没有。