3次ベジエ曲線と直線の交点は、3次方程式を解ければ求められる。
3次方程式を解くには解の公式を使えばよさそう。 そのためには、複素数の累乗根を求められる必要があるらしい。 なので、まずC# で複素数を扱う方法を調べる。
http://msdn.microsoft.com/ja-jp/library/6fbs5e2h(VS.80).aspx このページを見つけた。
読んでみると、普通に複素数のクラスを作っていたようなので、まねる。
struct Complex { public double real; public double imag; public Complex(double real, double imaginary) //constructor { this.real = real; this.imag = imaginary; } //中略 }
加えて、 -, * の演算子もオーバーロードしておく。
public static Complex operator -(Complex c1, Complex c2) { return new Complex(c1.real - c2.real, c1.imag - c2.imag); } public static Complex operator -(Complex c1) { return new Complex(-c1.real, -c1.imag); } public static Complex operator *(Complex c1, Complex c2) { return new Complex(c1.real * c2.real - c1.imag * c2.imag, c1.real * c2.imag + c1.imag * c2.real); }
そして、累乗根の関数を作る
// n乗根 public static Complex[] proot(Complex c, int i) { Complex[] result = new Complex[i]; double theta = Math.Atan2(c.imag, c.real); double r = Math.Sqrt(c.real*c.real + c.imag*c.imag); double r13 = Math.Pow(r, (1.0/i)); for (int cnt = 0; cnt < i; cnt++) { result[cnt] = new Complex( (r13 * Math.Cos((theta + Math.PI * 2.0 * cnt) / i)), (r13 * Math.Sin((theta + Math.PI * 2.0 * cnt) / i))); } return result; }
手順
- z = a + bi を、極形式にする。 -> z = r(cos θ + i sinθ) rは複素数の絶対値、θは偏角というものらしい。 r=√(a*a + b*b) θ=atan2(b, a)
- z^(1/3) = r^(1/3) * (cos θ + i sin θ)^(1/3)
- r の3乗根は Pow(r, 1.0/i) で求める。(3乗根なら i = 3)
- 後ろのほうは、ド・モアブルの定理で、 cos(θ/3) + i sin(θ/3) にする
- 角度を 2π ずつ加えながら繰り返し、 3乗根なら3つの解を得る。
参考文献:高校数学+α (p283-p291)http://www.h6.dion.ne.jp/~hsbook_a/