ベジェ曲線のパラメータ表示

今回の授業では、ベジェ曲線(Bezier curve)のパラメータ表示を解説します。

1. 曲線のパラメータ表示

以下の楕円上にある点を考えます。 $$ x^2+4y^2=1 $$

当該楕円の点を次の形で表すことが可能です。

$$ x(t) = \cos(2 \pi t), \quad y(t)= 2 \sin(2 \pi t), \quad (t \in [0,1]) $$

つまり、(媒介)変数 $t$ の変化に従って点$(x(t),y(t))$は一つの曲線を描くことができます。上記の式は曲線のパラメータ表示と呼ばれます。

例1:楕円のパラメータ表示

In [45]:
#例1
import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(0,10,1001);

x = np.cos(2*np.pi*t)
y = 2*np.sin(2*np.pi*t)

plt.plot(x,y,'-')
plt.grid()
plt.axes().set_aspect('equal')

演習1:

  • 以下のパラメータ曲線を描いてみてください。ただし、$n=1,2,3,4$にすること。

$$ x(t) = \cos^n(2\pi t), \quad y(t) = \sin^n(2\pi t), \quad (t \in [0,1]) $$

  • $x(t)$, $y(t)$を自由に修正して、パラメータ曲線の形を確認してください。例えば、

$$ x(t) = \cos^5(2\pi t), \quad y(t) = \sin(2\pi t), \quad (t \in [0,1]) $$

$$ x(t) = \cos(5\pi t), \quad y(t) = \sin(2\pi t), \quad (t \in [0,10]) $$

2. ベジェ曲線のパラメータ表示

実際の応用では、2次元平面上の曲線を自由に表現するために、以下のパラメータ曲線で現れるベジェ曲線が使用される。

$$ F(t) = (X(t), Y(t)) $$

ここで、 $$ X(t) = X_0 B_{0,n}(t) + X_1 B_{1,n}(t) + \cdots + X_n B_{n,n}(t) = \sum_{i=0}^n X_i B_{i,n}(t) $$ $$ Y(t) = Y_0 B_{0,n}(t) + Y_1 B_{1,n}(t) + \cdots + Y_n B_{n,n}(t) = \sum_{i=0}^n Y_i B_{i,n}(t) $$ また、制御点は以下の点となる。 $$ P_0=(X_0,Y_0), \quad P_1 = (X_1,Y_1),\quad \cdots, \quad P_n=(X_n,Y_n) $$

3次ベジェ曲線の例

ホームページにあるBezier曲線の補足資料(3次ベジェ曲線の例)を参考してください。

以下の制御点で定義されるベジェ曲線を描画します。 $$ P_0 = (0,0), P_1 = (0.5,1), P_0 = (2,-1), P_3=(3,0) . $$

In [60]:
import numpy as np
import matplotlib.pyplot as plt

#制御点のリストと描画
P=np.array([[0,0], [0.5,1], [2,-1], [3,0]]).T;
plt.plot(P[0,:],P[1,:],'b-o')


#Bernstein基底関数の定義
import math
def Bernstein(i,n,x):
    value = math.factorial(n) / ( math.factorial(i) * math.factorial(n-i) )* x**(i) * (1-x)**(n-i)
    return value

#ベジェ曲線のパラメータ表示
t = np.linspace(0,1,101);
X = 0; Y = 0;

for i in range(4):
    X += Bernstein(i,3, t)*P[0,i]
    Y += Bernstein(i,3, t)*P[1,i]
    
plt.plot(X,Y,'r-')
plt.grid()

ベジェ曲線の描画コードを関数とします。

以下のコードでは、draw_bezierという関数を定義して、与えられる点のリストに対応するベジェ曲線を描画することができます。

In [64]:
#制御点のリストと描画
P=np.array([[0,0], [0.5,1], [2,-1], [3,0]]).T;

#Bernstein基底関数の定義
import math
def Bernstein(i,n,x):
    value = math.factorial(n) / ( math.factorial(i) * math.factorial(n-i) )* x**(i) * (1-x)**(n-i)
    return value

def draw_bezier(P):
    
    import numpy as np
    import matplotlib.pyplot as plt

    plt.plot(P[0,:],P[1,:],'b-o')

    #ベジェ曲線のパラメータ表示
    t = np.linspace(0,1,101);
    X = 0; Y = 0;

    for i in range(4):
        X += Bernstein(i,3, t)*P[0,i]
        Y += Bernstein(i,3, t)*P[1,i]

    plt.plot(X,Y,'r-')
    plt.grid()
    
draw_bezier(P)

演習2

Windowsのツール「ペイント」を使ってで絵を描いてください。また、制御点の座標を記録して、Pythonのコードで絵を描いて再現してください。

特に、以前の授業で描いた「家」の飾りとして、どうぶ太陽、河、坂の輪郭などを描いてください。

In [59]:
# 演習2のコード