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?

独自に定義した曲線関数 MCQBezierのいろいろ

Last updated at Posted at 2024-07-08

はじめに

・MCQBezier(Midpoint-Controlled Quadratic Bezier Curve)は、指定する三点を通る二次ベジェ曲線です。

・私個人のプロジェクトで重要な役割をするのですが、いちいち紙のノートを探すのが面倒なのでここにまとめようと思います。

・Bezier曲線の入力を変更しただけで、実質的にBezier曲線と違いはありません。

定義

t = 割合, s = 始点, h = 中点, e = 終点 とする
$$
MCQBezier(t,s,h,e) = t^2 (2s + 2e - 4h) - t (3s + e - 4h) + s
$$

または A = 2s + 2e - 4h, B = A + s - eとし

$$
MCQBezier(t,s,h,e) = t^2 A - t B + s
$$

$$
\frac{d}{dt}MCQBezier(t,s,h,e) = 2tA - B
$$

導出

本来の二次ベジェ曲線をQBezierとする。QBezierの指定する定数の三点を、順番にs,b,eとすると、QBezierの定義は次のとおりである。
$$
QBezier(t,s,b,e)=s(1-t)^2 + 2bt(1-t)+et^2
$$
この曲線のt = 0.5 の時の点をhとする。bをhに入れ換えることを考える
$$
h = QBezier(0.5,s,b,e)= \frac{1}{4} s+ \frac{1}{2}b+\frac{1}{4}e
$$$$
2h = b+\frac{1}{2} s+\frac{1}{2}e
$$$$
b = 2h-\frac{1}{2} s-\frac{1}{2}e
$$

このbをQBezier(t,s,b,e)に代入した式が、MCQBezier(t,s,h,e)である。

長さ(近似)

ベジェ曲線の長さは微分の値(Δtに対する変化量)の長さの総和で求められる。
ガウス・ルジャンドル求積法を用いて0 <= t <= 1の範囲の長さを近似する。
$$
二次関数の近似に、必要な2つの定数は±\frac{1}{\sqrt{3}}
$$$$
d(t) = |2At-B|
$$$$
Length = \frac{1}{2}(d(\frac{1+\frac{1}{\sqrt{3}}}{2})+d(\frac{1-\frac{1}{\sqrt{3}}}{2}))
$$

点pに最も近いMCQBezier(t)

距離の微分を立式する

$MCQBezier(t)と点pの距離をL(t)とする$
$$
L(t) = \sqrt{(MCQBezier(t).x-p.x)^2 + (Yの項) + (Zの項)}
$$

$L(t)の微分が0になるとき、最近傍点となる(分子=0を解く)$
$$
\frac{d}{dt} L(t)の分子 = \frac{d}{dt}(MCQBezier(t).x - p.x)^2 + (Yの項) + (Zの項)
$$
$一旦、\frac{d}{dt}(MCQBezier(t) - p)^2を計算する。$

$$
MCQBezier(t) - p = t^2 A - tB+s-p より
$$$$
\frac{d}{dt}(MCQBezier(t) - p)^2 = t^3( 4A^2 ) + t^2( -6AB ) + t( -4Ap + 4As + 2B^2 ) + 2Bp - 2Bs
$$
以上の計算から
$\frac{d}{dt} L(t)の分子=$
$t^3(4A^2.x+ Yの項 + Zの項)$
$+t^2(-6AB.x+ Yの項 + Zの項)$
$+t( (-4Ap + 4As + 2B^2 ).x + Yの項 + Zの項)$
$+(2Bp - 2Bs).x + Yの項 + Zの項)$

これ=0を解の公式を使って解く

$a = 4A^2.x+ yzの項$
$b = -6AB.x+ yzの項$
$c = (-4Ap + 4As + 2B^2 ).x + yzの項$
$d = (2Bp - 2Bs).x + yzの項$

static float[] SolveCubicEquation(float a, float b, float c, float d)
        {
            if (a == 0.0)
            {
                Console.WriteLine("Error:a = 0.0"); 
                Console.WriteLine("This equation is NOT Cubic");
                return null;
            }
            float A, B, C, p, q, D,inv_a, inv_3,inv_27;
            inv_a = 1.0f / a;
            inv_3 = 0.3333f;
            inv_27 = 0.037037f;
            A = b * inv_a;
            B = c * inv_a;
            C = d * inv_a;
            p = B - A * A / 3.0f;
            q = 2.0f * A * A * A * inv_27 - A * B * inv_3 + C;
            D = q * q / 4.0f + p * p * p * inv_27;
            if (D < 0.0)
            {//three real solutions
                float theta = (float)Math.Atan2(Math.Sqrt(-D), -q * 0.5f);
                float[] result = new float[3];
                result[0] = (float)(2f * Math.Sqrt(-p * inv_3) * Math.Cos(theta *inv_3) - A *inv_3);
                result[1] = (float)(2f * Math.Sqrt(-p * inv_3) * Math.Cos((theta + 2f * Math.PI) * inv_3) - A * inv_3);
                result[2] = (float)(2f * Math.Sqrt(-p * inv_3) * Math.Cos((theta + 4f * Math.PI) * inv_3) - A * inv_3);
                foreach(var res in result)
                {
                    Console.WriteLine($"res {res}");
                }
                return result;
            }
            else
            {//single real solution and two imaginary solutions(c.c)
                float u =(float) Cbrt(-q * 0.5 + Math.Sqrt(D)), v = (float)Cbrt(-q * 0.5 - Math.Sqrt(D));
                float[] result = new float[1];
                result[0] = u + v - A *inv_3;
                Console.WriteLine($"res {result[0] }");
                return result;
            }
        }

四次関数の形から、3つの実数解をもつ場合はtが最小と最大の実数解のどちらかが最小のtとなる

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?