在本文中,我们将讨论如何使用 Bresenham 方程和极坐标方程绘制圆。
画圆算法
由于我们的电脑屏幕是由以矩阵形式组织的像素组成的,因此在电脑屏幕上显示连续平滑的弧线并不容易。因此,要在计算机屏幕上绘制圆,它应该始终从打印的像素中选择最近的像素,以便它们可以形成弧。
- 考虑以原点为中心、半径为整数的圆。
- 可以应用翻译来获得非原点中心圆。
- 圆的方程由下式给出:
x2 + y2 = R2
y = +/-sqrt(R2-x2)
- 给定的方程可以写成:
F(x, y)= x2+ y2-R2=0
5.
- Symmetry的使用:只需要计算一个八分圆。一个人可以在其他 7 个八分圆中获得积分,如下所示:
- 绘图点(x,y)
- 绘图点(y,x)
- 绘图点(x,-y)
- 绘图点(-y,x)
- 绘图点(-x,-y)
- 绘图点(-y,-x)
- 绘图点(-x,y)
- 绘图点(-y,x)
使用 Bresenham 方程绘制圆
Bresenham 方程使用高度对称的圆的关键特征。因此,对于整个 360度圆,将其分成8 个部分,每个八分圆为 45度。为此,我们的想法是使用Bresenham 圆算法来计算 45 度第一个八分圆中像素的位置。它假设圆以原点为中心。因此,对于每个像素(x, y) ,在圆的 8 个八分圆中的每个八分圆中绘制一个像素,如下所示:
在 Bresenham 算法中的任意点(x, y) 中,我们有两种选择,要么选择东部的下一个像素,即(x + 1, y) ,要么选择东南的下一个像素,即(x + 1, y – 1) .这可以通过使用决策参数 d来决定:
- 如果d > 0 ,那么(x + 1, y – 1)将被选为下一个像素,因为它会更靠近弧线。
- 否则(x + 1, y)将被选为下一个像素。
下面是 Bresenham 方程的算法:
- F(x, y) = x 2 + y 2 = 0 点在圆上。
- F(x, y) > 0 点位于圆外。
- F(x, y) < 0 点位于圆内。
- 如果 d >= 0 然后将 x 更新为 (x + 1) 和 y = (y – 1) 这给出了新的 d
- 如果 d < 0 然后将 x 更新为 (x + 1) 这给出了 d 的新值
C
// C program for the above approach
#include
#include
#include
#include
int xo, yo, r;
// Function to display the circle using
// the above algorithm
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
// Color of printing object
glColor3f(1, 0, 0);
// Giving the size of the point
glPointSize(2);
int x = 0;
int y = r;
float p = 5 / 4 - r;
glColor3f(1, 0, 0);
// Starting of drawing the circle
glBegin(GL_POINTS);
while (y > x) {
if (p < 0) {
// Increment x to x+1
x++;
p = p + 2 * x + 1;
}
else {
// Increment x to x+1
// and decrease y to y-1
y--;
x++;
p = p + 2 * (x - y) + 1;
}
// Draw the coordinates
glVertex2d(x + xo, y + yo);
glVertex2d(-x + xo, y + yo);
glVertex2d(x + xo, -y + yo);
glVertex2d(-x + xo, -y + yo);
glVertex2d(y + yo, x + xo);
glVertex2d(-y + yo, x + xo);
glVertex2d(y + yo, -x + xo);
glVertex2d(-y + yo, -x + xo);
}
glEnd();
// Its empties all the buffer
// causing the issue
glFlush();
}
// Driver Code
int main(int argc, char** argv)
{
printf("X-coordinate Y-coordinate radius:");
scanf("%d %d %d", &xo, &yo, &r);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Assigning the size of window
glutInitWindowSize(1000, 1000);
// Assign the position of window
// to be appeared
glutInitWindowPosition(100, 100);
// Defining the heading of the window
glutCreateWindow("GeeksforGeeks");
// Backgronnd Color
glClearColor(1, 1, 1, 1);
// limit of the coordinate points
gluOrtho2D(-500, 500, -500, 500);
// Calling the function
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
C
// C program to demonstrate circle
// drawing using polar equation
#include
#include
#include
#include
float xo, yo, rad;
// Function to display the circle
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
// Color of printing object
glColor3f(1, 1, 1);
float angle;
// Start to drawing the circle
glBegin(GL_POLYGON);
for (int i = 0; i < 100; i++) {
// Change the angle
angle = i * 2 * (M_PI / 100);
glVertex2f(xo + (cos(angle) * rad),
yo + (sin(angle) * rad));
}
glEnd();
// Its empties all the buffer
// causing the issue
glFlush();
}
// Driver Code
int main(int argc, char** argv)
{
glutInit(&argc, argv);
printf("Enter x y radius ");
scanf("%f %f %f", &xo, &yo, &rad);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Assigning the size of window
glutInitWindowSize(500, 500);
// Assign the position of window
// to be appeared
glutInitWindowPosition(200, 200);
// Defining the heading of the window
glutCreateWindow("GeeksforGeeks");
// Backgronnd Color
glClearColor(0, 1, 0, 1);
// limit of the coordinate points
gluOrtho2D(-500, 500, -500, 500);
// Calling the function
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
输出:
时间复杂度: O(N)
辅助空间: O(1)
使用极坐标方程的圆
在极地方程系统中,这个想法是用一只手思考时钟。与手一起从原点移出距离r ,有时称为模数,然后将手向上(逆时针)旋转角度θ以到达该点。以下是极坐标方程的算法:
- 初始化变量rad、center(x0, y0) 、索引值或增量值i ,并使用极坐标θ_end = 100定义一个圆。
- 如果θ_end < θ ,则退出循环。
- 将 x的值作为rad*cos(angle)和y作为rad*sin(angle) 。
- 绘制通过对称性找到的八个点,即当前 (x, y)坐标处的中心 (x0, y0)。
- 绘制 (x + xo, y + yo)
- 绘图 (-x + xo, -y + yo)
- 绘制 (y + xo, x + yo)
- 绘图 (-y + xo, -x + yo)
- 绘制 (-y + xo, x + yo)
- 绘制 (y + xo, -x + yo)
- 绘制 (-x + xo, y + yo)
- 绘制 (x + xo, -y + yo)
- 将角度增加i*2*(M_PI/100) 。
以下是实现上述方法的程序:
C
// C program to demonstrate circle
// drawing using polar equation
#include
#include
#include
#include
float xo, yo, rad;
// Function to display the circle
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
// Color of printing object
glColor3f(1, 1, 1);
float angle;
// Start to drawing the circle
glBegin(GL_POLYGON);
for (int i = 0; i < 100; i++) {
// Change the angle
angle = i * 2 * (M_PI / 100);
glVertex2f(xo + (cos(angle) * rad),
yo + (sin(angle) * rad));
}
glEnd();
// Its empties all the buffer
// causing the issue
glFlush();
}
// Driver Code
int main(int argc, char** argv)
{
glutInit(&argc, argv);
printf("Enter x y radius ");
scanf("%f %f %f", &xo, &yo, &rad);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Assigning the size of window
glutInitWindowSize(500, 500);
// Assign the position of window
// to be appeared
glutInitWindowPosition(200, 200);
// Defining the heading of the window
glutCreateWindow("GeeksforGeeks");
// Backgronnd Color
glClearColor(0, 1, 0, 1);
// limit of the coordinate points
gluOrtho2D(-500, 500, -500, 500);
// Calling the function
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
输出:
时间复杂度: O(N)
辅助空间: O(1)