【计算机图形学实验1——实现中点画线算法、Bresenham画线算法】

时间:2024-11-12 12:08:01

一、实验内容

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画线算法截图

在这里插入图片描述
到此结束,下次再更新圆和椭圆的中点算法。