In [1]:
from IPython.core.display import HTML
from string import Template
def jsConfig():
    src = """
    <script>require.config({ baseUrl: 'https://rawgit.com/kompgraf/course-material/master/assets/' });</script>
    """
    return HTML(src)
def addScript(script, identifier):
    src = Template("""
    <div id="${identifier}-container"></div>
    <script>require(['${script}'], main => main($$("#${identifier}-container"), '${identifier}'));</script>
    """)
    return HTML(src.substitute(script = script, identifier = identifier))
jsConfig()


Out[1]:

Hermite-ív

Bevezetés

Az Hermite-ív az első paraméteres görbe, amivel megismerkedünk. Ez egy olyan harmadfokú görbe, melynek előállításához az egyes kontrollpontok mellett minden kontrollponthoz meg kell adnunk a görbe adott pontbeli érintővektorát.

A feladat

Tegyük fel, hogy adott két síkbeli pont, $P$ és $Q$, továbbá adott a $P$-beli érintővektor, $v$ és a $Q$-beli érintővektor, $w$. Egy olyan $H(t)$ ($t \in [0, 1]$) harmadfokú polinomot keresünk, mely teljesíti a következő feltételeket:

$$ \begin{align*} H(0) &= P \\ H(1) &= Q \\ H^{\prime}(0) &= v \\ H^{\prime}(1) &= w \end{align*} $$

Polinomiális alak

Vezessük le az előző feltételekből a polinomiális alakot! Ez azt jelenti, hogy meg kell határoznunk a $h_0, h_1, h_2, h_3$ súlyfüggvényeket.

Nézzük meg, hogy pontosan hogyan is néz ki $H(t)$:

$$ H(t) = h_0(t) \cdot P + h_1(t) \cdot Q + h_2(t) \cdot v + h_3(t) \cdot w $$

Pusztán az előző képlet és a feltételek ismeretében már elkezdhetjük egyenként meghatározni a súlyfüggvényekben szereplő együtthatókat.

$h_0(t)$

Részletesen csak az első súlyfüggvényt vezetjük le, hiszen az együtthatók meghatározása a maradék három esetben teljesen analóg módon elvégezhető.

Kezdjük azzal, hogy felírjuk a sülyfüggvényt és deriváltját még egyelőre csupa ismeretlen együtthatóval:

$$ \begin{align*} h_0(t) &= a_0 \cdot t^3 + b_0 \cdot t^2 + c_0 \cdot t + d_0 \\ h_0^{\prime}(t) &= 3 a_0 \cdot t^2 + 2 b_0 \cdot t + c_0 \end{align*} $$

Most pedig a $H(t)$-re vonatkozó feltételeket vezessük át $h_0(t)$-re:

  • Ha $H(0) = P$, akkor $h_0(0) = 1$.
  • Ha $H(1) = Q$, akkor $h_0(1) = 0$.
  • Ha $H^{\prime}(0) = v$, akkor $h_0^{\prime}(0)=0$.
  • Ha $H^{\prime}(1) = w$, akkor $h_0^{\prime}(1)=0$.

Folytassuk a levezetést most már a $h_0(t)$-re vonatkozó feltételekkel:

$$ \begin{align*} h_0(0) &= d_0 &= 1 \\ h_0(1) &= a_0 + b_0 + c_0 + d_0 &= 0 \\ h_0^{\prime}(0) &= c_0 &= 0 \\ h_0^{\prime}(1) &= 3a_0 + 2b_0 + c_0 &= 0 \end{align*} $$

Az első egyenletből következik, hogy $d_0 = 1$, a harmadik egyenletből pedig, hogy $c_0 = 0$. Tehát marad két egyenlet két ismeretlennel:

$$ \begin{align*} a_0 + b_0 + 1 &= 0 \\ 3a_0 + 2b_0 &= 0 \end{align*} $$

Ezeket megoldva kapjuk, hogy $a_0 = 2$ és $b_0 = -3$.

Az összes együttható ismeretében most már felírhatjuk, hogy

$$ h_0(t) = 2t^3 -3t^2 + 1. $$

$h_1(t), h_2(t), h_3(t)$

A maradék három bázisfüggvény azonos levezetés után a következő formában áll elő:

$$ \begin{align*} h_1(t) &= -2t^3 + 3t^2 \\ h_2(t) &= t^3 -2t^2 + t \\ h_3(t) &= t^3 - t^2 \end{align*} $$

Ábrázoljuk a súlyfüggvényeket!


In [2]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

In [3]:
def hermite():
    t = np.linspace(0, 1, 100)

    h0 = (2*(t**3)) + (-3 * (t**2)) + 1
    h1 = (-2*(t**3)) + (3 * (t**2))
    h2 = t**3 + (-2 * (t**2)) + t
    h3 = t**3 + - t**2

    fig = plt.figure()

    axes = fig.add_axes([0, 0, 1, 1])

    axes.set_xlim([0, 1])
    axes.set_ylim([-0.3, 1.3])

    axes.plot(t, h0, 'r', label='$h_0$')
    axes.plot(t, h1, 'g', label='$h_1$')
    axes.plot(t, h2, 'b', label='$h_2$')
    axes.plot(t, h3, 'cyan', label='$h_3$')
    
    axes.axhline(y=0, color='k')
    
    axes.legend(loc=2);

    axes.set_xlabel('t')
    axes.set_title('Hermite súlyfüggvények');


hermite()


Mátrix alak

A polinomiális alak ismeretében a mátrix alak felírása már nem jelenthet kihívást, hiszen csak az $M$ mátrixot kell összeállítanunk a bázisfüggvények együtthatóiból:

$$ M = \begin{bmatrix} 2 & -3 & 0 & 1 \\ -2 & 3 & 0 & 0 \\ 1 & -2 & 1 & 0 \\ 1 & -1 & 0 & 0 \end{bmatrix}. $$

Tehát

$$ H(t) = \begin{bmatrix} P & Q & v & w \end{bmatrix} \cdot \begin{bmatrix} 2 & -3 & 0 & 1 \\ -2 & 3 & 0 & 0 \\ 1 & -2 & 1 & 0 \\ 1 & -1 & 0 & 0 \end{bmatrix} \cdot \begin{bmatrix} t^3 \\ t^2 \\ t \\ 1 \end{bmatrix}. $$

Az Hermite-ív hátrányai

A legnagyobb probléma az Hermite-ívvel az, hogy előállításához nemcsak kontrollpontokra, hanem érintővektorokra is szükség van, mint bemeneti információ. Sokkal szélesebb körben használhatóak az olyan eljárások, melyekhez a kontrollpontokon kívül más geometriai információra nincsen szükség. Látni fogjuk majd, hogy a Bézier-görbe vagy a Cardinal Spline mennyivel kényelmesebb lehetőséget biztosít a görbét előállításához.

Demonstráció

A következő demonstráció bemutat egy Hermite-ívvel. A pontok és az érintővektorok is mozgathatóak, utóbbiak a végpontok megragadásával és vonszolásával.


In [2]:
addScript("js/hermite-demo", "hermite-demo")


Out[2]:

Források


In [3]:
def styling():
    styles = open("../../styles/custom.html", "r").read()
    return HTML(styles)
styling()


Out[3]: