一、实验内容、目的、要求
1、实现圆的中点算法、椭圆的中点算法
2、掌握相关算法的原理及实现
3、交互方便、直观
可处理圆心不在原点的情形(标注出绘图窗口的坐标系)
优化算法:只含整数运算、加减法运算
二、C++源码
1、圆的中点算法代码
#include <GL/glut.h>
#include<math.h>
#include<iostream>
using namespace std;
//辅助画圆算法
void setcirpot(float xc, float yc, float x, float y) {
glBegin(GL_LINES);
glColor3f(1, 0, 0);//设置坐标轴颜色,红色
glVertex3f(-1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glEnd();
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图像颜色,蓝色
glVertex2f((xc + x) / 1000, (yc + y) / 1000);
glVertex2f((xc - x) / 1000, (yc + y) / 1000);
glVertex2f((xc + x) / 1000, (yc - y) / 1000);
glVertex2f((xc - x) / 1000, (yc - y) / 1000);
glVertex2f((xc + y) / 1000, (yc + x) / 1000);
glVertex2f((xc - y) / 1000, (yc + x) / 1000);
glVertex2f((xc + y) / 1000, (yc - x) / 1000);
glVertex2f((xc - y) / 1000, (yc - x) / 1000);
glEnd();
}
//中点画圆法
void Mid_circle(float xc, float yc, float r)
{
glClear(GL_COLOR_BUFFER_BIT);//把窗口清除为当前颜色
float x, y, d;
x = 0;
y = r;
d = 3 - 2*r;
setcirpot(xc, yc, x, y);
while (x <= y) {
if (d < 0) {
d = d + 4 * x + 6;
}
else {
d = d + 4 * (x - y) + 10;
y--;
}
x++;
setcirpot(xc, yc, x, y);
}
glFlush();
}
//显示函数
void display() {
float xc, yc;
float r;
cout << "请输入圆心坐标和半径:" << endl;
cin >> xc >> yc >> r;
Mid_circle(xc, yc, r);
}
void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitWindowSize(400, 400); //设置窗口的大小
glutCreateWindow("中点画圆法"); //创建窗口并赋予标题
glutDisplayFunc(display);
glutMainLoop();
}
圆的中点算法截图:
2、椭圆的中点算法代码
#include <GL/glut.h>
#include <math.h>
#include<iostream>
using namespace std;
void Draw(int x, int y) {
glPointSize(1.0);
glColor3f(0, 0, 1); //设置图形为蓝色
glVertex2i((int)(x), (int)(y));
}
void drawLine(int x0, int y0, int x1, int y1) {
int a, b, d1, d2, d, x, y; float m;
if (x1 < x0) {
d = x0, x0 = x1, x1 = d;
d = y0, y0 = y1, y1 = d;
}
a = y0 - y1, b = x1 - x0;
if (b == 0)
m = -1 * a * 100;
else
m = (float)a / (x0 - x1); x = x0, y = y0;
Draw(x, y);
if (m >= 0 && m <= 1) {
d = 2 * a + b; d1 = 2 * a, d2 = 2 * (a + b);
while (x < x1) {
if (d <= 0) {
x++, y++, d += d2;
}
else {
x++, d += d1;
}
Draw(x, y);
}
}
else if (m <= 0 && m >= -1) {
d = 2 * a - b; d1 = 2 * a - 2 * b, d2 = 2 * a;
while (x < x1) {
if (d > 0) { x++, y--, d += d1; }
else {
x++, d += d2;
}
Draw(x, y);
}
}
else if (m > 1) {
d = a + 2 * b; d1 = 2 * (a + b), d2 = 2 * b;
while (y < y1) {
if (d > 0) {
x++, y++, d += d1;
}
else {
y++, d += d2;
}
Draw(x, y);
}
}
else {
d = a - 2 * b; d1 = -2 * b, d2 = 2 * (a - b);
while (y > y1) {
if (d <= 0) {
x++, y--, d += d2;
}
else {
y--, d += d1;
}
Draw(x, y);
}
}
}
void drawTuoCircle(int x0, int y0, int a, int b) {
int x, y;
int xx, yy;
double d1, d2;
x = 0; y = b;
d1 = b * b + a * a * (-b + 0.25);
drawLine(x0 + x, y0 + y, x0 + x, y0 + y);
drawLine(x0 - x, y0 - y, x0 - x, y0 - y);
drawLine(x0 + x, y0 - y, x0 + x, y0 - y);
drawLine(x0 - x, y0 + y, x0 - x, y0 + y);
xx = x; yy = y;
while (b * b * (x + 1) < a * a * (y - 0.5))
{
if (d1 < 0)
{
d1 += b * b * (2 * x + 3);
x++;
}
else
{
d1 += (b * b * (2 * x + 3) + a * a * (-2 * y + 2));
x++; y--;
}
drawLine(x0 + xx, y0 + yy, x0 + x, y0 + y);
drawLine(x0 - xx, y0 - yy, x0 - x, y0 - y);
drawLine(x0 + xx, y0 - yy, x0 + x, y0 - y);
drawLine(x0 - xx, y0 + yy, x0 - x, y0 + y);
xx = x; yy = y;
}
d2 = sqrt(b * (x + 0.5)) + sqrt(a * (y - 1)) - sqrt(a * b);
while (y > 0)
{
if (d2 < 0)
{
d2 += b * b * (2 * x + 2) + a * a * (-2 * y + 3);
x++; y--;
}
else
{
d2 += a * a * (-2 * y + 3);
y--;
}
drawLine(x0 + xx, y0 + yy, x0 + x, y0 + y);
drawLine(x0 - xx, y0 - yy, x0 - x, y0 - y);
drawLine(x0 + xx, y0 - yy, x0 + x, y0 - y);
drawLine(x0 - xx, y0 + yy, x0 - x, y0 + y);
xx = x; yy = y;
}
}
void show() {
glClear(GL_COLOR_BUFFER_BIT);
//画椭圆
glBegin(GL_POINTS);
glColor3f(0, 0, 1); //蓝色
int x0, y0, a, b;
cout << "请输入椭圆坐标和长轴、短轴:" << endl;
cin >> x0 >> y0 >> a >> b;
drawTuoCircle(x0, y0, a, b);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(400, 400);//设置窗口大小
glutCreateWindow("椭圆中点算法");//创建窗口并赋予名称
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(-400, 400, -400, 400);
glutDisplayFunc(show);
glutMainLoop();
return 0;
}
椭圆的中点算法截图:
注意:以上均是默认窗口中心为原点。
结束啦,下次实验是多边形的扫描转换算法。