📅  最后修改于: 2020-12-20 09:38:40             🧑  作者: Mango
这是一种增量方法,用于扫描转换以标准位置为原点的椭圆,即长轴和短轴平行于坐标系轴。它与中点圆算法非常相似。由于四向对称性,我们需要考虑第一象限中的整个椭圆曲线。
首先,我们重写椭圆方程并定义函数f,该函数可用于确定两个候选像素之间的中点是在椭圆的内部还是外部:
现在将椭圆曲线从(0,b)到(a,0)在点Q处分成两部分,曲线的斜率是-1。
曲线的斜率由f(x,y)= 0定义其中fx&fy是f(x,y)关于x&y的偏导数。
我们有fx = 2b 2 x,fy = 2a 2 y& 因此,我们可以在扫描转换过程中监视斜率值以检测Q。我们的起点是(0,b)
假设在进入步骤i时最后一次扫描转换后的像素的坐标为(x i ,y i )。我们将选择T(x i + 1 ,y i )或S(x i + 1 ,y i-1 )作为下一个像素。 T&S的中点用于定义以下决策参数。
pi = f(x i + 1 ),y i- )
pi = b 2 (x i + 1 ) 2 + a 2 (y i- ) 2 -a 2 b 2
如果pi <0,则中点在曲线内,我们选择像素T。
如果pi> 0,则中点位于曲线的外部或曲线上,我们选择像素S。
下一步的决策参数是:
p i + 1 = f(x i + 1 + 1,y i + 1- )
= b 2 (x i + 1 +1) 2 + a 2 (y i + 1- ) 2 -a 2 b 2
由于x i + 1 = xi + 1,我们有
p i + 1 -pi = b 2 [(((x i + 1 +1) 2 + a 2 (y i + 1- ) 2- (y i- ) 2 ]
p i + 1 = pi + 2b 2 x i + 1 + b 2 + a 2 [(y i + 1- ) 2- (y i- ) 2 ]
如果选择T为像素(pi <0),则y i + 1 = yi。
如果选择S为像素(pi> 0),则y i + 1 = yi-1。这样我们可以表达
P I + 1在PI和方面(X I + 1,Y i + 1的):P I + 1 = PI + 2B 2 X I + 1 + B 2如果PI <0 = PI + 2B 2×i + 1的如果pi> 0,则+ b 2 -2a 2 y i + 1
递归表达式的初始值可以通过用(0,b)评估pi的原始定义来获得:
p1 =(b 2 + a 2 (b- ) 2 -a 2 b 2
= B 2 -A 2 B + A 2/4
假设像素(x j y j )在进入步骤j时刚刚进行了扫描转换。下一个像素是U(x j ,y j -1)或V(x j + 1,y j -1)。连接U&V的水平线的中点用于定义决策参数:
q j = f(x j + ,y j -1)
q j = b 2 (x j + ) 2 + a 2 (y j -1) 2 -a 2 b 2
如果q j <0,则中点在曲线内,我们选择像素V。
如果QĴ≥0,中点的曲线之外,我们选择像素U.Decision参数下一步是:
q j + 1 = f(x j + 1 + ,y j + 1 -1)
= b 2 (x j + 1 + ) 2 + a 2 (y j + 1 -1) 2 -a 2 b 2
由于y j + 1 = y j -1,我们有
q j + 1 -q j = b 2 [(x j + 1 + ) 2- (x j + ) 2 ] + a 2 (y j + 1 -1) 2- (y j + 1 ) 2 ]
q j + 1 = q j + b 2 [(x j + 1 + ) 2- (x j + ) 2 ] -2a 2 y j + 1 + a 2
如果选择V作为像素(qj <0),则x j + 1 = xj。
如果选择U作为像素(pi> 0),则x j + 1 = xj。这样我们可以表达
q J + 1在Q j的术语和(x j + 1,Y J + 1):
q j + 1 = q j + 2b 2 x j + 1 -2a 2 y j + 1 + a 2如果qj <0
= q j -2a 2 y j + 1 + a 2如果qj> 0
使用qj的原始定义计算递归表达式的初始值。并且为曲线的第1部分选择的最后一个像素的(x k y k)坐标:
q1 = f(x k + ,y k -1)= b 2 (x k + ) 2 -a 2 (y k -1) 2 -a 2 b 2
#include
#include
#include
#include
#include
#include
class bresen
{
float x,y,a, b,r,p,h,k,p1,p2;
public:
void get ();
void cal ();
};
void main ()
{
bresen b;
b.get ();
b.cal ();
getch ();
}
void bresen :: get ()
{
cout<<"\n ENTER CENTER OF ELLIPSE";
cout<<"\n ENTER (h, k) ";
cin>>h>>k;
cout<<"\n ENTER LENGTH OF MAJOR AND MINOR AXIS";
cin>>a>>b;
}
void bresen ::cal ()
{
/* request auto detection */
int gdriver = DETECT,gmode, errorcode;
int midx, midy, i;
/* initialize graphics and local variables */
initgraph (&gdriver, &gmode, " ");
/* read result of initialization */
errorcode = graphresult ();
if (errorcode ! = grOK) /*an error occurred */
{
printf("Graphics error: %s \n", grapherrormsg (errorcode);
printf ("Press any key to halt:");
getch ();
exit (1); /* terminate with an error code */
}
x=0;
y=b;
// REGION 1
p1 =(b * b)-(a * a * b) + (a * a)/4);
{
putpixel (x+h, y+k, RED);
putpixel (-x+h, -y+k, RED);
putpixel (x+h, -y+k, RED);
putpixel (-x+h, y+k, RED);
if (p1 < 0)
p1 += ((2 *b * b) *(x+1))-((2 * a * a)*(y-1)) + (b * b);
else
{
p1+= ((2 *b * b) *(x+1))-((2 * a * a)*(y-1))-(b * b);
y--;
}
x++;
}
//REGION 2
p2 =((b * b)* (x + 0.5))+((a * a)*(y-1) * (y-1))-(a * a *b * b);
while (y>=0)
{
If (p2>0)
p2=p2-((2 * a * a)* (y-1))+(a *a);
else
{
p2=p2-((2 * a * a)* (y-1))+((2 * b * b)*(x+1))+(a * a);
x++;
}
y--;
putpixel (x+h, y+k, RED);
putpixel (-x+h, -y+k, RED);
putpixel (x+h, -y+k, RED);
putpixel (-x+h, y+k, RED);
}
getch();
}
输出: