版权声明:欢迎转载和交流。 https://blog.csdn.net/Hachi_Lin/article/details/88309871
1、圆弧的特征
圆被定义为到给定中心位置
的距离为
的点集。圆心为
的圆有4条对称轴
。若已知圆弧上一点
,可以得到其关于4条对称轴的其它7个点,这种性质称为八对称性。因此,只要扫描1/8圆弧,就可以用八对称性求出整个圆弧的像素集。
显示圆弧上8个对称点的算法如下:
void CirclePoints(int x,int y,int color)
{
drawpixel(x, y,int color); drawpixel(y - (y0 - x0), x + (y0 - x0),int color);
drawpixel(y - (y0 - x0), x0 + y0 - x,int color); drawpixel(x, 2 * y0 - y,int color);
drawpixel(2 * x0 - x, 2 * y0 - y,int color); drawpixel(x0 + y0 - y, x0 + y0 - x,int color);
drawpixel(x0 + y0 - y, x + (y0 - x0),int color); drawpixel(2 * x0 - x, y,int color);
}
2、中点画圆法
构造函数
,对于圆上的点,
;对于圆外的点,
;对于圆内的点,
。与中点画线法一样,构造判别式:
(1)若
,则应取
为下一像素,而且下一像素的判别式为
(2)若
,则应取
为下一像素,而且下一像素的判别式为
这里讨论的是按顺时针方向生成第二个八分圆(如图),则第一个像素是
,判别式
的初始值为
为了摆脱浮点运算,使用
代替
。
- 中点画圆算法程序
MidPointCircle(int x0, int y0, int color)
{
drawpixel(x0, y0, color); //画圆心
int x, y;
int d, b;
x = x0; y = r + y0; d = 5 - 4*r; b = y0 - x0;
Circlepoints(x, y, color);
while (x + (y0 - x0) <= y)
{
if (d < 0)
d += 8*(x - x0) + 12;
else {
d += 8*x - 8*y + 8*b + 16;
y--;
}
x++;
Circlepoints(x,y,color);
}
}
3、极坐标画圆法
给定圆心
,可通过下列方程组表示圆
使用上述方法以单位角度为步长,可以在圆周上以等距的点来绘制圆,其中
。
- 极坐标画圆算法程序
PolarCircle(int x0, int y0, int color)
{
drawpixel(x0, y0, color); //画圆心
int angle = 90;
int x, y, change;
while (angle >= 45)
{
//角度转弧度
change = angle*pi/180;
x = int(0.5 + x0+r*cos(change));
y = int(0.5 + y0+r*sin(change));
Circlepoints(x , y, color);
angle--;
}
}
4、代码实现(VS2017 + OpenGL)
// Circle_Algorithm.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include "pch.h"
#include <iostream>
#include <math.h>
#include <gl\glut.h>
#include <gl\GL.h>
#include <gl\GLU.h>
using namespace std;
#define pi 3.1415926
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); // Set display-window color to white.
glMatrixMode(GL_PROJECTION); // Set projection parameters.
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
//窗口大小改变时调用的登记函数
void ChangeSize(GLsizei w, GLsizei h) {
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0, -1.0);
else
glOrtho(0.0f, 250.0f*w / h, 0.0f, 250.0f, 1.0, -1.0);
}
void CirclePoint(int x0, int y0, int x, int y) {
glColor3f(0.0, 0.0, 1.0); //设置像素点颜色为蓝色
//按顺时针画圆
glVertex2f(x, y); glVertex2f(y - (y0 - x0), x + (y0 - x0));
glVertex2f(y - (y0 - x0), x0 + y0 - x); glVertex2f(x, 2 * y0 - y);
glVertex2f(2 * x0 - x, 2 * y0 - y); glVertex2f(x0 + y0 - y, x0 + y0 - x);
glVertex2f(x0 + y0 - y, x + (y0 - x0)); glVertex2f(2 * x0 - x, y);
}
//中点画圆算法
void MidPointCircle(int x0, int y0, int r)
{
glColor3f(0.0, 0.0, 1.0); //设置像素点颜色为蓝色
glPointSize(2.0f); //设置像素点大小
glVertex2f(x0, y0); //画圆心
int x, y;
int d,b;
x = x0; y = r + y0; d = 5 - 4 * r; b = y0 - x0;
CirclePoint(x0, y0, x, y);
while (x + b <= y)
{
if (d < 0)
d += 8*(x - x0) + 12;
else {
d += 8*x - 8*y + 8*b + 16;
y--;
}
x++;
CirclePoint(x0, y0, x, y);
}
}
//极坐标画圆算法
void PolarCircle(int x0, int y0, int r)
{
glColor3f(0.0, 0.0, 1.0); //设置像素点颜色为蓝色
glPointSize(2.0f); //设置像素点大小
glVertex2f(x0, y0); //画圆心
int angle = 90;
int x, y, change;
while (angle >= 45)
{
//角度转弧度
change = angle * pi / 180;
x = int(0.5 + x0 + r * cos(change));
y = int(0.5 + y0 + r * sin(change));
CirclePoint(x0, y0, x, y);
angle--;
}
}
void display()
{
int x1_1 = 20, y1_1 = 20, x2_1 = 160, y2_1 = 80;
int x1_2 = 20, y1_2 = 40, x2_2 = 160, y2_2 = 100;
int x1_3 = 20, y1_3 = 60, x2_3 = 160, y2_3 = 120;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
MidPointCircle(80, 60, 60);
glEnd();
glBegin(GL_POINTS);
MidPointCircle(80, 80, 60);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv); //GLUT初始化
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //指出显示窗口使用单个缓存且使用由红绿蓝三种颜色模型
glutInitWindowPosition(500, 500); //设置显示窗口位置
glutInitWindowSize(400, 400); //设置显示窗口大小
glutCreateWindow("Line Algorithm"); //设置显示窗口的标题
glutDisplayFunc(display); //将图赋值给显示窗口
glutReshapeFunc(ChangeSize);
init();
glutMainLoop(); //必须是程序的最后一个
return 0;
}
- 运行结果