方法一
一.设计思路
该实验利用中点算法和Bresenham算法寻找最逼近椭圆的理想像素集。
对于,判断下一点取
还是
,
先取中点,判断该中点在圆内还是圆外,
若在圆外,说明椭圆上的点离下方的像素点更近,
则下一个中点取;
图1 中点在圆外
若在圆内,说明椭圆上的点离上方像素点更近,则下一个中点取
。
图2 中点在圆内
则通过判断中点的位置来选择下一像素点。
二.具体思路
- 由于椭圆的对称性,我们将椭圆以象限分为四部分,再通过将
转变为
、
、
得到其他象限的部分。
glVertex2i(x, y); glVertex2i(-x, -y); glVertex2i(-x, y); glVertex2i(x, -y);
- 由于需要
,再将第一象限的椭圆分为两部分,一部分从x轴开始计算,一部分从y轴开始计算。
时,即
时,从x轴方向开始依次x++。
- 通过将椭圆方程构造成
,则将判断中点与椭圆上的点的位置转换为判断
的正负情况,用d表示该式。
- 可得d的初始值为
。
- 为了得到中点误差项,需计算
,
,当下一中点取
时,则中点误差项
;
- 同理可得,当下一中点取
时,
。
-
d = b * b - a * a * 0.25 + a * a * b;//求的d初值 while (b * b * x < a * a * y) //求导、以x为轴,|k|<1 { if (d < 0)//中点在圆内 { d + = b * b * (2 * x + 3); x++; } else //中点在圆外 { d + = b * b * (2 * x + 3) + a * a * (-2 * y + 2); x++; y--; } }
- 当
,且y>0时,为保证
,
,从y轴方向向下依次y--。 同理, 当从y轴方向开始计算时,将d的初始值替换为为
进行计算。
d = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
//从y轴方向开始计算,d的初始值
while (y > 0) //以y为轴,|k|<1
{
if (d <= 0)
{
d += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
x++;
y--;
}
else
{
d += a * a * (-2 * y + 3);
y--;
}
}
三.具体函数
void oval(int a, int b)
{
int x = 0, y = b;//从(0,b)点开始
float d;
d = b * b - a * a * 0.25 + a * a * b;3)//求的d初值
while (b * b * x < a * a * y) //求导、以x为轴,|k|<1
{
if (d < 0)//在圆外
{
d += b * b * (2 * x + 3);
x++;
}
else //在圆内
{
d += b * b * (2 * x + 3) + a * a * (-2 * y + 2);
x++;
y--;
}
glVertex2i(x, y);
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
//从y轴方向开始计算
d = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;//d初始
while (y > 0) //以y为轴,|k|<1
{
if (d <= 0)
{
d += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
x++;
y--;
}
else
{
d += a * a * (-2 * y + 3);
y--;
}
glVertex2i(x, y);
glVertex2i(-x, -y);
glVertex2i(-x, y);
glVertex2i(x, -y);
}
}
四.绘制效果
方法二
一.设计思路
将圆的坐标用变形为
来表示椭圆。
二.具体代码
void oval_circle(int r)
{
int x, y;
float d;
x = 0, y = r;
d = 1.25 - r;
glVertex2i(ax, by);
glVertex2i(-ax, -by);
glVertex2i(-ax, by);
glVertex2i(ax, -by);
glVertex2i(ay, bx);
glVertex2i(-ay, -bx);
glVertex2i(-ay, bx);
glVertex2i(ay, -bx);
while(x < y)
{
if(d < 0)
{
d = d + 2 * x + 3;
}
else
{
d = d + 2 * ( x - y ) + 5;
y--;
}
x++;
glVertex2i(ax, by);
glVertex2i(-ax, -by);
glVertex2i(-ax, by);
glVertex2i(ax, -by);
glVertex2i(ay, bx);
glVertex2i(-ay, -bx);
glVertex2i(-ay, bx);
glVertex2i(ay, -bx);
}
}
三.优点
减少了k<1,k>1的分类,只需要计算1/8图形,将效率提高了一倍。