0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

陰関数でベジェ曲線の交点を求める ~ その2:DKA法を試してみた

Last updated at Posted at 2025-08-18

はじめに

2つのベジェ曲線の交点を、陰関数を経由して代数方程式に変換し解(交点のパラメータ)を求める方法(Implicitization)について、前回、Sage Math上で解を求めました。

代数方程式の解を求める(求根)処理の実装を目指すため、DKA法を試してみました。
結果、うまくいく場合といかない場合がありました。

DKA法について

DKA法の解説や実装例は以下を参考にしました。

DKA法はニュートン・ラフソン法をベースに、高次方程式に対応した求根アルゴリズムです。複素根に対応しています。関数の次数と各項の係数が入力となります。
根を包含する円周上に等間隔で初期値を配置し、近似計算を反復します。
複数の近似解がひとつの根に収束しないよう、近似解どうしの差が漸化式の計算に反映されるしくみ(斥力の作用)が備わっています。
初期値の円の半径を求める処理が面倒くさいですが、正しく設定する必要があります。小さすぎると不安定な挙動が発生し、大きすぎると収束が遅くなります。

例①(うまくいく)

 inter_ex1.png

曲線0(オレンジ色)を $(x, y)=(f_0(t), g_0(t))$、曲線1(青色)を $(x, y)=(f_1(u), g_1(u))$ とします。
曲線0の陰伏方程式 $F_0(x,y)=0$ について、$x$ に $f_1(u)$、$y$ に $g_1(u)$ を代入した $u$ についての9次方程式を $F_0(u)=0$ とします。
曲線1の陰伏方程式 $F_1(x,y)=0$ について、$x$ に $f_0(t)$、$y$ に $g_0(t)$ を代入した $t$ についての9次方程式を $F_1(t)=0$ とします。

$F_0(u)=0$ と $F_1(t)=0$ の係数と根をSage Mathで求めました。それぞれ以下の通りです。
(項0は $u^9$、$t^9$ の係数、項9は $u^0$、$t^0$の係数)

$F_0(u)$の係数 $F_1(t)$の係数
0 -396417457736 396417457736
1 1687229544456 -1837788312096
2 -2959049224008 3582099890784
3 2763498928752 -3814300664676
4 -1484376700032 2413858345488
5 462506013504 -925767453096
6 -80122864392 210592186686
7 6974963136 -26777484144
8 -258820272 1716328440
9 2909250 -42600087
$F_0(u)$の根 $F_1(t)$の根
0.0192470307676812 0.0705390793450691
0.0549916382769417 0.0972454495384701
0.122057002218322 0.151317532883142
0.320989106683592 0.423317135673883
0.442530534075141 0.504784914630604
0.488155778702660 0.616234378772213
0.900475882753311 0.858627731561791
0.944674407179144 0.947328062423360
0.963072466334768 0.966598091975171

この係数をDKA法に入力しました。この例ではすべての根($t$ と $u$)が $[0,1]$ の範囲の実数なので初期値の円は小さな半径で済み、迅速に収束しました。

反復の各回における近似解は以下の通りです。(左:$u$、右:$t$ )
青点線は初期値が配置される円(半径 0.8911451625812689 と 0.8150730626130066)です。
 inter_ex1u_dka1.png inter_ex1t_dka1.png

反復の各回における近似残差(Sage Mathで求めた根との距離)は以下の通りです。
どの程度の精度が必要かによりますが、15回程度の反復で収束しました。
 inter_ex1u_dka2.png
 inter_ex1t_dka2.png

例②(うまくいく)

 inter_ex3.png

係数は以下の通りです。

$F_0(u)$の係数 $F_1(t)$の係数
0 -1 1
1 18 27
2 -18 189
3 -6489 -264
4 68040 -3780
5 -209412 7803
6 128169 -2283
7 -20250 -5481
8 276534 10476
9 -153711 -3502

この例では、ベジェ曲線の交点は1つだけですが、実数根が5個ずつあります。

$F_0(u)$の根 $F_1(t)$の根
-17.4455311309653 -11.7491222197159
0.559001039805706 -1.13495840453138
1.58591522923000 0.427184956901181
4.61782798597658 1.82778197153885
5.80036113872243 2.78366617296693
-0.584112384659363 - 0.893083467241210*I -10.1061675932554 - 1.15206211156715*I
-0.584112384659363 + 0.893083467241210*I -10.1061675932554 + 1.15206211156715*I
12.0253252532746 - 13.4619234074658*I 0.528891354675582 - 0.942411682190976*I
12.0253252532746 + 13.4619234074658*I 0.528891354675582 + 0.942411682190976*I

ベジェ曲線のパラメータの値域は $[0,1]$ ですが、それより外側を作図すると以下のようなおどろおどろしい曲線となります。交点が4つあります。自己交差もあります。
 inter_ex3a.png

さらに外側を作図すると、はるか彼方にもう1つ交点があります。
パラメータの値域を無視すると交点は5個で、実根の数と一致します。
 inter_ex3b.png

反復の各回における近似解は以下の通りです。(左:$u$、右:$t$ )
初期値が配置される円の半径は 20.38309113011681 と 14.12514808245628 です。
ベジェ曲線としては、1つ以外の交点は『どうでも良い』のですが、DKA法ではそうもいかず、すべての根を包含するよう初期値の円が大きくなってしまいます。
 inter_ex3u_dka1.png inter_ex3t_dka1.png

反復の各回における近似残差は以下の通りです。
反復回数は20回程度に増やす必要があります。
 inter_ex3u_dka2.png
 inter_ex3t_dka2.png

例③(うまくいかない)

 inter_ex5.png

例②とほぼ同じですが、$P_0$ が左にずれています。
この作用で『どうでも良い』交点がはるか彼方に移動し、初期値の配置される円の半径が 624193.8162941233 と 518608.3232018586 と、とてつもなく大きくなってしまいました。
DKA法を反復50回までは試してみましたが、収束しませんでした。

ちなみに、Sage Mathで求めた係数と根は以下の通りです。

$F_0(u)$の係数 $F_1(t)$の係数
0 -2.84217094304040e-14 2.13162820728030e-14
1 4.54747350886464e-13 1.92096649698215e-8
2 4.32191882282495e-8 0.00997905112308217
3 -5184.01247445624 1727.93513568025
4 62208.0991688475 -9071.84469953083
5 -210924.160909874 13283.8409573164
6 131220.153425417 -2375.98128942742
7 29888.0681867107 -10286.8914761232
8 216514.307900543 14498.9058213240
9 -135594.460289519 -4589.97442830960
$F_0(u)$の根 $F_1(t)$の根
-567115.622411213 -248197.018538645
0.557665338289116 -1.03330670884847
1.61807431932095 0.446194297282387
5.16799108368957 1.86453498958389
5.79814264427882 2.90335369440187
-0.570941565478316 - 0.800872586604778*I -213844.115726888 - 446351.819141408*I
-0.570941565478316 + 0.800872586604778*I -213844.115726888 + 446351.819141408*I
283559.811210479 - 491136.142417216*I 0.534608073955102 - 0.882297985704637*I
283559.811210479 + 491136.142417216*I 0.534608073955102 + 0.882297985704637*I

反復回数を大幅に増やせば収束するかもしれませんがそもそも、9次関数その他の計算誤差がひどいことになっていると思われます。64ビットdoubleでは厳しいかと。
また、これがワーストケースというわけではありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?