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]:

1. házi feladat - Zárt B-Spline görbe

Áttekintés

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.

Elvárt jellemzők

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

  • megjeleníti a kontrollpontokat,
  • megjeleníti a kontrollpoligont,
  • tetszőleges számú kontrollpont elhelyezését teszi lehetővé,
  • már elhelyezett kontrollpont mozgatását lehetővé teszi (például drag & drop módszer segítségével),
  • által kirajzolt görbe valós időben követi a kontrollpontok mozgását, azaz a görbe megváltozása nem csak akkor lesz látható, amikor egy kontrollpont vonszolását befejeztük, hanem a vonszolás közben végig,
  • a görbepontok kiszámításához a gyakorlaton megismert $GMT(t)$ formulát használja,
  • a megadott kontrollpontok alapján egy zárt, harmadfokú szegmensekből felépülő B-Spline görbét jelenít meg.

Természetesen a görbét csak a negyedik kontrollpont elhelyezése után kell elkezdeni kirajzolni.

A kiszámítás módja

A felhasznált mátrixok

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 számítás menete

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.

Interaktív demonstráció

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]: