高手给剖析一下这个画圆的算法,谢谢
void DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crColour, BOOL bDashed)
{
const int nDashLength = 1;
LONG lError, lXoffset, lYoffset;
int nDash = 0;
BOOL bDashOn = TRUE;
//Check to see that the coordinates are valid
ASSERT( (p.x + lRadius <= LONG_MAX) && (p.y + lRadius <= LONG_MAX) );
ASSERT( (p.x - lRadius > = LONG_MIN) && (p.y - lRadius > = LONG_MIN) );
//Set starting values
lXoffset = lRadius;
lYoffset = 0;
lError = -lRadius;
do {
if (bDashOn) {
pDC-> SetPixelV(p.x + lXoffset, p.y + lYoffset, crColour);
pDC-> SetPixelV(p.x + lXoffset, p.y - lYoffset, crColour);
pDC-> SetPixelV(p.x + lYoffset, p.y + lXoffset, crColour);
pDC-> SetPixelV(p.x + lYoffset, p.y - lXoffset, crColour);
pDC-> SetPixelV(p.x - lYoffset, p.y + lXoffset, crColour);
pDC-> SetPixelV(p.x - lYoffset, p.y - lXoffset, crColour);
pDC-> SetPixelV(p.x - lXoffset, p.y + lYoffset, crColour);
pDC-> SetPixelV(p.x - lXoffset, p.y - lYoffset, crColour);
}
//Advance the error term and the constant X axis step
lError += lYoffset++;
//Check to see if error term has overflowed
if ((lError += lYoffset) > = 0)
lError -= --lXoffset * 2;
if (bDashed && (++nDash == nDashLength)) {
nDash = 0;
bDashOn = !bDashOn;
}
} while (lYoffset <= lXoffset);//Continue until halfway point
}
这个算法似乎比brensenham还简洁,实在是看不明白它的原理,请教!
[解决办法]
分成8个45度的弧线,然后利用对称性8段同时描点
建议去看一下图形学,里面应该有讲如何画圆弧
[解决办法]
下面是用Brensenham画半径r的圆,圆心(xc,yc),颜色为c:
procedure circle(xc,yc,r,c:integer);
var
d,u,v:integer;
begin
u:=0;
v:=r;
d:=3-2*r;
while u <=v do
begin
point8(u,v,xc,yc,c);
if d <0 then
d:=d+4*u+6
else
begin
d:=d+4*(u-v)+10;
v:=v-1;
end;
u:=u+1;
end;
if u=v then point8(u,v,xc,yc,c);
end;
其中point8(u,v,xc,yc,c)就是画对称的8个点.
[解决办法]
是八分法,没用过不知道效果如何。
[解决办法]
效果理想,不太可能有更理想的了.
[解决办法]
只用加减可以实现画圆吗???
这里面还真的看不出来。。
[解决办法]
计算机专业的
学过计算机控制原理的就应该知道了
可以看看这里,说得很仔细
单片机控制下步进电机画圆算法思考
http://blog.sina.com.cn/u/4a552627010005ww
[解决办法]
Brensenham画圆可以只用+,-,位移,不用乘,
即把4*u改为4左移2位,等
但乘2,乘4等乘法其实际效果与左移一样快.