計算機圖形學中,所有的光滑曲線、曲面都採用線段或三角形逼近來模擬,但為了精確地表現曲線,通常需要成千上萬個線段或三角形來逼近,這種方法對於計算機的硬體資源有相當高的要求。然而,許多有用的曲線、曲面在數學上只需要用少數幾個引數(如控制點等)來描述。這種方法所需要的儲存空間比線段、三角形逼近的方法來所需要的空間要小得多,並且控制點方法描述的曲線、曲面比線段、三角形逼近的曲線、曲面更精確。
為了說明如何在opengl中繪製複雜曲線和曲面,我們對上述兩模擬方法都進行了介紹。下面我們先來介紹有關基礎知識,然後再看是如何實現的吧。
一、曲線的繪製
opengl通過一種求值器的機制來產生曲線和曲面,該機制非常靈活,可以生成任意角度的多項式曲線,並可以將其他型別的多邊形曲線和曲面轉換成貝塞爾曲線和曲面。這些求值器能在任何度的曲線及曲面上計算指定數目的點。隨後,opengl利用曲線和曲面上的點生成標準opengl圖元,例如與曲線或曲面近似的線段和多邊形。由於可讓opengl計算在曲線上所需的任意數量的點,因此可以達到應用所需的精度。
對於曲線,opengl中使用glmap1*()函式來建立一維求值器,該函式原型為:
void glmap1(glenum target,type u1,type u2,glint stride, glint order,const type *points);
函式的第乙個引數target指出控制頂點的意義以及在引數points中需要提供多少值,具體值見表一所示。引數points指標可以指向控制點集、rgba顏色值或紋理座標串等。例如若target是gl_map1_color_4,則就能在rgba四維空間中生成一條帶有顏色資訊的曲線,這在資料場視覺化中應用極廣。引數u1和u2,指明變數u的範圍,u一般從0變化到1。引數stride是跨度,表示在每塊儲存區內浮點數或雙精度數的個數,即兩個控制點間的偏移量,比如上例中的控制點集ctrpoint[4][3]的跨度就為3,即單個控制點的座標元素個數。函式引數order是次數加 1,叫階數,與控制點數一致。
引數意義
gl_map1_vertex_3
x,y,z頂點座標
gl_map1_vertex_4
x,y,z,w 頂點座標
gl_map1_index
顏色表gl_map1_color_4
r,g,b,a
gl_map1_normal
法向量gl_map1_texture_coord_1
s 紋理座標
gl_map1_texture_coord_2
s,t 紋理座標
gl_map1_texture_coord_3
s,t,r 紋理座標
gl_map1_texture_coord_4
s,t,r,q 紋理座標 表
一、引數target的取值表
使用求值器定義曲線後,必須要啟動求值器,才能進行下一步的繪製工作。啟動函式仍是glenable(),其中引數與glmap1*()的第乙個引數一致。同樣,關閉函式為gldisable(),引數也一樣。
一旦啟動乙個或多個求值器,我們就可以構造近似曲線了。最簡單的方法是通過呼叫計算座標函式glevalcoord1*()替換所有對函式glvertex*()的呼叫。與glvertex*()使用二維、三維和四維座標不同,glevalcoord1*()將u值傳給所有已啟動的求值器,然後由這些已啟動的求值器生成座標、法向量、顏色或紋理座標。opengl曲線座標計算的函式形式如下:
void glevalcoord1[v](type u);
該函式產生曲線座標值並繪製。引數u是定義域內的值,這個函式呼叫一次只產生乙個座標。在使用glevalcoord1*()計算座標,因為u可取定義域內的任意值,所以由此計算出的座標值也是任意的。
使用glevalcoord1*()函式的優點是,可以對u使用任意值,然而,如果想對u使用n個不同的值,就必須對glevalcoord1*()函式執行n次呼叫,為此,opengl提供了等間隔值取值法,即先呼叫glmapgrid1*()定義乙個間隔相等的一維網格,然後再用glevalmesh1()通過一次函式執行,將求值器應用在網格上,計算相應的座標值。下面詳細解釋這兩個函式:
1、void glmapgrid1(glint n,type u1,type u2);
定義乙個網格,從u1到u2分為n步,它們是等間隔的。實際上,這個函式定義的是引數空間網格。
2、void glevalmesh1(glenum mode,glint p1,glint p2);
計算並繪製座標點。引數mode可以是gl_point或gl_line,即沿曲線繪製點或沿曲線繪製相連的線段。這個函式的呼叫效果同在p1和p2之間的每一步給出乙個glevalcoord1()的效果一樣。從程式設計角度來說,除了當i=0或i=n,它準確以u1或u2作為引數呼叫glevalcoord1()之外,它等價於一下**:
glbegin(gl_point); /* glbegin(gl_line_strip); */
for(i=p1;i<=p2;i++)
glevalcoord1(u1+i*(u2-u1)/n);
glend();
為了進一步說明opengl中曲線的繪製方法。下面我們來看乙個簡單的例子,這是用四個控制頂點來畫一條三次bezier曲線。程式如下(注:這是本講座中提供的第乙個完整的opengl例項**,如果讀者朋友對整個程式結構有些迷惑的話,也不要緊,慢慢地往下看,先有乙個感官上的印象,主要是掌握如何實現曲線繪製這一部分。關於opengl的程式整體結構實現,筆者將在第五講中專門闡述):
#include "glos.h"
#include
#include
#include
void myinit(void);
void callback myreshape(glsizei w, glsizei h);
void callback display(void);
glfloat ctrlpoints[4][3] = , ,
, };
void myinit(void)
void callback display(void)
void callback myreshape(glsizei w, glsizei h)
曲線和曲面
1.二維平面上的曲線方程 y f x 以上方程中,對任意x 暫不考慮定義域 都有乙個y與之對應,因此表示的是一條曲線。寫成引數形式 x f t y g t 或進一步寫成向量形式 r t f t i g t j。1.1 曲線長度 將曲線上的每一小段dx都看做近似平直,那麼每一小段的長度是sqrt dx...
基於VC 的OpenGL程式設計講座之曲線和曲面
天極軟體專題專區精選 到天極軟體 讀編交流區 暢所欲言 google專區 popo專區 qq專區 qq掛機 了解web2.0 處理數字暗房 ppt動畫演示教程 excel動畫教程集 word動畫演示教程 windows vista專區 特洛伊木馬專區 黑客知識教程專區 防火牆應用專區 登錄檔應用專區...
CG筆記之二 曲線和曲面
cg造型中用到較多曲線論和曲面論的知識,這在一般分析學課程中不作為重點,而屬於微分幾何講授的內容。一些不十分艱深的數學參考書,如南開大學數學叢書系列之一 微分幾何 孟道驥,梁科著,科學出版社出版 都能對相關理論內容做較詳細的闡述。在曲線連續部分,有關g2和c2關係問題,容易引起一些誤解。其實g2已經...