本文实例为大家分享了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








发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。