OpenGL中点Bresenham绘制直线算法

时间:2022-10-29 22:34:47

本文实例为大家分享了OpenGL中点Bresenham绘制直线算法,供大家参考,具体内容如下

环境

macos xcode编译器

代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <GLUT/GLUT.h>
#include <iostream>
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
float wid = 400;  //设置窗口的大小,约定窗口必须为正方形
float height = wid; //设置窗口的大小
int numbers = 20; //设置划分的网格的个数
float t = wid/numbers; //模拟像素下的单位1
/*
 参数设置说明:
 输入直线的两点A(x1,y1);B(x2,y2)
 您应当确保参数范围在-400~400.且为整数。
 *支持不同斜率
 *支持两点位置颠倒
 */
int x1 = -300,y1=-400,x2 =400,y2 = 100;
void draw_point(float x, float y,int k_kind,int d_kind);
float translater(int x);
void swap(int &a, int &b)
{ int tmp = 0;
 tmp = b;
 b = a;
 a = tmp; }
void bresenham(int x1, int y1,int x2, int y2){
 /*
 函数说明:bresenham算法部分
 参数说明:与openGL已有的划线函数一样,要求用户提供的是点的起点(x1,y1)和终点(x2,y2)
 为了便于观察,我们会绘制原像素下的直线。
 这里的坐标要求是-1 ~ 1
 */
 int k_kind = 0; //k_kind用来表示斜率的类型。0是0~1;1是1~无穷;2是0~-1;3是负无穷~-1
 int d_kind =0; //d_kind用来表示dy正负的类型。
 if (x1 > x2) {
 swap(x1,x2);
 swap(y1,y2);
 }
 int dx = abs(x2-x1), dy = abs(y2-y1);
 if (y1 > y2) {//如果是向下的
 y1 = -y1;
 y2 = -y2;
 d_kind = 1;
 }
 if (dy > dx) { //斜率介于1~无穷的,将看作坐标系变换(这里将坐标变换)。
 swap(x1, y1);
 swap(x2,y2);
 swap(dx,dy);
 k_kind = 1;
 }
 float d = (dy +dy -dx)*t; //令d为决策量(这里利用d = dx*w*2避免浮点运算)
 float x = x1+0.0,y = y1+0.0;
 draw_point(translater(x),translater(y),k_kind,d_kind); //绘制下一个点
 while( x < x2){  //以x为步长
 if (d < 0){
  d += 2*dy*t;
 }
 else{
  d += 2*(dy-dx)*t;
  y += t; //说明应该画在上面那个位置
 }
 x= x + t;
 draw_point(translater(x),translater(y),k_kind,d_kind); //绘制下一个点
 }
}
float translater(int x){
 /*
 函数说明:将像素坐标下的坐标转化为openGL坐标
 参数说明:传入点像素坐标-wid-wid,返回-1~1坐标
 */
 return x/wid;
}
void draw_point(float x , float y, int k_kind,int d_kind){
 /*
 函数说明:绘制像素的点,这里将点的大小设置为7。
 颜色采用蓝色。
 参数说明:浮点数x,y是openGl坐标系。kind是指明斜率的类型
 */
 glPointSize(7);
 glColor3f(0.0,0.0,1.0);
 glBegin(GL_POINTS);
 cout <<"k:"<<k_kind<<"d:" << d_kind << endl;
 if(k_kind==0&&d_kind==1){
 y = -y;
 }else if (k_kind ==1 &&d_kind==1){
 x= -x;
 swap(x,y);
 }else if (k_kind==1&&d_kind ==0){
 swap(x,y);
 }
 glVertex3f(x,y,0.0);
 glEnd();
 glFlush();
}
void grid(){
 /*
 函数说明:绘制网格为了便于将真实的像素pixel转化为我们模拟的像素
 */
 glClearColor(0, 0, 0, 0);//这是设置背景色,必须要在glclear之前调用
 glClear(GL_COLOR_BUFFER_BIT);
 //画直线
 int wid_number = numbers;
 int hei_number = numbers;
 float delta_wid = wid / wid_number;
 float delta_hei = height / hei_number;
 glColor3f(1.0,1.0,0);
 for (int i = 1; i < 40 ; i ++ ) {
 glBegin(GL_LINES);
 glVertex2f(-1+i*delta_hei/height, -1);
 glVertex2f(-1+i*delta_hei/height, 1);
 glVertex2f(-1,-1+i*delta_hei/height);
 glVertex2f(1,-1+i*delta_hei/height);
 glEnd();
 glFlush();
 }
 glColor3f(1.0,0,0);
 glBegin(GL_LINES); //绘制坐标系,便于观察
 glVertex2f(-1,0);
 glVertex2f(1,0);
 glVertex2f(0,-1);
 glVertex2f(0,1);
 glEnd();
 glFlush();
 glBegin(GL_LINES);
 glColor3f(1.0,0.0,0.0);
 glVertex2f(translater(x1),translater(y1)); //定点坐标范围
 glVertex2f(translater(x2),translater(y2));
 glEnd();
 glFlush();
 //刷新缓冲,保证绘图命令能被执行
 bresenham(x1, y1,x2,y2);
}
int main(int argc, char *argv[]) {
 //初始化GLUT library
 glutInit(&argc, argv);
 //对窗口的大小进行初始化
 glutInitWindowSize(700,700);
 glutInitWindowPosition(300,200);
 // 设置窗口出现的位置
 //glutInitWindowPosition(int x, int y);
 glutInitDisplayMode(GLUT_RGBA);
 glutCreateWindow("class16_hw1");
 glutDisplayFunc(&grid);
 glutMainLoop();
 return 0;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/OOFFrankDura/article/details/79559083