C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > OpenGL直线算法

OpenGL中点Bresenham绘制直线算法

作者:Frank(Zhiyang-Dou)

这篇文章主要为大家详细介绍了OpenGL中点Bresenham绘制直线算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

环境

macos xcode编译器

代码

#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;

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

您可能感兴趣的文章:
阅读全文