一、实验内容
1、实现中点画线算法
2、Bresenham画线算法
二、实验目的
1、掌握相关算法的原理及实现
2、了解绘图区域的坐标概念
三、实验要求
1、掌握OpenGL或其他开发工具的环境配置
2、交互方便(鼠标点选、键盘输入等)
3、标注出绘图窗口的坐标系(原点、坐标轴)
4、可处理任意方向、斜率的直线段
四、c++源代码
1、中点画线算法
#include <GL/>
#include<>
#include<iostream>
using namespace std;
void Midpoint_Line(float x11, float y11, float x22, float y22)
{
glClear(GL_COLOR_BUFFER_BIT);
//绘制坐标轴
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();
float a, b, d1, d2, d, x, y;
float k;
a = y11 - y22, b = x22 - x11;
if (x22 < x11) {
d = x11, x11 = x22, x22 = d;
d = y11, y11 = y22, y22 = d;
}
if (b == 0)
k = -1 * a * 100;
else
k = a / (x11 - x22);
x = x11;y = y11;
if (k >= 0 && k <= 1){
d = 2 * a + b;
d1 = 2 * a;
d2 = 2 * (a + b);
while (x < x22)
{
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图形颜色蓝色
glVertex2f(x / 1000, y / 1000);
glEnd();
if (d <= 0) {
x++, y++, d += d2;
}
else {
x++, d += d1;
}
}
}
else if (k <= 0 && k >= -1)
{
d = 2 * a - b; d1 = 2 * a - 2 * b, d2 = 2 * a;
while (x < x22)
{
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图形颜色蓝色
glVertex2f(x / 1000, y / 1000);
glEnd();
if (d > 0) {
x++, y--;
d += d1;
}
else {
x++, d += d2;
}
}
}
else if (k > 1)
{
d = a + 2 * b; d1 = 2 * (a + b), d2 = 2 * b;
while (y < y22)
{
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图形颜色蓝色
glVertex2f(x / 1000, y / 1000);
glEnd();
if (d > 0) {
x++, y++, d += d1;
}
else {
y++, d += d2;
}
}
}
else
{
d = a - 2 * b; d1 = -2 * b, d2 = 2 * (a - b);
while (y > y22)
{
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图形颜色蓝色
glVertex2f(x / 1000, y / 1000);
glEnd();
if (d <= 0) {
x++, y--, d += d2;
}
else {
y--, d += d1;
}
}
}
glFlush();
}
void display() {
float x11, y11, x22, y22;
cout << "请输入直线起始点坐标和终点坐标:" << endl;
cin >> x11 >> y11 >> x22 >> y22;
Midpoint_Line(x11, y11, x22, y22);
}
int main(int argc, char** argv) {
glutInit(&argc, argv); //初始化glut
glutCreateWindow("中点画线算法"); //创建窗口并赋予标题
glutDisplayFunc(display);//调用renderScene把绘制传送到窗口
glutMainLoop(); //进入循环等待
return 0;
}
2、Bresenham画线算法
#include <GL/>
#include<>
#include<iostream>
using namespace std;
void Bresenham_line(float x11, float y11, float x22, float y22)
{
glClear(GL_COLOR_BUFFER_BIT);
//绘制坐标轴
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();
float x, y, dx, dy;
x = x11; y = y11;
float k, e;
dx = abs(x22 - x11);
dy = abs(y22 - y11);
k = dy / dx;
e = -dx;
int s1 = x22 > x11 ? 1 : -1;
int s2 = y22 > y11 ? 1 : -1;
bool flag = false; //默认|k|<1
if (dy > dx) { //|k|>1的情况
int temp = dx;
dx = dy;
dy = temp;
flag = true;
}
for (int i = 0; i < dx; i++)
{
glBegin(GL_POINTS);
glColor3f(0, 0, 1);//设置图形颜色蓝色
glVertex2f(x / 1000, y / 1000);
glEnd();
if (e >= 0)
{
if (!flag) // 当斜率 < 1 时,选取上下象素点
y += s2;
else // 当斜率 > 1 时,选取左右象素点
x += s1;
e -= 2 * dx;
}
if (!flag)
x += s1; // 当斜率 < 1 时,选取 x 为步长
else
y += s2; // 当斜率 > 1 时,选取 y 为步长
e += 2 * dy;
}
glFlush();
}
void display() {
int x11, y11, x22, y22;
cout << "请输入直线起始点坐标和终点坐标:" << endl;
cin >> x11 >> y11 >> x22 >> y22;
Bresenham_line(x11, y11, x22, y22);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //初始化glut
glutCreateWindow("Bresenham算法"); //创建窗口并赋予title
glutDisplayFunc(display);//调用renderScene把绘制传送到窗口
glutMainLoop(); //进入循环等待
return 0;
}
五、测试效果截图
1、中点画线算法截图
2、Bresenham画线算法截图
到此结束,下次再更新圆和椭圆的中点算法。