6 c algorithm geometry bresenham
目前我正在使用 Bresenham 的圆形绘制算法,该算法可以很好地绘制圆形,但是我想要一种相对快速且有效的方法来绘制具有指定厚度的圆形(因为 Bresenham 的方法仅绘制单个像素厚度)。我意识到我可以简单地绘制多个具有不同半径的圆,但我相信这会非常低效(效率很重要,因为这将在 Arduino 上运行,其中每一微秒都很宝贵)。我目前正在使用以下代码:
void circle(byte xc, byte yc, int radius, Colour colour) {
int x = -radius, y = 0, err = 2 - 2 * radius;
while(x < 0) {
setPixel(xc - x, yc + y, colour);
setPixel(xc - y, yc - x, colour);
setPixel(xc + x, yc - y, colour);
setPixel(xc + y, yc + x, colour);
radius = err;
if(radius <= y) {
err += ++y * 2 + 1;
}
if(radius > x || err > y) {
err += ++x * 2 + 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我如何修改它以允许指定圆的厚度?PS 我不想使用任何外部库,拜托!
如果您按照中点圆算法的说明沿八分圆扫描,您的主坐标y将始终增加一。然后您可以一次绘制两个圆,因为它们的主坐标是同步的。
您可以在具有相同y(或x)坐标的内圆和外圆的点之间绘制水平(和垂直)线,而不是放置像素。这样做直到外圆到达对角线。
x您可以使用和来保持两个圆的状态err,即内圆i和外圆o。内圆到达对角线后,内点位于该对角线上。这意味着您正在绘制八个相邻的八分圆扇区。
这个想法与 @oakad 在评论中提出的非常相似,但不需要保留列表。中点圆算法可能比 Bresenham 算法慢,因此可能还有改进的空间,但低内存占用是一个优势。
下面的代码将绘制一个具有给定内半径和外半径的空心圆。线宽为ro - ri + 1,因此即使半径相等也会打印出一个像素宽的圆。如果内半径小于外半径,它将不会打印任何内容。
void xLine(int x1, int x2, int y, int colour)
{
while (x1 <= x2) setPixel(x1++, y, colour);
}
void yLine(int x, int y1, int y2, int colour)
{
while (y1 <= y2) setPixel(x, y1++, colour);
}
void circle2(int xc, int yc, int inner, int outer, int colour)
{
int xo = outer;
int xi = inner;
int y = 0;
int erro = 1 - xo;
int erri = 1 - xi;
while(xo >= y) {
xLine(xc + xi, xc + xo, yc + y, colour);
yLine(xc + y, yc + xi, yc + xo, colour);
xLine(xc - xo, xc - xi, yc + y, colour);
yLine(xc - y, yc + xi, yc + xo, colour);
xLine(xc - xo, xc - xi, yc - y, colour);
yLine(xc - y, yc - xo, yc - xi, colour);
xLine(xc + xi, xc + xo, yc - y, colour);
yLine(xc + y, yc - xo, yc - xi, colour);
y++;
if (erro < 0) {
erro += 2 * y + 1;
} else {
xo--;
erro += 2 * (y - xo + 1);
}
if (y > inner) {
xi = y;
} else {
if (erri < 0) {
erri += 2 * y + 1;
} else {
xi--;
erri += 2 * (y - xi + 1);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5756 次 |
| 最近记录: |