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]:
A feladat egy zárt B-Spline görbe kirajzolására képes program elkészítése, mely a görbe megjelenítése mellett a kontrollpontok le- és áthelyezését biztosítja. A görbepontokat a gyakorlaton megismert, mátrixokon alapuló módszer segítségével kell számolni.
A házi feladat megvédése csak akkor lehet sikeres, ha a program a jellemzőit tekintve hiánytalan. Az elvárt jellemzőket teljesítő program
Természetesen a görbét csak a negyedik kontrollpont elhelyezése után kell elkezdeni kirajzolni.
A görbepontokat a gyakorlatokon megismert $GMT(t)$ alakú formula segítségével kell meghatározni, ahol a megfelelő mátrixok a következőek:
$$ \begin{align*} G &= \;\;\, \begin{bmatrix} P_i && P_{i + 1} && P_{i + 2} && P_{i + 3} \end{bmatrix} \\ M &= \frac{1}{6} \begin{bmatrix} -1 & 3 & -3 & 1 \\ 3 & -6 & 0 & 4 \\ -3 & 3 & 3 & 1 \\ 1 & 0 & 0 & 0 \\ \end{bmatrix} \\ T(t) &= \;\;\, \begin{bmatrix} t^3 \\ t^2 \\ t \\ 1 \\ \end{bmatrix} \end{align*} $$A teljes görbét kisebb, egymáshoz csatlakozó harmadrendű darabokból kell felépíteni, melyeket kontrollpont-négyesek segítségével képzünk. Egy-egy ilyen darabot nevezünk a teljes görbe egy szegmensének.
Ha adottak a $P_0, P_1, \ldots, P_n$ kontrollpontok, akkor hagyományos esetben $n - 2$ szegmenst tudunk elkészíteni. Zárt esetben azonban minden egyes kontrollpontból kiindulva képezni fogunk egy szegmenst, azaz a szegmensek száma meg fog egyezni a kontrollpontok számával. Ha $i$-vel jelöljük a szegmensek indexeit, akkor $i = 0,1,\ldots, n$. Ne feledjük, hogy $n$ ebben az esetben a kontrollpontok száma mínusz egy!
Például $4$ kontrollpont esetén $4$ darab szegmensünk lesz. Az $i=1$ indexű szegmenst ekkor úgy hozzuk létre, hogy az utolsó három és az első kontrollpont fogja meghatározni. Az ezt követő szegmenst az első kettő és az utolsó kettő. Végül az $i=3$ indexű szegmenst az utolsó és az első három. Mindig az egymással szomszédos négy kontrollpontot vesszük.
Az $i$ szegmens elkészítéséhez először képeznünk kell a megfelelő pontokból a $G$ mátrixot. Általánosítva, zárt görbe esetén a ez a következő lesz:
$$ G = \begin{bmatrix} P_{i \; \mathrm{mod} \; n + 1} && P_{i + 1 \; \mathrm{mod} \; n + 1} && P_{i + 2\; \mathrm{mod} \; n + 1} && P_{i + 3\; \mathrm{mod} \; n + 1} \end{bmatrix}, $$ahol $i$ a szegmens indexe, $i = 0, 1, \ldots n$, $n$ pedig a kontrollpontok száma mínusz egy. $x \; \mathrm{mod} \; y$ pedig $x$ $y$-nal vett osztási maradékát jelenti.
Ha megvan a $G$ mátrix, futtassuk a $t$ paramétert a $[0, 1]$ tartományon, és állítsuk össze a $T(t)$ mátrixot, majd számoljuk ki a $t$-nek megfelelő görbepontot. Ismételjük meg ezt az összes szegmensre, és készen vagyunk.
Az elkészítendő program kipróbálható a lenti téglalapban. Kattintással helyezhetőek el új kontrollpontok, és vonszolással helyezhetőek át a meglevőek.
A demonstráció működéséhez a WebGL és ES6 technológiákat támogató böngésző szükséges.
In [2]:
addScript("js/hf-01-zart-b-spline", "hf-01-zart-b-spline")
Out[2]:
In [3]:
def styling():
styles = open("../../styles/custom.html", "r").read()
return HTML(styles)
styling()
Out[3]: