#include <GL/glut.h>
#include<iostream>
using namespace std;
int WinWidth = 900, WinHeight = 900,numbers=30;
int X0, Y0, X1, Y1,t=WinWidth/numbers;//起点和终点坐标
void swap(GLint& a, GLint& b) {
GLint t = a;
a = b;
b = t;
}
void drawgrid();
void Bresenham(int,int,int,int);
void DrawLine() {
glClearColor(0, 0, 0, 0);//这是设置背景色,必须要在glclear之前调用
glClear(GL_COLOR_BUFFER_BIT);
printf("(%d,%d)->(%d,%d)\n", X0/30, Y0/30, X1/30, Y1/30);
glBegin(GL_LINES);
glVertex2f(X0, Y0); //定点坐标范围
glVertex2f(X1, Y1);
glEnd();
Bresenham(X0, Y0, X1, Y1);
drawgrid();
}
void drawpixel(GLint x, GLint y) {
glPointSize(7);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
}
void drawgrid() {
int wid_number = numbers;
int hei_number = numbers;
float delta_wid = WinWidth / wid_number;
float delta_hei = WinHeight / hei_number;
glColor3f(255, 255, 255);
for (int i = 0; i <= 30; i++) {
glBegin(GL_LINES);
glVertex2f(0,i*delta_hei);
glVertex2f(WinWidth, i * delta_hei);
glVertex2f(i*delta_wid,WinHeight);
glVertex2f(i*delta_wid,0);
glEnd();
}
glFlush();
}
void Bresenham(int x0,int y0,int x1,int y1) {
if (x0 > x1)swap(x0, x1), swap(y0, y1);//(x0,y0)->(x1,y1);
bool negk = y1 < y0;//负斜率,沿x轴对称,画点时用-y
if (negk) y0 = -y0, y1 = -y1;
bool steepk = y1 - y0 > x1 - x0;// 斜率 |k|>1,交换x和y的位置
if (steepk) swap(x0, y0), swap(x1, y1);
int x = x0, y = y0, dx = x1 - x0, dy = y1 - y0;
int e = -dx * t;
for (int i = 0; i <= dx; i+=t) {
drawpixel(steepk ? y : x, negk ? (steepk ? -x:-y) : (steepk ? x : y));
x += t; e += 2 * dy * t;
if (e >= 0) y += t, e -= 2 * t * dx;
}
}
void dragmouse(int x, int y) {//鼠标拖拽时,仅画直线,不运行模拟
cout << "运行了鼠标拖拽函数" << endl;
X1 = x; Y1 = y;
glColor3f(255, 215, 0);
glClearColor(0, 0, 0, 0);//这是设置背景色,必须要在glclear之前调用
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2f(X0, Y0); //定点坐标范围
glVertex2f(X1, Y1);
glEnd();
drawgrid();
}
void mymouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
cout << "鼠标松开了" << endl;
X1 = round((x + 0.0) / 30) * 30; Y1 = round((y + 0.0) / 30) * 30;
DrawLine();
glFlush();
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
cout << "鼠标按下了" << endl;
X0 = round((x + 0.0) / 30) * 30; Y0 = round((y + 0.0) / 30) * 30;
}
}
void init() {
glClearColor(0, 0, 0, 1);//(R,G,B,alpha)归一化在(0,1)之间的值,清空当前的所有颜色
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(1.0f);
glMatrixMode(GL_PROJECTION);//声明接下来要进行的操作,GL_PROJECTION 投影,GL_MODELVIEW 模式视图,GL_TEXTURE 纹理
glLoadIdentity();//加载一个单位矩阵
gluOrtho2D(0, WinWidth, WinHeight,0);//鼠标获取的坐标 屏幕左上角是原点
glColor3f(0, 0, 0);//设置画点颜色 R-G-B
drawgrid();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);//指定单缓存窗口与RGB颜色模式的窗口
glutInitWindowPosition(100, 100);//设置初始窗口位置,(0,0)为屏幕左上角
glutInitWindowSize(WinWidth, WinHeight);
glutCreateWindow("Bresenham画线算法");
init();
glutDisplayFunc(DrawLine);//绘制回调函数
glutMouseFunc(mymouse);
glutMotionFunc(dragmouse);
glutMainLoop();
}
10-17
581