Bresenham圆绘制算法

在计算机屏幕上显示连续平滑的圆弧并不容易,因为我们的计算机屏幕是由矩阵形式的像素组成的。所以,要在电脑屏幕上画一个圆,我们应该从打印的像素中选择最接近的像素,这样它们就可以形成一个圆弧。有两种算法可以做到这一点:

null
  1. 中点圆绘制算法
  2. Bresenham圆绘制算法

我们已经讨论了这个问题 中点圆绘制算法 在我们之前的帖子中。在这篇文章中,我们将讨论Bresenham的圆绘制算法。

这两种算法都使用了圆的关键特性,即它是高度对称的。所以,对于整个360度的圆,我们将它分成8个部分,每一个45度的八分之一。为了做到这一点,我们将使用Bresenham圆算法来计算45度第一个八分之一的像素位置。它假定圆以原点为中心。因此,对于它计算的每个像素(x,y),我们在圆的8个八分之一的每个八分之一中绘制一个像素,如下所示:

circle 1

现在,我们将看到如何从先前已知的像素位置(x,y)计算下一个像素位置。在Bresenham的任意点(x,y)算法中,我们有两个选择,要么选择东部的下一个像素,即(x+1,y),要么选择东南部的下一个像素,即(x+1,y-1)。

circle 2

这可以通过使用决策参数d来决定:

  • 如果d>0,则(x+1,y-1)将被选择为下一个像素,因为它将更接近圆弧。
  • 否则(x+1,y)将被选为下一个像素。

现在,为了绘制给定半径“r”和中心(xc,yc)的圆,我们将从(0,r)开始,在第一象限移动,直到x=y(即45度)。我们应该从列出的初始条件开始:

d = 3 - (2 * r)x = 0y = r

现在,对于每个像素,我们将执行以下操作:

  1. 设置(xc,yc)和(x,y)的初始值
  2. 将决策参数d设置为d=3–(2*r)。
  3. 调用drawCircle(intXC,intYC,intX,intY)函数。
  4. 重复步骤5至8,直到x<=y
  5. x的增量。
  6. 如果d<0,则设置d=d+(4*x)+6
  7. 否则,设置d=d+4*(x–y)+10,并将y减1。
  8. 调用drawCircle(int xc、int yc、int x、int y)函数

drawCircle()函数:

CPP

// function to draw all other 7 pixels
// present at symmetric position
drawCircle( int xc, int yc, int x, int y)
{
putpixel(xc+x, yc+y, RED);
putpixel(xc-x, yc+y, RED);
putpixel(xc+x, yc-y, RED);
putpixel(xc-x, yc-y, RED);
putpixel(xc+y, yc+x, RED);
putpixel(xc-y, yc+x, RED);
putpixel(xc+y, yc-x, RED);
putpixel(xc-y, yc-x, RED);
}


下面是上述方法的C实现。

CPP

// C-program for circle drawing
// using Bresenham’s Algorithm
// in computer-graphics
#include <stdio.h>
#include <dos.h>
#include <graphics.h>
// Function to put pixels
// at subsequence points
void drawCircle( int xc, int yc, int x, int y)
{
putpixel(xc+x, yc+y, RED);
putpixel(xc-x, yc+y, RED);
putpixel(xc+x, yc-y, RED);
putpixel(xc-x, yc-y, RED);
putpixel(xc+y, yc+x, RED);
putpixel(xc-y, yc+x, RED);
putpixel(xc+y, yc-x, RED);
putpixel(xc-y, yc-x, RED);
}
// Function for circle-generation
// using Bresenham's algorithm
void circleBres( int xc, int yc, int r)
{
int x = 0, y = r;
int d = 3 - 2 * r;
drawCircle(xc, yc, x, y);
while (y >= x)
{
// for each pixel we will
// draw all eight pixels
x++;
// check for decision parameter
// and correspondingly
// update d, x, y
if (d > 0)
{
y--;
d = d + 4 * (x - y) + 10;
}
else
d = d + 4 * x + 6;
drawCircle(xc, yc, x, y);
delay(50);
}
}
// Driver code
int main()
{
int xc = 50, yc = 50, r = 30;
int gd = DETECT, gm;
initgraph(&gd, &gm, "" ); // initialize graph
circleBres(xc, yc, r); // function call
return 0;
}


输出:

circleout

优势

  • 这是一个简单的算法。
  • 它可以很容易地实现
  • 它完全基于圆的方程,即x 2. +y 2. =r 2.

缺点

  • 生成点时存在精度问题。
  • 该算法不适用于复杂、高分辨率的图形图像。

本文由 希瓦姆·普拉丹(anuj_charm) .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享