在我的程序中,我正在使用带有以下代码的中点圆算法渲染圆圈。
void drawcircle(int x0, int y0, int radius)
{
int x = radius-1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
while (x >= y)
{
putpixel(x0 + x, y0 + y);
putpixel(x0 + y, y0 + x);
putpixel(x0 - y, y0 + x);
putpixel(x0 - x, y0 + y);
putpixel(x0 - x, y0 - y);
putpixel(x0 - y, y0 - x);
putpixel(x0 + y, y0 - x);
putpixel(x0 + x, y0 - y);
if (err <= 0)
{
y++;
err += dy;
dy += 2;
}
if (err > 0)
{
x--;
dx += 2;
err += (-radius << 1) + dx;
}
}
}
但我的问题是,是否可以让此功能以相同的方式工作,但将圆圈分成4个单独的部分?即,不是渲染正常的圆圈,它看起来有点像这样
答案 0 :(得分:0)
你实现了8个子部分相遇的重叠像素。圆圈的直径也是错误的(应该始终是因为半径* 2),这是一些重叠的原因。
要固定大小并删除重叠,我将圆圈的一半移出(向右下方)一个像素,并防止渲染最后一个迭代像素的一半。
此时不需要语句if(err <= 0)
,因为此时err
将始终满足该条件。 y偏移每次迭代增加1个像素,err
将在x需要步进时找到。
通过这个解决你的问题关于在圆圈中放置洞。您只需要一个计数器来倒数您想要跳过的像素数。虽然该计数器是> 0不绘制任何像素。
我将其作为第4个参数hole
添加到下面的代码段中。一个int
,是圆圈顶部,底部,左侧和右侧孔洞尺寸的一半。
因此,如果你想要一个20像素的洞,那么最后一个参数是10。
见右下图。
请注意,如果您将洞的最大尺寸设为更大,则不会绘制像素。sin(PI / 4) * radius
作为旁注,绘制的像素数(没有孔)约为sin(PI / 4) * radius * 8 - 4
,几乎比圆周小10%。
void drawcircle(int x0, int y0, int radius, int hole) {
int x = radius-1;
int y = 0;
int dx = 1;
int dy = 1;
int err = dx - (radius << 1);
int x1 = x0 + 1;
int y1 = x0 + 1;
while (x >= y) {
if(hole == 0){
putpixel(x1 + x, y1 + y);
putpixel(x0 - x, y0 - y);
putpixel(x0 - y, y1 + x);
putpixel(x1 + x, y0 - y);
if (x > y) {
putpixel(x1 + y, y1 + x);
putpixel(x0 - x, y1 + y);
putpixel(x0 - y, y0 - x);
putpixel(x1 + y, y0 - x);
}
} else {
hole--;
}
y++;
err += dy;
dy += 2;
if (err > 0) {
x--;
dx += 2;
err += (-radius << 1) + dx;
}
}
}
此外,我对这个功能非常了解,因为它制作了一些优秀的高性能形状,如圆形十字架和盒子,只有很小的变化,我认为值得分享。见图片
获得其他形状......
添加y err
测试,然后将delta X和delta y错误更改更改为2以外的值。
if(err <= 0){ // needed
y++;
err += dy;
dy += 8; << change this
}
if (err > 0) {
x--;
dx += 8; << change this
err += (-radius << 1) + dx;
}
// See image in answer
// 8 made bottom right cross,
// 18 top right
// 28 top left
// 0.8 bottom left
图像显示了孔的形状和结果