65.9K
CodeProject 正在变化。 阅读更多。
Home

椭圆绘制算法

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.18/5 (9投票s)

2007年10月25日

2分钟阅读

viewsIcon

57799

downloadIcon

737

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

Screenshot - drwelpsalg.jpg

引言

首先,我必须说明我英语水平有限,这篇文章可能包含许多错误!

我现在正在开发一个完全独立于系统的图形库。我已经编写了许多绘制线条、点、矩形等的操作。目前所有操作都是基础的,以便以后可以优化它们以提高性能和速度。

今天早上我正在寻找一个绘制椭圆的算法。我访问了 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 段的值。

最后,我必须为这篇文章中所有错误道歉,因为这是我第一次使用英语写作!

最后,我希望您在阅读这些文字时能找到一些有用的和有趣的东西!

最后,感谢您阅读到这里 :)

历史

目前没有。

© . All rights reserved.