SSブログ

Bezier曲線による関数の近似 - その7 [レンズ形状をBezierで描く]

Bezier曲線を関数近似に使う話。今日でひと段落。今日は3次元空間内の曲面をBezier曲面で近似する。とりあえずできるようにはなったんだけど、問題は少し残る....

曲線の場合と同じように端点からの微分の値を一致させることを考える。3次元空間内の3次Bezier曲面の場合、$4\times 4 \times 3 = 48$個の変数がある。さっきの8分の1球では$z=1$にふたつの点が一致してしまっていたが、曲面の内部にある点(曲面と一致する点)は隅っこの4つの端点で残り12点を微係数から決めることになる。

曲線では扱いやすいように$y=f(x)$の陽な形に書けるのを前提にした。曲面の場合それでは限定しすぎるし3次元では対称性が悪いので、 \begin{equation} (x,y,z)=\boldsymbol{f}(u,v) \equiv \left(f_x(u,v),f_y(u,v),f_z(u,v) \right) \hspace{5mm} 0 \le u \le 1,\hspace{3mm}0 \le v \le 1 \end{equation} のようにパラメトリックに書かれているとして、これをBezier曲面で近似する。Bezier曲面も媒介変数表示なので、なんだかほとんど変わらないような気もするけど、やってみる。

ただし、わかりきったことではあるけどひとつ問題がある。というのは、2次元の曲線の場合は場所に関する微分を使ったけど、これはパラメータに関する微分を使うことになる。場所に関する微分だと幾何学がちゃんと反映さてちゃんと面の傾きになるけど、パラメータに関する微分は面の傾きでもなんでもなく、ただ形式的な微分でしかない。

パラメータに関する微分を幾何学的に意味あるものにするためには、要素ではなくかならずベクトルとしてあつかう必要がある。つまり例えば微分は必ず \begin{equation} \left( \frac{\partial x}{\partial u},\frac{\partial y}{\partial u},\frac{\partial z}{\partial u}\right) \end{equation} などというふうに単独の微分ではなく、組として現れないといけない。例えばこの微分はある点での面内にあるひとつのベクトルを表すけど、単独の$\partial x/\partial u$だけでは何の意味もなくて、そのお互いの比だけに意味がある。

しかしこの場合すごく簡単なので、気をつけながらとりあえずちょっとやってみることにする。3次のBezier曲面だと決めないといけない点の座標はさっきも書いた通り12点なので、
  • uに関する1階微分の端点での値
  • vに関する1階微分の端点での値
  • uvに関するそれぞれ1階微分の端点での値
で端点が4つあるのでこれで3次元空間ベクトルについての方程式が12個になってしまって、2階微分の出る幕がない(みっつめは微分の微分なので2階微分ではあるけど)。でもそれで一応変数の数と独立な式の数が一致する($u$と$v$の両方についての微分のおかげで中の方の制御点の座標が含まれる)。媒介変数にすると陰関数なんかも表すことができるので、その自由度がとられるということだな。4次にして制御点を増やすと2階微分まで含めることができるけど、そうすると制御点の合計が25点になる。決めるべき変数と独立な方程式の数を合わせる自信がないのでやめておく。

けどそうすると数は多いけどめちゃ簡単というか、単なる1次の連立方程式になって \begin{align} \boldsymbol{P}_{0,0} &= \boldsymbol{f}(0,0) \nonumber \\ \boldsymbol{P}_{0,1} &= \boldsymbol{f}(0,0)+\frac{1}{3}\boldsymbol{f}^{0,1}(0,0) \nonumber \\ \boldsymbol{P}_{0,2} &= \boldsymbol{f}(0,1)-\frac{1}{3}\boldsymbol{f}^{0,1}(0,1) \nonumber \\ \boldsymbol{P}_{0,3} &= \boldsymbol{f}(0,1) \nonumber \\ \boldsymbol{P}_{1,0} &= \boldsymbol{f}(0,0)+\frac{1}{3}\boldsymbol{f}^{1,0}(0,0) \nonumber \\ \boldsymbol{P}_{1,1} &= \boldsymbol{f}(0,0)+\frac{1}{3}\boldsymbol{f}^{0,1}(0,0)+\frac{1}{3}\boldsymbol{f}^{1,0}(0,0)+\frac{1}{9}\boldsymbol{f}^{1,1}(0,0) \nonumber \\ \boldsymbol{P}_{1,2} &= \boldsymbol{f}(0,1)-\frac{1}{3}\boldsymbol{f}^{0,1}(0,1)+\frac{1}{3}\boldsymbol{f}^{1,0}(0,1)-\frac{1}{9}\boldsymbol{f}^{1,1}(0,1) \nonumber \\ \boldsymbol{P}_{1,3} &= \boldsymbol{f}(0,1)+\frac{1}{3}\boldsymbol{f}^{1,0}(0,1) \nonumber \\ \boldsymbol{P}_{2,0} &= \boldsymbol{f}(1,0)-\frac{1}{3}\boldsymbol{f}^{1,0}(1,0) \nonumber \\ \boldsymbol{P}_{2,1} &= \boldsymbol{f}(1,0)+\frac{1}{3}\boldsymbol{f}^{0,1}(1,0)-\frac{1}{3}\boldsymbol{f}^{1,0}(1,0)-\frac{1}{9}\boldsymbol{f}^{1,1}(1,0) \nonumber \\ \boldsymbol{P}_{2,2} &= \boldsymbol{f}(1,1)-\frac{1}{3}\boldsymbol{f}^{0,1}(1,1)-\frac{1}{3}\boldsymbol{f}^{1,0}(1,1)+\frac{1}{9}\boldsymbol{f}^{1,1}(1,1) \nonumber \\ \boldsymbol{P}_{2,3} &= \boldsymbol{f}(1,1)-\frac{1}{3}\boldsymbol{f}^{1,0}(1,1) \nonumber \\ \boldsymbol{P}_{3,0} &= \boldsymbol{f}(1,0) \nonumber \\ \boldsymbol{P}_{3,1} &= \boldsymbol{f}(1,0)+\frac{1}{3}\boldsymbol{f}^{0,1}(1,0) \nonumber \\ \boldsymbol{P}_{3,2} &= \boldsymbol{f}(1,1)-\frac{1}{3}\boldsymbol{f}^{0,1}(1,1) \nonumber \\ \boldsymbol{P}_{3,3} &= \boldsymbol{f}(1,1) \label{control3d} \end{align} ただし \begin{align} \boldsymbol{f}^{0,1}(u,v) &= \frac{\partial}{\partial u}\boldsymbol{f}(u,v) \nonumber \\ \boldsymbol{f}^{1,0}(u,v) &= \frac{\partial}{\partial v}\boldsymbol{f}(u,v) \nonumber \\ \boldsymbol{f}^{1,1}(u,v) &= \frac{\partial^2}{\partial u\partial v}\boldsymbol{f}(u,v) \end{align} である。ごちゃごちゃしてるけどずいぶん簡単。もちろん、式はそれぞれ全部3次元座標についての式で、成分に分かれていないのでさっきの注意点は問題がない。 またもちろん、もとの関数の変数の範囲を$(0,1)$に限定していたけど、任意の$(a,b)$でも結果は変わらない(0を$a$、1を$b$に読み替えるだけ)。

さてこれで、前回ヒューリスティックに求めた8分の1球の制御点を計算してみる。 \begin{equation} \boldsymbol{f}(u,v) = \left(\cos \frac{\pi u}{2} \cos \frac{\pi v}{2},\sin\frac{\pi u}{2} \cos \frac{\pi v}{2},\sin \frac{\pi v}{2}\right) \end{equation} として式-\ref{control3d}に代入して制御点を求めて、Bezier曲面を描いたのがこれ。
0208spherebezier3d.png
前回ヒューリスティックに決めたのと制御点の配置はよく似ている。半径の残差の半径に対する比をプロットしてみると
0208spherebezier3derror.png
となって、誤差の形状はよく似ている(向きが前後逆にプロットされてしまった。もう描き直すのめんどくさい。ごめんなさい)。しかし誤差の最大値が2%を超えていてヒューリスティックに求めた場合より一桁近く大きい。

ヒューリステックに求めたものは、2次元の曲線から計算した。2次元のは陽関数と仮定して2次の微係数まで考慮したものだった。特徴的な数値(中間の制御点の座標値)が2次の微係数まで考慮した場合$(\sqrt{7}-1)/3 \approx 0.548...$だったのが、媒介変数だと$\pi/6\approx 0.5236...$になってる。そのぶんだけ誤差が増える方向にいったんだろうけど、媒介変数表示の方が表現の自由度は大きい。

しかし最初に書いたように、これはパラメータに関する微分を一致させただけなので、例えば元の関数のパラメータの実座標に対する測度が結果に影響する。 例えば今の8分の1球をパラメータの2次で書き直して \begin{equation} \boldsymbol{f}(u,v) = \left(\cos \frac{\pi u^2}{2} \cos \frac{\pi v^2}{2},\sin\frac{\pi u^2}{2} \cos \frac{\pi v^2}{2},\sin \frac{\pi v^2}{2}\right) \end{equation} としても媒介変数の関数としては何の違いもないし、これで描画しても8分の1球でさっきのと全く同じになる。しかし当然制御点の位置は全然違って
0214othersphere.png
こんなふうになるし、球からの誤差は
0214othersphereerror.png
で倍ほどに増えて符号も逆になっている。この問題をどうやって解決すればいいか考えてたんだけど難しくてよくわからない。

関数を陽に書いて、つまり$z=f(x,y)$などと書いて、2次元平面の場合と同じように2次まで考慮するやりかたでBezier曲面を決めようとしたけど、途中の式がめちゃ大きくなってしまうのと、変数と方程式の数を合わせようとすると対称性が悪くなってしまって、結局挫けた。$z=f(x)g(y)$の形に限定すれば2次元の場合と同じ方法が使えそうだったけど、もういいや。めんどくさい。

それでもこれで次数の高いトーリック非球面なんかの体積計算を数値的に安定に実行できる。誤差の大きさの評価を忘れないようにしないといけないけど。

11.1  フィレットの表現

まあいいとして、CADなんかでよくあるフィレットをこの方法で制御点を求めてBezier曲面としてプロットしてみた。
0209fillet1.png
0209fillet2.png
赤丸は制御点の位置。どっちもA、B、Cの3つの3次Bezier曲面でできていて、ふたつの円弧の上にある端点がAとB、BとCの曲面で共通になっている。まあ、見た目はもっともらしい。

12  媒介変数表示された曲線をBezier曲線で近似する

逆に、最初に戻って2次元平面の場合に陽関数に制限せず、媒介変数で表示された関数をBezier曲線で近似するのは曲面の場合を2次元に落とせばいいので簡単。 この場合も単なる1次の連立方程式になるので、結果だけを書くと、もとの関数を \begin{equation} (x,y) = \boldsymbol{f}(t) \equiv \left(f_x(t),f_y(t) \right) \hspace{5mm}0 \le t \le 1 \end{equation} として \begin{align} \boldsymbol{P}_0 &= \boldsymbol{f}(0) \nonumber \\ \boldsymbol{P}_1 &= \boldsymbol{f}(0)+\frac{1}{3}\boldsymbol{f}'(0) \nonumber \\ \boldsymbol{P}_2 &= \boldsymbol{f}(1)-\frac{1}{3}\boldsymbol{f}'(1) \nonumber \\ \boldsymbol{P}_3 &= \boldsymbol{f}(1) \end{align} となる。こっちのほうがずっと簡単だったな。先にこれをやればよかった。これだと3次元空間内の曲線への拡張も簡単にできる(変数と方程式の数を合わせる心配がない)。僕には必要ないのでやらないけど。

でも誤差は大きい。例えば4分の1円では陽関数の場合最大誤差が0.2%ぐらいだったのが、これだと1.5%ぐらいになった。体積計算に使うにはちょっと誤差が大きいけど、表示のためにはこれでも十分な場合が多いんではないかな。まあアプリケーションと近似対象の関数の形しだいだよな、結局。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

チック・コリアが死んだmRNAワクチン ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。