ベジェ曲面はベジェ曲線であり、制御点は静止しているのではなく、他のベジェ曲線に沿って移動しています。
B(0,u) = (1-u)^3
B(1,u) = 3*u*(1-u)^2
B(2,u) = 3*u^2*(1-u)
B(3,u) = u^3
C[0..3, 0..3] = control points
Curve(t,C0,C1,C2,C3) = B(0,t)*C0 + B(1,t)*C1 + B(2,t)*C2 + B(3,t)*C3
Surface(s,t,C[0..3,0..3]) =
Curve(t, Curve(s, C[0,0], C[1,0], C[2,0], C[3,0]),
Curve(s, C[0,1], C[1,1], C[2,1], C[3,1]),
Curve(s, C[0,2], C[1,2], C[2,2], C[3,2]),
Curve(s, C[0,3], C[1,3], C[2,3], C[3,3]))
t
これらの関数は、 (および)の特定の値について曲線(またはサーフェス)をサンプリングしますs
。
この記事では、合計を計算する前に、Bernstain多項式(B(i,u)
関数)の値をキャッシュする方法について説明しています。これは、毎回再計算する必要がないようにするためです。
次に、細分化について話します。これには、各曲線の4つの制御点を4つの2つのグループに分割することが含まれます。各グループは、元の曲線の半分をトレースします。
これをサーフェスに進めると、各行曲線が2つに分割され、次に各列曲線が2つに分割されます。これにより、元の曲線の一部をトレースする4つのサーフェスが得られます。
細分割は、通常、カーブ/サーフェスをサンプリングするよりも高速です。
SplitCurve(C0,C1,C2,C3) = [
C0, # First control-point of first sub-curve
(C0 + C1)/2, # Second control-point of first sub-curve
(C0 + 2*C1 + C2)/4, # Third control-point of first sub-curve
(C0 + 3*C1 + 3*C2 + C3)/8, # Shared first/last control-point
(C1 + 2*C2 + C3)/4, # Second control-point of second sub-curve
(C2 + C3)/2, # Third control-point of second sub-curve
C3 # Fourth control-point of second sub-curve
]
SplitSurface(C[0..3,0..3]) =
col0 = SplitCurve(C[0,0], C[0,1], C[0,2], C[0,3])
col1 = SplitCurve(C[0,0], C[0,1], C[0,2], C[0,3])
col2 = SplitCurve(C[0,0], C[0,1], C[0,2], C[0,3])
col3 = SplitCurve(C[0,0], C[0,1], C[0,2], C[0,3])
return [
SplitCurve(col0[0], col1[0], col2[0], col3[0]),
SplitCurve(col0[1], col1[1], col2[1], col3[1]),
SplitCurve(col0[2], col1[2], col2[2], col3[2]),
SplitCurve(col0[3], col1[3], col2[3], col3[3]),
SplitCurve(col0[4], col1[4], col2[4], col3[4]),
SplitCurve(col0[5], col1[5], col2[5], col3[5]),
SplitCurve(col0[6], col1[6], col2[6], col3[6])
]
すべてのコントロールポイントが同じピクセル内に配置されるまで、各サブサーフェスを細分割し続けます。ここで「ピクセル」とは、投影された曲線を指します。これを確認するための単純な方法は、各コントロールポイントを画面座標に投影することです。
三角形メッシュを作成するには、コントロールポイントを一定の回数分割してから、各サーフェスの左上のコントロールポイントを選択します。