日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL——使用Bresenham算法绘制圆

發布時間:2024/9/5 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenGL——使用Bresenham算法绘制圆 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  Bresenham算法是計算機圖形學中為了“顯示器(屏幕或打印機)系由像素構成”的這個特性而設計出來的算法,使得在求直線各點的過程中全部以整數來運算,因而大幅度提升計算速度。——摘自 “百度百科”。

  Bresenham算法繪制直線就不贅述了,大家看一看算法簡介就能很好理解與實踐。

  稍稍麻煩一點的就是用該算法繪制圓了,算法思想其實是一樣的,并沒有太大改變。

  算法核心:

????

  

  

  

  組合以上式子,當Dupper-Dlower<0時,取上點;當Dupper-Dlower>0時,取下點;否則任意。

?

  實驗過程中,我使用了兩種方法:① 畫點法 ② 連線法。

  一、 畫點法:

    畫點法就是僅僅用OpenGL繪制點。可以選擇按照圓的軌跡畫整個圓,當然這樣的算法要比較慢,而且要注意分段函數的增減性。

  ???? 我使用的是對稱法,利用圓的對稱性質,僅僅計算1/8的圓弧的點(當然算1/4也可以),其余的點均用對稱性直接繪制。如下圖所示:

??????????

    代碼如下:

1 /* 2 * Draw Circle by Bresenham Algorithm 3 * @para < xc, yc - 圓心: (xc, yc) > 4 * @para < r - 半徑 > 5 * @para < deltaX - 坐標系每個小格的間距,用于控制精細度 > 6 */ 7 void drawCircle_Bresenham(GLfloat xc, GLfloat yc, GLfloat r, const GLfloat deltaX) { 8 GLfloat xi = - r, yi = 0; /* 圓上點 (xi, yi) */ 9 GLfloat du_l; /* upper - lower */ 10 glBegin(GL_POINTS); 11 while (abs(xi) >= abs(yi)) { 12 // 根據圓的八向對稱,只計算其中八分之一的點,然后對稱得出其他點 13 // 假設圓心在原點,先求點,再平移 14 glVertex2f(xc + xi, yc + yi); 15 glVertex2f(xc - xi, yc + yi); 16 glVertex2f(xc + xi, yc - yi); 17 glVertex2f(xc - xi, yc - yi); 18 glVertex2f(xc + yi, yc + xi); 19 glVertex2f(xc - yi, yc + xi); 20 glVertex2f(xc + yi, yc - xi); 21 glVertex2f(xc - yi, yc - xi); 22 23 xi += deltaX; // 下一個x 24 float yi_1 = sqrt(pow((GLfloat)r, 2) - pow((GLfloat)xi, 2)); // yi+1 25 du_l = 2 * (GLfloat)yi + deltaX - 2 * yi_1; 26 yi = (du_l <= 0) ? (int)yi_1 + deltaX : (int)yi_1; 27 } 28 glEnd(); 29 glFlush(); 30 }

  結果如圖(半徑150,圓心在原點,橫坐標間隔為0.001):

?

  二、 畫線法:

  根據圓弧四個象限的增減性和凹凸性的不同,分別繪制四段曲線,組合成一個圓。核心算法和第一種方法相同。

  

1 const GLint FIRST_QUA = 1; // 第一象限 2 const GLint SECOND_QUA = 2; // 第二象限 3 const GLint THIRD_QUA = 3; 4 const GLint FOURTH_QUA = 4; 5 6 /* 7 * 根據起點和終點繪制弧(畫線法) 8 * @para < deltaX - 坐標系每個小格的間距,用于控制精細度 > 9 * @para < Quadrant - 象限 > 10 */ 11 void setPixel(GLfloat startX, GLfloat endX, GLfloat startY, GLfloat xc, GLfloat yc, GLfloat r, GLfloat deltaX, GLint Quadrant) { 12 GLfloat du_l; /* upper - lower */ 13 int inc = (Quadrant % 2 == 1) ? -1 : 1; 14 int nag = (Quadrant > 2) ? -1 : 1; 15 glBegin(GL_LINE_STRIP); 16 while (startX <= endX) { 17 // 假設圓心在原點,先求點,再平移 18 glVertex2f(startX + xc, startY + yc); 19 startX += deltaX; 20 float yi_1 = nag * sqrt(pow((GLfloat)r, 2) - pow((GLfloat)startX, 2)); // yi+1 21 du_l = 2 * (GLfloat)startY + inc * deltaX - 2 * yi_1; 22 startY = (du_l <= 0) ? (int)yi_1 + deltaX : (int)yi_1; 23 } 24 glEnd(); 25 } 26 27 /* 28 * Bresenham 算法(畫線法) 29 * @para < xc, yc - 圓心(xc, yc) > 30 * @para < r - 半徑 > 31 */ 32 void drawCircle_Bresenham_line(GLfloat xc, GLfloat yc, GLfloat r, GLfloat deltaX) { 33 setPixel(-r, 0, 0, xc, yc, r, deltaX, SECOND_QUA); // 左上半 34 setPixel(0, r, r, xc, yc, r, deltaX, FIRST_QUA); // 右上半 35 setPixel(0, r , -r, xc, yc, r, deltaX, FOURTH_QUA); // 右下半 36 setPixel(-r, 0, 0, xc, yc, r, deltaX, THIRD_QUA); // 左下半 37 glFlush(); 38 }

  結果如圖(半徑150,圓心在原點,橫坐標間隔為0.001):

?

?

  

轉載于:https://www.cnblogs.com/xulf/p/4357875.html

總結

以上是生活随笔為你收集整理的OpenGL——使用Bresenham算法绘制圆的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。