1. 程式人生 > 程式設計 >OpenGL中點Bresenham繪製直線演算法

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),d_kind); //繪製下一個點
 }
}
float translater(int x){
 /*
  函式說明:將畫素座標下的座標轉化為openGL座標
  引數說明:傳入點畫素座標-wid-wid,返回-1~1座標
  */
 return x/wid;
}
void draw_point(float x,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);//這是設定背景色,必須要在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);
 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);
 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;

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。