機械学習基礎理論独習

誤りがあればご指摘いただけると幸いです。数式が整うまで少し時間かかります。リンクフリーです。

勉強ログです。リンクフリーです
目次へ戻る

2次ベジェ曲線から3次ベジェ曲線への変換

2次ベジェ曲線を3次ベジェ曲線に変換

2次ベジェ曲線より、3次ベジェ曲線の方が自由度が高いので、変換ができます。
3次ベジェ曲線の制御点を {\bf P}_0,{\bf P}_1,{\bf P}_2,{\bf P}_{3} とすると、
2次ベジェ曲線の端点は3次ベジェ曲線の端点と一致するので、制御点は  {\bf P}_0,{\bf Q}_1,{\bf P}_{3} となります。

3次ベジェ曲線上の点を P_3(t) 、2次ベジェ曲線上の点を P_2(t) とします。
位置と1階微分が一致するようにすればよいので、次の式が成り立ちます。

\begin{eqnarray}
\left\{
    \begin{array}{l}
     P_3(t)=P_2(t)\\
     P_3'(t)=P_2'(t)
    \end{array}
  \right.\tag{1}
\end{eqnarray}

ここで、P_3(t),P_2(t),P_3'(t),P_2'(t) は以下のようになります。

\begin{eqnarray}
&&P_3(t)={\bf P}_{0} \left(1 - t\right)^{3} + 3 {\bf P}_{1} t \left(1 - t\right)^{2} + {\bf P}_{2} t^{2} \cdot \left(3 - 3 t\right) + {\bf P}_{3} t^{3}\\
&&P_2(t)={\bf P}_{0} \left(1 - t\right)^{2} + {\bf P}_{3} t^{2} + {\bf Q}_{1} t \left(2 - 2 t\right)\\
&&P_3'(t)=- 3 {\bf P}_{0} \left(1 - t\right)^{2} + 3 {\bf P}_{1} t \left(2 t - 2\right) + 3 {\bf P}_{1} \left(1 - t\right)^{2} - 3 {\bf P}_{2} t^{2} + 2 {\bf P}_{2} t \left(3 - 3 t\right) + 3 {\bf P}_{3} t^{2}\\
&&P_2'(t)={\bf P}_{0} \cdot \left(2 t - 2\right) + 2 {\bf P}_{3} t - 2 {\bf Q}_{1} t + {\bf Q}_{1} \cdot \left(2 - 2 t\right)\\
\end{eqnarray}

(1) を解くと、以下のようになります。

\begin{eqnarray}
\left\{
    \begin{array}{l}
    {\bf P}_{1} = \dfrac{{\bf P}_{0}}{3} + \dfrac{2 {\bf Q}_{1}}{3}\\
    {\bf P}_{2} = \dfrac{{\bf P}_{3}}{3} + \dfrac{2 {\bf Q}_{1}}{3}
    \end{array}
  \right.\tag{2}
\end{eqnarray}

(2) を変形すると、元の制御点の線分上の長さが2/3に新しい制御点があることがわかります。

\begin{eqnarray}
\left\{
    \begin{array}{l}
    {\bf P}_{1} - {\bf P}_0 = \dfrac{2}{3}({\bf Q}_{1} - {\bf P}_0)\\
    {\bf P}_{2} - {\bf P}_3 = \dfrac{2}{3}({\bf Q}_{1} - {\bf P}_3)
    \end{array}
  \right.
\end{eqnarray}


Pythonのコード

上記の連立方程式は、PythonのライブラリSymPyを使って解きました。
そのコードを載せておきます。

import sympy

sympy.var("p_0 p_1 p_2 p_3 q_1 t")

p3 = (1-t)**3 * p_0 + 3 * (1-t) ** 2 * t * p_1 + 3 * (1-t) * t ** 2 * p_2 + t ** 3 * p_3
p3d = sympy.diff(p3, t)
p2 = (1-t)**2 * p_0 + 2 * (1-t) * t * q_1 + t ** 2 * p_3
p2d = sympy.diff(p2, t)

eq1 = sympy.Eq(p3, p2)
eq2 = sympy.Eq(p3d, p2d)
solve = sympy.solve ([eq1, eq2], [p_1, p_2]) 

print("\\begin{eqnarray}")
print("&&P_3(t)=" + sympy.latex(p3) + "\\\\")
print("&&P_3'(t)=" + sympy.latex(p3d) + "\\\\")
print("&&P_2(t)=" + sympy.latex(p2) + "\\\\")
print("&&P_2'(t)=" + sympy.latex(p2d) + "\\\\")
print("&&" + sympy.latex(solve) + "\\\\")
print("\\end{eqnarray}")

コードの実行結果
\begin{eqnarray}
&&P_3(t)=p_{0} \left(1 - t\right)^{3} + 3 p_{1} t \left(1 - t\right)^{2} + p_{2} t^{2} \cdot \left(3 - 3 t\right) + p_{3} t^{3}\\
&&P_3'(t)=- 3 p_{0} \left(1 - t\right)^{2} + 3 p_{1} t \left(2 t - 2\right) + 3 p_{1} \left(1 - t\right)^{2} - 3 p_{2} t^{2} + 2 p_{2} t \left(3 - 3 t\right) + 3 p_{3} t^{2}\\
&&P_2(t)=p_{0} \left(1 - t\right)^{2} + p_{3} t^{2} + q_{1} t \left(2 - 2 t\right)\\
&&P_2'(t)=p_{0} \cdot \left(2 t - 2\right) + 2 p_{3} t - 2 q_{1} t + q_{1} \cdot \left(2 - 2 t\right)\\
&&\left\{ p_{1} : \frac{p_{0}}{3} + \frac{2 q_{1}}{3}, \ p_{2} : \frac{p_{3}}{3} + \frac{2 q_{1}}{3}\right\}\\
\end{eqnarray}

目次へ戻る