使用基本Bezier求值器繪製曲線和曲面

2021-07-23 13:42:39 字數 3564 閱讀 1051

ogl只能繪製基本的頂點圖元,但是要繪製曲線或曲面就需要使用求值器,使得儲存更少的資訊渲染時候求值得到需要的效果。可以使用求值器描述任何角度的多項式或有理多項式樣條或表面。他們幾乎包含了如今所有常見的樣條或樣條表面,包括b-樣條,nurbs(非均勻有理b-樣條)表面,bezier曲線和表面,以及hermite樣條,但是都是提供了底層描述,glu的nurbs提供了高層介面。這裡描述的ogl求值器基本是指bezier求值器,可以對頂點,法線,顏色和紋理座標分別進行求值。bezier曲線曲面求值器可以對簡單的曲線曲面進行繪製,因為bezier缺點是增加控制點時,曲線和曲面變得不可控難以得到平滑效果,這個時候需要採用b spline(均勻b樣條或非均勻b樣條(nurbs non-uniform rational b-spline) ),也可以使用hermite樣條。下面主要關注ogl bezier求值器。

線性公式

給定點p0、p1,線性貝茲曲線只是一條兩點之間的直線。這條線由下式給出:

且其等同於線性插值。

二次方公式

二次方貝茲曲線的路徑由給定點p0、p1、p2的函式b(t)追蹤:

truetype字型就運用了以貝茲樣條組成的二次貝茲曲線。

三次方公式

p0、p1、p2、p3四個點在平面或在三維空間中定義了三次方貝茲曲線。曲線起始於p0走向p1,並從p2的方向來到p3。一般不會經過p1或p2;這兩個點只是在那裡提供方向資訊。p0和p1之間的間距,決定了曲線在轉而趨進p3之前,走向p2方向的「長度有多長」。

曲線的引數形式為:

現代的成象系統,如postscript、asymptote和metafont,運用了以貝茲樣條組成的三次貝茲曲線,用來描繪曲線輪廓。

一般引數公式

階貝茲曲線可如下推斷。給定點p0、p1、…、pn,其貝茲曲線即:

如上公式可如下遞迴表達: 用表示由點

p

0、p

1、…、

p

n所決定的貝茲曲線。

用平常話來說,階的貝茲曲線,即雙階貝茲曲線之間的插值。

曲面的bezier公式是用s,t兩個插值變數來控制,而不是t乙個。s等於乙個值時,t都要從0到n來遍歷一遍生成一條曲線。

glmap2f (glenum target, glfloat u1, glfloat u2, glint ustride, glint uorder, glfloat v1, glfloat v2, glint vstride, glint vorder, const glfloat *points);

glenable(gl_map2_texture_coord_2);

glenable(gl_map2_vertex_3);

glevalcoord2f((glfloat)i/30.0, (glfloat)j/8.0);

glmapgrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);

glenable(gl_auto_normal);

glevalmesh2(gl_fill, 0, 20, 0, 20);

#include #include glfloat ctrlpoints[4][3] = , , 

, };

glint genpointnum = 30;

void init(void)

void display(void)

void reshape(int w, int h)

void keyboard(unsigned char key, int x, int y)

}int main(int argc, char** argv)

#include #include glfloat ctrlpoints[4][4][3] = , , 

, },

, ,

, },

, ,

, },

, ,

, }};void display(void)

glpopmatrix ();

glflush();

}void init(void)

void reshape(int w, int h)

void keyboard(unsigned char key, int x, int y)

}int main(int argc, char** argv)

#include #include glfloat ctrlpoints[4][4][3] = ,,,

},,,,

},,,,

},,,,

}};void initlights(void)

; glfloat position = ;

glfloat mat_diffuse = ;

glfloat mat_specular = ;

glfloat mat_shininess = ;

glenable(gl_lighting);

glenable(gl_light0);

gllightfv(gl_light0, gl_ambient, ambient);

gllightfv(gl_light0, gl_position, position);

glmaterialfv(gl_front, gl_diffuse, mat_diffuse);

glmaterialfv(gl_front, gl_specular, mat_specular);

glmaterialfv(gl_front, gl_shininess, mat_shininess);

}void display(void)

void init(void)

void reshape(int w, int h)

void keyboard(unsigned char key, int x, int y)

}int main(int argc, char **argv)

#include #include #include glfloat ctrlpoints[4][4][3] = , , 

, },

, ,

, },

, ,

, },

, ,

, }};glfloat texpts[2][2][2] = , },

, }};

void display(void)

#define imagewidth 64

#define imageheight 64

glubyte image[3*imagewidth*imageheight];

void makeimage(void)

}}void init(void)

void reshape(int w, int h)

void keyboard(unsigned char key, int x, int y)

}int main(int argc, char** argv)

QT風格(QStyle) 繪製基本元素時使用的標誌

qstyle stateflag 繪製基本元素時使用的標誌 qstyle state none 指示視窗小部件沒有狀態。qstyle state active 指示小部件處於活動狀態。qstyle state autoraise 用於指示是否應在工具按鈕上使用自動提公升外觀。qstyle state...

觸發器基本使用

1 after觸發器 之後觸發 a insert觸發器 b update觸發器 c delete觸發器 2 instead of 觸發器 之前觸發 觸發器語句中使用了兩種特殊的表 deleted 表和 inserted 表。deleted 表用於儲存 delete 和 update 語句所影響的行的...

不使用定時器實現動態繪製動畫

在實現乙個簡單動畫時,往往都會使用定時器,現在我們在 中不使用定時器來實現乙個動畫,首先我們要找乙個計時器,這是關鍵,動畫是有禎頻的,計時是必須的。查了 msdn gettickcount 這個函式能夠滿足我們的需要。例子的特效是實現逐行掃瞄的效果,因此 實現如下 在動畫體類中寫入兩個函式 計時操作...