How to | スプラインプリミティブでグラフィックスを作成する方法
Wolfram言語は,ベジエ(Bézier)曲線,Bスプライン曲線,Bスプライン曲面等の完全に統合されたスプライングラフィックスプリミティブを提供する.スプラインプリミティブはスプラインの任意次数および有理式等の広範に渡るユーザコントロールをサポートする.スプラインプリミティブは複雑なグラフィックスを作成する簡単な方法を提供する.
BezierCurveは,ある「制御点」で定義される複合ベジエ曲線を描く.デフォルトで三次ベジエ曲線が使用される:
Graphics[BezierCurve[{{0, 0}, {1, 1}, {2, 0}, {3, 1}}]]BSplineCurveをGraphicsと一緒に使って,7つの制御点からなる三次Bスプライン曲線を作成する:
Graphics[BSplineCurve[{{1, -1}, {2, 1}, {3, -1}, {4, 1}, {5, -1}, {6, 1}, {7, -1}}, SplineDegree -> 4]]pts = Table[{i, (-1)^i}, {i, 7}];
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts]}]SplineDegreeオプションはスプライン曲線の内在する多項式次数を制御する.通常,次数が高ければ高いほど結果の曲線はより滑らかなものとなる.
ここではTableを使ってBSplineCurveを1から6まで変化するSplineDegreeと一緒に反復させることによって,6つの異なるスプライン曲線を同じ制御点集合から作成する:
pts = Table[{i, (-1)^i}, {i, 7}];
Table[Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts, SplineDegree -> d]}], {d, 1, 6}]SplineKnotsオプションはBスプライン曲線の形に対して詳細な制御を提供する.SplineKnotsの値が指定されていない場合には,Wolfram言語は結果の曲線が全体的に滑らかで端点は補間されているようなデフォルトのノット列を返す:
pts = {{0, 0}, {0, 2}, {2, 3}, {4, 0}, {6, 3}, {8, 2}, {8, 0}};
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts]}]以下は同じ曲線であるが,デフォルトのノットの値が明示的に示されている.最初と最後の
個の繰り返すノットによって曲線は端点を通る.ここで
はスプラインの次数である.残りのノットは均等に配置される:
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts, SplineKnots -> {0, 0, 0, 0, (1/4), (1/2), (3/4), 1, 1, 1, 1}]}]真ん中でノットの値1/2を繰り返すことによって,曲線の滑らかさを減少させることができる:
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts, SplineKnots -> {0, 0, 0, 0, (1/2), (1/2), (1/2), 1, 1, 1, 1}]}]SplineClosedオプションがTrueに設定される場合,Wolfram言語は滑らかで閉じられたBスプライン曲線を作成する:
pts = {{0, 0}, {0, (1/2)}, {1, (1/2)}, {1, 0}};Graphics[BSplineCurve[pts]]Graphics[BSplineCurve[pts, SplineClosed -> True]]SplineWeightsオプションは各点に重みを割り当てるのに使うことができる.曲線は点の方向により大きな重みで引っ張られる:
pts = Table[{i, (-1)^i}, {i, 7}];SplineWeightsに明示的な設定を行わない場合,Wolfram言語は各点に同じ重みを割り当てる:
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts]}]SplineWeightsで5の重みが与えられている真ん中の点に向かって曲線は引っ張られている:
Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts, SplineWeights -> {1, 1, 1, 5, 1, 1, 1}]}]数学的に,非一様な重みはNURBSとしても知られる有理Bスプライン関数を作成する.NURBSは通常のBスプラインが表せない形を表現することができる.例えば,BSplineCurveを使い,SplineWeightsをwの値に,そしてSplineKnotsをkの値に設定することによって正確な円を作成する:
pts = {{.5, 0}, {1, 0}, {1, 1}, {.5, 1}, {0, 1}, {0, 0}, {.5, 0}};
w = {1, .5, .5, 1, .5, .5, 1};
k = {0, 0, 0, 1 / 4, 1 / 2, 1 / 2, 3 / 4, 1, 1, 1};Graphics[{Green, Line[pts], Red, Point[pts], Orange, BSplineCurve[pts, SplineWeights -> w, SplineKnots -> k]}]Graphics3D[BezierCurve[{{0, 0, 0}, {1, 1, 1}, {2, -1, 1}, {3, 0, 2}}]]Graphics3D[BSplineCurve[{{0, 0, 0}, {1, 1, 1}, {2, -1, 1}, {3, 0, 2}, {4, 1, 1}}]]曲線をTubeで囲むことによって,管に入ったスプライン曲線を3Dで作成することができる.以下の例では,管の半径は0.2である:
Graphics3D[Tube[BezierCurve[{{0, 0, 0}, {1, 1, 1}, {2, -1, 1}, {3, 0, 2}}], 0.2]]Graphics3D[Tube[BSplineCurve[{{0, 0, 0}, {1, 1, 1}, {2, -1, 1}, {3, 0, 2}, {4, 1, 1}}], 0.2]]制御点に半径のリストを関連付けることによって,いろいろな半径を持つ管を作成できる:
radii = {0.1, 0.2, 0.5, 0.2, 0.1};Graphics3D[Tube[BSplineCurve[{{0, 0, 0}, {1, 1, 1}, {2, -1, 1}, {3, 0, 2}, {4, 1, 1}}], radii]]BSplineSurfaceは3Dの点の行列で定義されるテンソル積Bスプライン曲面を作成する:
pts = Table[{i, j, (-1)^i + j}, {i, 5}, {j, 5}];
Graphics3D[{BSplineSurface[pts], Red, Point /@ pts}]BSplineCurveのオプションがすべて同じように使える.しかし曲面に対しては,それぞれのパラメータ的な方向に別々にオプションを指定することができる.例えば以下のSplineDegree設定は,1つの方向については次数1,もう1つの方向については次数3でBスプライン曲面を作成する:
Graphics3D[{BSplineSurface[pts, SplineDegree -> {1, 3}], Red, Point /@ pts}]Bスプライン曲線と同様に,有理曲面,つまりNURBS曲面は,SplineWeightsを使って作成できる.コンピュータを使ったデザインアプリケーションの多くはNURBSを使って工業用の曲面を表す.以下の例では直角の円筒状管を生成する:
pts = {{{.5, 0, -.5}, {0, 0, -.5}, {0, 1, -.5}, {.5, 1, -.5}, {1, 1, -.5}, {1, 0, -.5}, {.5, 0, -.5}}, {{.5, 0, 0.7}, {0, 0, 0.7}, {0, 1, 0.7}, {.5, 1, 0.7}, {1, 1, 0.7}, {1, 0, 0.7}, {.5, 0, 0.7}}, {{.5, 0, 0.9}, {0, 0, 0.9}, {0, 1, 1.5}, {.5, 1, 1.5}, {1, 1, 1.5}, {1, 0, 0.9}, {.5, 0, 0.9}}, {{.5, -0.1, 1}, {0, -0.1, 1}, {0, .5, 2}, {.5, .5, 2}, {1, .5, 2}, {1, -0.1, 1}, {.5, -0.1, 1}}, {{.5, -0.3, 1}, {0, -0.3, 1}, {0, -0.3, 2}, {.5, -0.3, 2}, {1, -0.3, 2}, {1, -0.3, 1}, {.5, -0.3, 1}}, {{.5, -1.5, 1}, {0, -1.5, 1}, {0, -1.5, 2}, {.5, -1.5, 2}, {1, -1.5, 2}, {1, -1.5, 1}, {.5, -1.5, 1}}};w = {{1, .5, .5, 1, .5, .5, 1}, {1, .5, .5, 1, .5, .5, 1}, {1, .5, .5, 1, .5, .5, 1}, {1, .5, .5, 1, .5, .5, 1}, {1, .5, .5, 1, .5, .5, 1}, {1, .5, .5, 1, .5, .5, 1}};
uk = {0, 0, 0, (1/4), (1/2), (3/4), 1, 1, 1};
vk = {0, 0, 0, (1/4), (1/2), (1/2), (3/4), 1, 1, 1};
Graphics3D[{
FaceForm[Yellow, Blue],
BSplineSurface[pts, SplineKnots -> {uk, vk}, SplineDegree -> 2, SplineWeights -> w, SplineClosed -> {False, True}]}]