プログラムで動的なacosを項とする多項式で、内角の正確な値を求めているんだけど・・・
なんで、atanでもasinでもなくacosにしたのかは、二辺挟角のイメージがしやすかったからかな。
動的といいつつ、45度は常に静的に持つことにして、なんやかんやそこに集約させて、直線なのか、直角なのか、それ以外なのか、などと判定していたりする。
多項式の各項は、
a*acos(b/√c)
a, b, c∈Z
という格好にしている。
多項式でも、ある程度の共通部分があるものは、まとめて項数を減らしていかなければ、判定として使えない。
a*acos(1/√2) = a*45度
という項は、aが0でも静的に保持してある。
これしか項がなく、a=2なら直角、a=4なら直線と判定すればよい。
他の項は、aが0なら、消してしまう。
45度以外の項のaは負であると、面倒なので正になるようにする。
どうするかというと、
a*acos(b/√c) = 2*a*acos(1/√2) - a*acos((c-b^2)/√c)
簡単に言えば、直角三角形の内角の関係式を持ち出す。
これで、45度=acos(1/√2)の項以外は、すべてのaは正になる。
同様に、ある2項のcが共通で、
a1*acos(b/√c) + a2*acos((c-b^2)/√c)
a3=min(a1,a2)
ならば、
(a0+2*a3)*acos(1/√2) + (a1-a3)*acos(b/√c) + (a2-a3)*acos((c-b^2)/√c)
となって、(a1-a3)か(a2-a3)のどちらかが0となるので、どちらかの項が減る。
当然、ある2項の(b/√c)が共通ならば、
a1*acos(b/√c) + a2*acos(b/√c) = (a1 + a2)*acos(b/√c)
となって、項数が減るのは当たり前。
では、ある2項のcは共通だが、bの関係性がない場合は、加法定理を使ってみる。
a*acos(b1/√c) + a*acos(b2/√c) = a*acos((b1*b2-(c-b1^2)*(c-b2^2))/√(c*c))
展開してもよいのだが、簡潔になるならよいが、プログラム的にはこのままでも良さそうだ。
こういう操作を繰り返すと、bが負になる場合がある。
そんなときはどうするか。
a*acos(b/√c) = 4*acos(1/√2) - a*acos(-b/√c)
とすればよいだろう。
またaが負になってしまうが、それは先の方法で正にすればよい。
さて、cは肥大化するが、bと約分することができる場合がある。
そんなこんなを繰り返せば、項数はある程度で落ち着くことだろう。
同じ角度なのに、多項式が異なる場合があるが、これは直線でなく、角であるならば問題視するほどのことではなさそうである。
ver.0.01はこれくらいにしておくかな。
ver.0.00に比べると、ファイルサイズにすると2/5くらいに減ったし、多項式を動的に作りこんだから変形パターンは完全かどうかはわからないがかなり網羅できただろう。
次は何をやろうかな。
角度が0になると、点が重なって、操作ができなくなるというのがある。
そういう操作が出来ないように作りこむかな。
面積が負になる操作が出来てしまうが、これはこれで、途中経過だとすれば、それはそれでよいだろう。
線分が交差するようなクエストは作らないので、まぁいいか。
↧
acos part 3
↧