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]:
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.
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*} $$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.
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:
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. $$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()
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}. $$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.
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]:
In [3]:
def styling():
styles = open("../../styles/custom.html", "r").read()
return HTML(styles)
styling()
Out[3]: