470 likes | 586 Views
繪製平面曲線. 靜宜大學資工系 蔡奇偉 副教授 2001-2006. 大綱. 基本概念 繪製顯函式的圖形 隱函式 參數曲線 立方參數曲線 Hermite 立方曲線 混合函數 Bezier 曲線 B-Spline 曲線. 基本概念. 繪製任意平面曲線的方法是用一些短線段來逼近曲線。線段數愈多,逼近的效果愈好,但計算時間也相對提高。有時,為了線段的數目以提高繪製的效率,我們可以在曲率大的地方,使用較多的線段,在曲率較小的部份,使用較少的線段。. a. b. 繪製顯函式的圖形.
E N D
繪製平面曲線 靜宜大學資工系 蔡奇偉 副教授 2001-2006
大綱 • 基本概念 • 繪製顯函式的圖形 • 隱函式 • 參數曲線 • 立方參數曲線 • Hermite 立方曲線 • 混合函數 • Bezier 曲線 • B-Spline 曲線
基本概念 繪製任意平面曲線的方法是用一些短線段來逼近曲線。線段數愈多,逼近的效果愈好,但計算時間也相對提高。有時,為了線段的數目以提高繪製的效率,我們可以在曲率大的地方,使用較多的線段,在曲率較小的部份,使用較少的線段。
a b 繪製顯函式的圖形 對任意的顯函式(explicit function)y = f(x),下列的演算法用 n條線段來繪製 f(x) 介於區間 [a, b] 的圖形。 • dx = (b – a) / n; • glBegin(GL_LINE_STRIP); • for (x = a; x <= b; x += dx) • glVertex2f (x, f(x)); • glEnd();
r (u,v) b a (u,v) 隱函式 有些曲線(如圓形)無法用前一頁所說的顯函式來定義。但這些曲線可用隱函式 f(x, y) = 0 來定義,如: 圓: 橢圓:
然而,隱函式並不適合用來繪製其所代表的曲線。原因在於我們必須求出滿足方程式 f(x, y) = 0 的解,在多半的情形下,方程式的解並不容易算出來。
(x(T), y(T)) (x(0), y(0)) 參數曲線 從另一個角度來看,曲線是一個「粒子」運動所行經的軌跡。這個軌跡可以用參數式 P(t) = (x(t), y(t)), 0 £ t £T, 來描述。 P(t) 代表於 t 時間「粒子」所在的位置座標,所以 P(0) = (x(0), y(0))是曲線的起點,P(T) = (x(T), y(T)) 是曲線的終點。
(x(T), y(T)) (x(0), y(0)) 參數曲線 P(t) 在 t 時間位置的切向量( tangent vector )是: 切向量表示運動的方向 斜率表示運動的速度 斜率( slope )則是:
範例一:直線 假定已知兩點 P0 = (x0, y0) 和 P1 = (x1, y1) ,如上圖所示。則通過這兩點的直線參數式如下: 令 P(t) = (x(t), y(t)),則
範例二:以原點為圓心且半徑為 1 的單位圓 以下三個參數式都滿足公式 x2 + y2 = 1,所以都會產生單位圓的曲線。 雖然三者都是單位圓的參數式,不過就如下一頁的圖形所示,等分參數區間所得的逼近線段,三者並不相同。其中, (2) 最均勻,但是 (3) 的計算最簡易。
對任意的參數式 P(t) = (x(t), y(t)) ,下列的演算法用 n條線段來繪製 P(t) 介於參數區間 [a, b] 的圖形。 • dt = (b – a) / n; • glBegin(GL_LINE_STRIP); • for (t = a; t <= b; t += dt) • glVertex2f (x(t), y(t)); • glEnd();
立方參數曲線 從解析幾何的觀點來說,若要用多項式來定義連續且平滑的曲線,則最少必須用立方多項式。立方參數曲線的定義如下: 其中的 aix和 aiy, i = 0, 1, 2, 3 是方程式的係數。
令 則 P(t) 可寫成: 也可寫成底下的矩陣形式:
P(t) P(1) P(0) Hermite 立方曲線 Hermite 立方曲線用兩個端點與端點上的切向量來唯一定義一條立方曲線。給定兩點 P(0) 和 P(1) 與切向量 P’(0) 和 P’(1) ,如下圖所示: 我們想找出滿足這些條件的立方參數曲線 P(t)(如上圖所示)
由於 代入前述的端點條件後,我們的問題變成解底下的線性方程式組: 以求出係數向量
前述方程組的解如下: 經過一番整理後,我們得到底下的 P(t) 公式:
P2 P1 P0 Herrmite 曲線的應用 我們可用三點 P0, P1, 和 P2 和底下的公式來定義一條 Hermite 曲線。 註:也就是說:把 P2 – P0 和 P1 – P2 視為端點上的切向量。
P2 P2 P0 P1 P1 P0 P2 P1= Q0 P0 Q1 Q2
/* An algorithm for drawing a Hermite cubic curve. It takes three points P0, P1, and P2, and a parameter n to control the fineness of the curve. It is assumed that point is the following structure type : typedef struct {float x, y; } point; */ HermiteCurve(point P0, point P1, point P2, int n) { float dt, t2, t3, f1, f2, f3, f4; point PT0, PT1; dt = 1.0/n; // t runs from 0 to 1. PT0.x = P2.x - P0.x; PT0.y = P2.y - P0.y; PT1.x = P1.x – P2.x; PT1.y = P1.y – P2.y; glBegin(GL_LINE_STRIP);
for (t = 0.0; t <= 1.0; t += dt) { t2 = t * t; t3 = t2 * t; // t3 = t * t * t f1 = 2.0*t3 - 3.0*t2 + 1.0; f2 = -2.0*t3 + 3.0*t2; f3 = t3 - 2.0*t2 + t; f4 = t3 - t2; glVertex2f( f1*P0.x + f2*P1.x + f3*PT0.x + f4*PT1.x, f1*P0.y + f2*P1.y + f3*PT0.y + f4*PT1.y ); } glEnd(); }
混合函數 上面 Hermite 參數式中的函式 F1(t), F2(t), F3(t),和 F4(t) 稱為混合函數(blending function) 這麼稱呼的原因是:這些函數把邊界條件 P(0), P(1), P’(0), 和 P’(1) 混合起來而產生出曲線。 下面兩頁展示這些混合函數從 0 到 1 之間的圖形。
Bezier 曲線 Pierre Bézier 是法國的數學家。他曾提出底下的曲線定義來輔助雷諾汽車廠的設計師們設計車體。 給定 n + 1 個控制點(control points)P0, P1, …, Pn。則 n-階的 Bezier 曲線 P(t) 為: 其中混合函數 Bi,n(t) 稱為 Bernstein 多項式。 下面兩頁展示若干 Bi,n(t) 的圖形。
n = 2 n = 3
n = 4 n = 5
一些 Bézier 曲線的範例: Linear Bézier curves Quadratic Bézier curves Cubic Bézier curves
convexhull Bezier 曲線的性質 Bezier 曲線必定落於控制點所定義的 convex hull 之內。
Bezier 曲線在 P0的切向量方向和向量 P0P1一致。 Bezier 曲線在 Pn的切向量方向和向量 Pn-1Pn一致。 這是因為 這是因為 根據前頁的公式:
立方 Bezier 曲線 立方 Bezier 曲線可由四個控制點 P0, P1, P2, 和 P3來定義。
Composite Bezier Curve
使用 Bezier 曲線來定義 字型的外框
令 Cn(t, P0,…, Pn) 代表由控制點 P0,…, Pn所定義的 n-階 Bezier 曲線。我們可以得到以下的公式: • Cn(t, P0,…, Pn) = (1- t) Cn-1(t, P0,…, Pn-1) + t Cn-1(t, P1,…, Pn) 証明: