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

NURBS

Áttekintés

A feladat egy NURBS-görbe kirajzolására képes program elkészítése, mely a görbe megjelenítése mellett a görbe alakját befolyásoló adatok valós idejű megváltoztatását is lehetővé teszi. A görbepontokat a gyakorlaton megismert képlet segítségével kell kiszámolni.

Elvárt jellemzők

Általános elvárások

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),
  • lehetővé teszi a súlyok megváltoztatását,
  • lehetővé teszi a csomóértékek megváltoztatását, új csomó hozzáadását, a csomók számának csökkentését (természetesen a fokszám változtatásával),
  • által kirajzolt görbe valós időben követi a kontrollpontok, súlyok és csomóértékek megváltozását,
  • a görbepontok kiszámításához a gyakorlaton megismert képletet használja,
  • megakadályozza az illegális értékek megadását, azaz
    • biztosítja, hogy a csomóvektor elemei monoton növekvő sorozatot alkotnak,
    • biztosítja, hogy a csomóértékek száma minden pillanatban a kontrollpontok és a fokszám összege plusz egy,
    • a fokszám értékét a megfelelő határok között tartja, azaz a fokszám nem lehet kisebb, mint $1$, és mindig kisebb, mint a kontrollpontok száma,
    • biztosítja, hogy minden súly nagyobb, mint nulla.

Felhasználói felület

Olyan felhasználói felületet kell készíteni, mely lehetővé teszi a görbe alakját befolyásoló paraméterek kényelmes módosítását. Természetesen ez egy szubjektív, nem mérhető elvárás, azonban két tulajdonságot érdemes szem előtt tartani. Az egyik, hogy kézenfekvő módon lehessen változtatni a paramétereket. A másik pedig az, hogy a súlyok és a csomók aktuális értéke valamilyen módon mindig megjelenjen.

Használhatunk például csúszkákat a súlyok módosításához, vagy kihasználhatjuk az egérgörgőt. Azaz, ha az egérmutatót egy kontrollpont fölé visszük, akkor a görgő segítségével módosíthatjuk a kontrollponthoz rendelt súlyt. Utána egy adott pont helyére a pont súlyával arányban álló sugarú kört rajzolhatunk.

A kiszámítás módja

Legyenek adottak a következők:

  • $n + 1$ darab kontrollpont: $P_0, P_1, \ldots, P_{n}$,
  • $n + 1$ darab súly, oly módon, hogy $w_i > 0, \; \forall i = 0, 1, \ldots, n$
  • $p$, a görbe foka, melyre teljesül, hogy $1 \leq p \leq n$
  • $n + 1 + p + 1$ (azaz a kontrollpontok száma és a fokszám plusz egy) darab csomóérték, melyekre teljesül, hogy

    $$ t_i \leq t_{i + 1}, \; \forall i = 0, 1, \ldots, n + p $$

A görbét leíró függvény a következő:

$$ Q(t) = \sum_{i=0}^{n}R_{i, p}(t)P_i \qquad t \in \lbrack t_p, t_{n + 1} \rbrack, $$

ahol

$$ R_{i, p}(t) = \frac{N_{i, p}(t) \cdot w_i}{\sum\limits_{j = 0}^{n}N_{j, p}(t) \cdot w_j}, $$

és

$$ N_{i, 0}(t) = \begin{cases} 1, & \text{ha } t_i \leq t < t_{i + 1} \\ 0, & \text{egyébként} \end{cases} $$$$ N_{i, p}(t) = \frac{t - t_i}{t_{i + p} - t_i} \cdot N_{i, p - 1}(t) + \frac{t_{i + p + 1} - t}{t_{i + p + 1} - t_{i + 1}} \cdot N_{i + 1, p - 1}(t). $$

A fenti képletben, ha bármely tört esetén a nevező értéke $0$ lenne, akkor a tört értékét definíció szerint $0$-nak tekintjük.

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 görbe kirajzolásához legalább három darab kontrollpontot kell elhelyezni. A csomóértékek és a fokszám módosítását lehetővé tevő mezők csak ezután fognak megjelenni. Ha az egérmutató egy kontrollpont fölött van, akkor az adott kontrollponthoz tartozó súlyt az egérgörgő segítségével módosíthatjuk.

A demonstráció működéséhez a WebGL és ES6 technológiákat támogató böngésző szükséges.


In [3]:
addScript("js/nurbs-homework", "nurbs-homework")


Out[3]:

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


Out[2]: