diff --git a/.gitignore b/.gitignore
index 9d8e3a8..85f2898 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,9 @@ __pycache__/
# C extensions
*.so
+# workspace file
+*.code-workspace
+
# Distribution / packaging
.Python
env/
diff --git a/docs/notes/sem4/computer_graphics/1.md b/docs/notes/sem4/computer_graphics/1.md
deleted file mode 100644
index 184703b..0000000
--- a/docs/notes/sem4/computer_graphics/1.md
+++ /dev/null
@@ -1,303 +0,0 @@
-# Geometriák és algebrák:
-> A geometriák különböző axiómákra épülnek.
-> Például az Euklidészi síkgeometriában az egyik legfontosabb, hogy egy egyenesre egy külső pontból legfeljebb 1 olyan egyenes húzható, ami nem metszi *(ez a párhuzamos)*
-
-- Ezeknek az axiómáknak a megváltoztatása különböző eredményekhez vezethet. Például a háromszög szögeinek összege mindig:
- - Hiperbolikus geometriában: $< 180°$
- - Euklidészi geometriában: $180°$
- - Gömbi geometriában: $> 180°$
-
-## Görbület
-- **Görbék görbülete:**
- - Egy adott pontra az alábbi két definíció egyikét használhatjuk:
- - A görbület az egysebességű centripetális gyorsulás ($a_{cp} = \frac{v^2}{R}$, egysebességű = a sebesség nagysága állandó)
- - A simuló kör sugarának reciproka
- - 
- - *($\kappa = \frac{1}{r} = \frac{v^2}{r}$)*
-
-- **Gauss görbület:**
- - Egy felület (mondjuk henger) görbületét szeretnénk meghatározni egy adott pontban.
- *(Ebben a pontban a felületnek van egy normálvektora, ami merőleges a felület síkjára)*.
- - Ekkor az alakzatot a felvághatjuk síkokkal *(amik a pontot metszik és a normálvektorral párhuzamosak)*
- - Azek a síkok bármerre állhatnak és a felületet ahogy metszik, úgy egy görbét határoznak meg.
- Az így kapott görbék közül van 2, ahol az egyiknél minimális a görbület, a másiknál maximális. Ezek a metszési irányok egymásra merőlegesek *(ezek a principális / főgörbületi irányok)*
- - Az itt található görbületek szorzata a Gauss-görbület
- - 
-- [*Részletesebben*](https://youtu.be/0ZV4TjgI424?t=621)
-*(a diasorokon voltak még további alakzatok, ezeken érdemes ezt végig gondolni, a legfontosabb, hogy a normállal mindig párhuzamosak ezek a metszések)*
-
-## Gömbi geometria
-- Gömb egyenlete: $x^2 + y^2 + z^2 = R^2 = \frac{1}{K}$
-- Itt a görbület állandóan pozitív, az egyenesek is görbék
-- Fontos változás:
- - Két pont nem mindig határoz meg egy egyenest egyértelműen
- - Két egyenes mindig 2 pontban metszi egymást
- - Itt 0 darab nem metsző egyenes van (még a párhuzamosok is metszik egymást)
-- **Főkör:** 2 pont és a gömb közepe meghatároz egy síkot. A kör, ami a sík és gömb metszésével jön létre a főkör
-*(Nem mindig lehet egyértelműen meghatározni, pl. Északi sark, Déli sark, Origó pontokkal végtelensok sík van)*
-- Gömbi geometriában a legrövidebb út két pont között mindig a főkörön van
-- **Elliptikus geometria:** olyan geometria, ahol az átellenes pontok egynek számítanak
-
-- **Gömbök vetítése:**
- 
-
- 1. Középpontos vetítés:
- - csak a felső gömböt
- - egyenes tartó
- - nem kör, szög és távoltástartó
- 2. Sztereografikus vetítés:
- - a déli pólus kivételével mindent
- - nem egyenestartó
- - kör és szögtartó, de nem távolságtartó
-
-- **Mercator térkép:** hengerre vetít a gömb középpontból, de emiatt megnyúlik.
- - Szögtartó
- - Nem távolságtartó
-
-- **Számolások gömbi geometriánál:**
- - A görbület: $\kappa = 1/R^2$
- - Távolság: $R \theta = \theta / \sqrt{\kappa}$
- *(ez egy körív, ahol 2 pont között $\theta$ szög van - radiánban)*
- - Kör kerülete:
- 
- - Háromszögek:
- - $a^2 + b^2 > c^2$
- - $T = (\alpha + \beta + \gamma - \pi) / \kappa$
-
-## Hiperbolikus geometria
-- Hiperboloid egyenlete: $x^2 + y^2 - z^2 = -R^2 = \frac{1}{\kappa}$
- - *Ez levezethető komplex számmal is $(iR)^2$*
-- Itt a görbület állandóan negetív
-- Fontos változások:
- - Egy egyenesre egy külső ponból több nem metsző egyenes húzható
-- Hiperbolikus terek vetítése egy diszkre:
-
-
-- *Emlékeztető a 3. háziból - 2 kör merőleges:*
-
-
-### Minkowski tér
-- A háromdimenziós teret kiterjesztjük egy negyedik dimenzióval, ami az idő
-- Itt nem pontok, hanem események vannak jelen
- - *Mert ugyanaz a hely szerepelhet kétszer, de különböző időpontokban más-más esemény közben van*
-- Ebben a rendszerben a távolságot úgy kell érteni, hogy $x_1$ helyről $t$ idő alatt egy hatás elér-e egy $x_2$ helyre
-
-#### Projektív geometria
-> a GPU mindegyik geometriát támogatja, de projektív geometriában gondolkodik
-
-- Euklideszi geometriában nem beszélhetünk végtelenről, viszont a projektív geometriában létezik.
-- Fontos változás:
- - Itt két egyenes pontosan egy pontban metszi egymást
- *(vagy 1 pontban metszenek, vagy a végtelenben. Ha azon gondolkodnál, hogy de balra és jobbra is van végtelen, az ne aggasszon, mert az a pont jobbra és balra ugyanaz a végtelen)*
-- *Ez a rendszer nem metrikus, mert nem lehet pl. távolságról beszélni, hiszen ha a végtelen is része, akkor ami végtelen távol van, azt nem lehet számításba venni*
-- Nincsenek olyan koordináta rendszerek, amik távolságokat használnak *(fentebb említett ok miatt)* - Vagyis Descartes és Polár koordinátarendszerek nem használhatók
- - 
- - Itt a zöld és a piros pontok az **ideális pontok** ahol az egyenesek metszenék egymást.
- Mivel a geometriánkban végtelen sok egyenes lehet, ezért a piros és zöld pontok között végtelen sok ideális pont lehet még.
-- *Ha átgondoljuk, hogy van végtelen sok ideális pont, amik jobbra és balra nézve is önmaguk képviselik, akkor láthatjuk, hogy ez egy elliptikus geometria (fogalma fentebb) csak szög és távolság fogalom nélkül*
-
-## Síkgeometria
-- 2 dimenzióról beszélünk ($x$,$y$ koordinátákkal), amihez felveszünk egy harmadik tulajdonságot ($w$-t). Így képesek vagyunk Euklideszi és Projektív geometriát is mejeleníteni.
- - Projektív esetben mondjuk azt, hogy csak az egyenes, ami átmegy az origón.
- 
- Vagyis akkor van egy bizonyos végtelen pontunk, ahol minden egyenes találkozik.
- Ekkor minden pont végtelen távoli, ahol $w$ = 0, hiszen bármely egyenes, ami rajtuk átmegy, az az origón is. Vagyis az egyenesük párhuzamos lesz a (kék) síkkal, amit látunk.
-- Ambiens tér ([ambient space](https://en.wikipedia.org/wiki/Ambient_space_(mathematics))): egy olyan tér, ami valamilyen objektumot körbevesz
- - Ezek a befoglaló terek nekünk az ábrázolást segítik. Ezért az ambiens vektorokat képesnek kell lennünk összeadni és skálázni.
- - Ebből következik, hogy $w=0$ a vektoroknál és $w=1$ a pontoknál (egyéb $w$-k se nem pontok, se nem vektorok).
-- **Skaláris szorzás:**
- - $a_1 \cdot a_2 = |a_1| |a_2| \cos(\alpha)$
- - Euklideszi geometriában: $a_1 \cdot a_2 = x_1 x_2 + y_1 y_2 + z_1 z_2$
- - Nem asszociatív művelet (számít a szorzások sorrendje)
- $(u \cdot v) \cdot w \neq u \cdot (v \cdot w)$
-- **Vektoriális szorzás (kereszt szorzás):**
- - $|a_1 \times a_2 | = |a_1| |a_2| \sin(\theta)$
- - $c_x = a_y b_z - a_z b_y$
- $c_y = a_z b_x - a_x b_z$
- $c_z = a_x b_y - a_y b_x$
- - Ez sem asszociatív
-- **Vektorok tulajdonságai:**
- - Két pont különbsége vektor
- - Az ambiens térnek elemei $[x,y,0]$
- - Hossz: $|v| = \sqrt{v \cdot v}$
- - Merőlegesség: $u \perp v$ ha $u \cdot v = 0$
- - Minden vektorra végtelensok merőleges van $\lambda [y, -x, 0]$
- - Párhuzamosság: $u \parallel v$ ha $u = \lambda v$
- - Minden vektorra végtelensok párhuzamos van $\lambda [x, y, 0]$
-- **Egyenesek:**
- - Parametrikus egynlet: $r(t) = p + vt$
- *(vagyis p pontból t ideje indultunk el v vektorrala - ha végig gondolod ez valóban pontok gyűjteménye, hiszen $w=1$ mindig)*
- - Implicit egyenlet: $n \cdot (r - p) = 0$
- - Ahol $r$ egyenest határozzuk meg $p$ pontja és $n$ normálvektora segítségével
- $r(x,y) \Rightarrow [n_x, n_y, 0] \cdot [x - p_x, y - p_y, 0] = 0$
- Vagyis: $n_x x + n_y y + d = 0$
- - Ha $r$ helyére behelyettesítünk, akkor könnyen eldönthetjük, hogy egy pont rajta van-e
- *(egyébként pont azért implicit egyenlet, mert az r egyenest nem fejezzük ki explicit)*
-
-## Térgeometria
-- A cél, hogy minden legyen ugyanolyan mint a síknál, csak mostmár egyel magasabb dimenzióban
-- vektor: $[x,y,z,0]$, pont: $[x,y,z,1]$
-- a korábban megbeszélt műveletek nem válltoznak
-- az egynes egynletek továbbra is megmaradnak
-- **Sík egyenlete:**
- - Explicit: $r(u,v) = p + au + bv \qquad$ (ahol $a, b$ nem párhuzamos vektorok)
- - Implicit: $n \cdot (r-p) = 0 \qquad \qquad$ (ahol $n$ normálvektor merőleges $a, b$ vektorokra)
- Vagyis: $n_x x + n_y y + n_z z + d = 0$
-
-## Homogén koordináták
-- Homogén koordináták: ahol +1 dimenzióban megadunk egy értéket ami jelöli, hogy ideális pontról beszélünk-e
-- Ezt valamennyire láttuk, a fontos különbség, hogy a $w$ távolság jelölést is segíti nekünk
- - $[2x,2y,1] = [x,y,\frac{1}{2}]$
- mert ha osztjuk a $w$ koordinátájával, akkor $[x,y,\frac{1}{2}] / \frac{1}{2} = [2x,2y,1]$
-- Az egyenes implicit egyenlete:
- - $[X(t),Y(t),w(t)] = [X_1,Y_1,w_1](1-t) + [X_2, Y_2,w_2] \cdot t$
- - Ez 2 különböző pontból segít meghatározni az egyenest
- - *De mégis miért jobb ez? Mert ez magától kezeli a végtelen pontokat a Descartes koordinátákkal szemben*
- $n_x X / w + n_y Y / w + d = 0 \qquad w \neq 0$
- $n_x X + n_y Y + dw = 0\qquad w \neq 0$
-- Hogyan csináljunk Euklidésziből homogént:
- - Fogjuk a pontokat és mindenhol kibővítjük a pontok koordinátáit $w = 1$-el.
-
----
-
-# Kvíz
-
-> 1\. Milyen messze van az $(-5, 4)$ pont a $3x + 4y + 5 = 0$ implicit egyenletű egyenestől
-
-**Középiskolában tanultakkal megoldható:**
-*(ha van gyorsabb megoldás javítsátok)*
-
-1. Egyenesre normálvektort állítasz
-$(3, 4) \Rightarrow (4, -3)$
-2. Normálvektorral új egyenes, ami átmegy a ponton
-$4 * (-5) + (-3) * 4 + d = 0$
-$d = 32 \Rightarrow 4x -3y + 32 = 0$
-3. Az egyenesek metszéspontjának megtalálása
-$4x -3y + 32 = 0 \text{ és } 3x + 4y + 5 = 0$
-*(Mondjuk hozzáadom $\frac{3}{4}$-szer az másodikat az elsőhöz, de sok jó út van)*
-$\frac{25}{4} x + \frac{133}{4} = 0 \Rightarrow x = \frac{-143}{25}$
-$\Rightarrow y = \frac{76}{25}$
-4. Metszés pont és eredeti pont távolságának kiszámítása
-$d = \sqrt{(((-5) - (\frac{-143}{25}))^2 + (4 - \frac{76}{25})^2)} = 1.2$
-
-**Alternatív megoldás:**
-
-- képletet használunk $d = n \cdot (r-p)$, ahol $r$ az egyenes és $n$ egység hosszú
- 1. a normálvektort egységhosszúvá tesszük
- $n = (3, 4) \Rightarrow n = \frac{(3, 4)}{\sqrt{3^2 + 4^2}} = (\frac{3}{5}, \frac{4}{5})$
- *(figyeljünk, implicit egyenletnél a koordináta sorrendre)*
-
- 2. az $r-p$ kivonást elvégzzük: *(ez egy vektor r és p között)*
- A számításához használhatjuk az $r$ bármely pontját *(én az x=0 pontot választottam)*
- $R = (0, \frac{-5}{4})$
- Ekkor $r - p = (0, \frac{-5}{4}) - (-5, 4) = (5, -\frac{21}{4})$
- 3. elvégezzük a skaláris szorzást:
- $n \cdot (r-p) = (\frac{3}{5}, \frac{4}{5}) \cdot (5, -\frac{21}{4}) = \frac{3}{5} * 5 + \frac{4}{5} * -\frac{21}{4} = 3 - \frac{21}{5} = -1.2$
- 4. De miért negatív?
- Ez egy előjeles távolság, szóval függ attól, hogy a p pont az egyenes melyik oldalán van
- Vagyis, ha abszolútértékkel használjuk, akkor helyes megoldást kapunk
- $|-1.2| = 1.2$
- :cake:
-
-[(a képlet kb így jön ki)](https://brilliant.org/wiki/dot-product-distance-between-point-and-a-line/)
-
----
-> 2\. Tekintsünk 2 várost "A"-t és "B"-t az északi szélesség (lattitude) 45 fokán. Az "A" város keleti hosszúsága 165 fok, a "B" város keleti hosszúsága 50 fok.
-> Mekkora az A és B város távolsága km-ben, ha a föld sugarát 6000 km-nek vesszük?
-
-*(Ilyenkor nem használhatjuk a Távolság: $R \theta$ képletet direktben, mert x és y tengelyen is van bezárt szög és ezért vagy a sugár méretét kéne arányosítani, vagy a szöget kéne újraszámolni)*
-
-Keressük tehát azt a $\theta$ szöget, melyet a A és B *(pontosabban a beléjük húzott sugarak)* bezárnak a rajtuk átmenő főkörön.
-
-
-
- Konkrét megoldás:
-
-
-
-
-Ellenőrzésre és általános esetre [script](./code/dist.py).
-
-
-
----
-> 3\. A gömbi geometriánk Gauss görbülete $0.8$. Mekkora a $0.2$ sugarú kör kerülete ebben a geometriában?
-
-1. Gauss görbületből a gömb sugara:
-$K = 1/R^2 \Rightarrow R = 1 / \sqrt{K} = 1 / \sqrt{0.8} \approx 1.12$
-2. A kör sugara most a gömbön található egyenesben mérve van megadva. *(a korábbi ábrán ez volt $r$)*
-$r = R * \theta \Rightarrow \theta = 0.2 / 1.12 \approx 0.18$
-3. A kör kerülete pedig:
-$2 \pi R \sin(\theta) = 2 \pi * 1.12 * \sin(0.18) = 1.2499$
-*(ha pontos értékekkel számolunk, ha kerekítve, akkor 1.26 kb)*
-
----
-> 4\. Egy pont koordinátái a t idő alábbi függvényei: x(t) = t*t, y(t) = 1/t mekkora a mozgás sebességének a négyzete 1 sec-ben?
-
-1. A sebesség a mozgás idő szerinti első deriváltja:
-$x'(t) = 2t \qquad y'(t) = -1 / t^2$
-2. Ezt szeretnénk tudni az 1 időpontban:
-$x'(1) = 2 \qquad y'(1) = -1 / 1$
-3. Ebből a sebesség:
-$v = \sqrt{2^2 + (-1)^2} = \sqrt{5}$
-4. Vagyis a sebesség négyzete:
-$\sqrt{5}^2 = 5$
-
----
-> 5\. Asszociatív műveletek:
-> (x * y) * z = x * (y * z)
-
-- Komplex számok szorzata
-- Duális számok szorzata
-- Mátrixok szorzata
-- Vektorok elemenkénti szorzata
-*(ez csak arra ment ki, hogy a vekoriális és a skaláris szorzás ne asszociatív)*
-
----
-> 10\. Kommutatív műveletek:
-> a * b = b * a
-
-- Komplex számok szorzata
-- Duális számok szorzata
-- Vektorok skaláris szorzata
-- Vektorok elemenkénti szorzata
-
----
-> 6\. Mi igaz Euklideszi geometriában
-
-- sinh(3x + 4y + 5) = 0 egy egynes *(valóban az)*
-- 3x + 4y + 5 = 0 egyenesre merőleges a 4x -3y + 5 = 0
-- 3x + 4y + 5 = 0 egyenes megegyezik a -3x -4y - 5 = 0-tel
-- 3x + 4y + 5 = 0 egyenes párhuzamos a 9x 3y + 5 = 0-tel *(ráadásul meg is egyeznek)*
-
----
-> 7\. Milyen műveleti eredmények értelmezhetők Euklideszi geometriában?
-
-- Két pont kombinációja *(ha jól gondolom, ez egy egyenes)*
-- Két vektor kombinációja
-- Két vektor összege
-- Vektor szorzása számmal
-- Pont és vektor összege
-
-*(pont szorzása vektorral és két pont összege pedig nem létező műveletek)*
-
----
-> 8-9\. Mi igaz a geometriákra
-
-| | Gömbi | Hiperbolikus |
-| - | ----- | ------------ |
-| A sík görbülete | Pozitív | Negatív |
-| Egyenes a 2 pont közti legrövidebb út | igaz | igaz |
-| Háromszög szögeinek összege | > 180° | < 180° |
-| A pitagorasz tétel | nem igaz | nem igaz |
-| Egyéb | Két különböző egyenes 2 pontban metszi egymást | 1 egyenesre 1-nél több nem metsző egyenes van |
-
-[Következő](2.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/10.md b/docs/notes/sem4/computer_graphics/10.md
deleted file mode 100644
index 15f2d70..0000000
--- a/docs/notes/sem4/computer_graphics/10.md
+++ /dev/null
@@ -1,583 +0,0 @@
-
-
-# Játékfejlesztés
-
-## Játékok feladatai
-- képszintézis az avatár nézőpontjából
-- avatár vezérlése valamilyen beviteli eszközzel *(akár többel)*
-- intelligens objektumok *(ai/állapotgép)*
-- játéklogika
-- a fizika világ szimulációja (Newtoni fizika)
-
-> Ezek szinte minden játéknak részei, ezért ezeket előre elkészíthetjük általános formában, egy keretrendszer *(ún. game engine)* formájában.
-> A gameenginenek hála nekünk elég csak a játék konkrétumait, műkődését és kinézetét beállítani, leprogramozni.
-
-## Osztálydiagram
-
-
-
-## GameObject
-```cpp
-class GameObject
-{
-protected:
- Shader *shader;
- Material *material;
- Texture *texture;
- Geometry *geometry;
- vec3 pos, velocity, acceleration;
- vector children;
- virtual void ModelingTransform(mat4 &M, mat4 &Minv) { M = Minv = UnitMatrix(); }
-
-public:
- GameObject(Shader *s, Material *m, Texture *t, Geometry *g) { … }
- virtual void Control(float dt) {}
- virtual void Animate(float dt) {}
- virtual void Draw(RenderState state)
- { // parameter by value to separate objects
- mat4 M, Minv;
- ModelingTransform(M, Minv);
- state.M = M * state.M;
- state.Minv = state.Minv * Minv;
- state.material = material;
- state.texture = texture;
- shader->Bind(state); // uniform variable setting
- geometry->Draw(); // triangles go down the pipeline
- for (Object *child : children)
- child->Draw(state);
- }
-};
-```
-> Unitysek előnyben! Nade mi is történik itt?
-
-A játékunk érzékelhető része `GameObject`ekből áll, minden *(majdnem)*, amit megjelenítünk egy `GameObject` (vagy annak leszármazottja). Ezek tárolás egy fa struktúrát követ, a gyökere a `Scene`, az összes többi csúcsban `GameObject`ek vannak, és ők is tartalmazhatnak más `GameObject`eket (`children`).
-
-Egy `Gameobject` tudja magáról a megjelenítéséhez szükséges tulajdonságait és alakját. Kirajzoláskor ezeket beállítja a `RenderState`be, (**mert az ópengéel egy álalpotgép**) mielőtt meghívná a `geomteri`ájára a kirajzolást. Fontos megemlíteni hogy az `M` transzformációs mátrixot (és inverzét) nem felülírja, hanem megszorozza az eddigi állapotot. Ez azért van így, mert a `GameObject`ek `child`jainak helyzetét a `parent`hez relatívan értelmezzük.
-
-> Pl. Sceneből indul (0, 0, 0) origó középpontból, a karakterünket direktben tartalmazza, koordinátája egyenlő lesz a világbeli koordinátáival, mondjuk (1, 1, 1). A karakter egyik child objektuma a kalapja, ennek koordinátái a (0, 0, 2), relatíven értelmezzük, tehát a karakterünk origójától lesz ilyen távolságban. Ha az ezekhez tartozó mátrixokat egymás után összeszorozzuk, kapjuk meg a child GameObjectek tényleges világbeli pozícióját, itt ez most (1, 1, 3) lenne.
-
-
-## Szimulációs hurok (Game loop)
-
-```cpp
-void onIdle()
-{ // idle call back
- static float tend = 0;
- float tstart = tend;
- tend = glutGet(GLUT_ELAPSED_TIME);
- scene.Simulate(tstart, tend, keys);
- glutPostRedisplay();
-}
-```
-> Azaz amikor a programunk épp nem renderel, megmérjük az előző `Simulate` (Unityben update) óra eltelt időt, majd meghívjuk a függvényt.
-
-```cpp
-void Scene::Simulate(float ts, float te, bool keys[])
-{
- avatar->ProcInput(keys);
- for (float t = ts; t < te; t += dt)
- {
- float Dt = fmin(dt, te - t);
- for (GameObject *o : objects)
- o->Control(Dt);
- for (GameObject *o : objects)
- o->Animate(Dt);
- }
-}
-```
-> Mi itt a `Dt`? Ez az ún. delta time, ami méri két kirajzolt képkocka = két szimulációs "update tick" közti időt.
-> Ha az eltelt idő (`te-ts`) nagyon nagy, az szimulációs anomáliákhoz (pl. hibás ütközés) vezethet, ezért bevezetünk egy maximum delta time változót (`dt`). Ha `te-ts` túllépné ezt ezt a maximumot, akkor ezt az időegységet a biztonság kedvéért kisebb szeletekre bontjuk, kis lépésekben szimuláljuk le.
-
-
-```cpp
-void onDisplay()
-{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- scene.Render();
- glutSwapBuffers();
-}
-```
-> A szimulálás után pedig kirendereljük a jelenlegi állapotot.
-
-
-```cpp
-void Scene::Render()
-{
- RenderState state; // M=Minv=UnitMatrix();
- avatar->SetCameraTransform(state);
- for (GameObject *o : objects)
- o->Draw(state);
-}
-```
-> Figyeljük meg, hogy új `RenderState`t hozunk létre, `M` és `Minv` az egységmátrix lesznek, azaz nem nyújtunk, nem forgatunk, nem méretezünk.
-
-## Volumetric shader
-> Semelyik jegyzetben, sem a videóiban nem találtam hozzá magyarázatot. Freestyle.
-
-Kiterjedt de nem egyértelműen meghatározható geometriájú térfogatok (volume, hence the name volumetric shader), pl. köd, füst stb. megjelenítésére használjuk. Ezek többnyire minden irányból ugyan úgy néznek ki.
-
-
-Vertex shader:
-```c
-uniform mat4 MVP;
-layout(location = 0) in vec2 vtxPos;
-out vec2 uv;
-void main()
-{
- gl_Position = vec4(vtxPos, 0, 1) * MVP;
- uv = (vtxPos + vec2(1, 1)) / 2;
-}
-```
-Fragment shader:
-```c
-uniform sampler2D textureMap;
-uniform vec4 color;
-in vec2 uv;
-out vec4 fragColor;
-void main()
-{
- fragColor = texture(textureMap, uv) * color;
-}
-```
-
-Implementáció:
-```cpp
-class VolumetricShader : public GPUProgram
-{
-public:
- void Bind(RenderState state)
- {
- Use(); // make this program run
- setUniform(state.MVP, "MVP");
- setUniform(state.color, "color");
- setUniform(*state.texture, "textureMap");
- }
-};
-```
-
-## Avatar
-> A mi szemszögünk
-
-```cpp
-struct Avatar : public GameObject
-{
- virtual void ProcessInput() {}
- virtual vec3 wVup() { return vec3(0, 1, 0); }
- void SetCameraTransform(RenderState &state)
- {
- Camera camera(pos, pos + velocity, wVup()); // a gyorsulás irányába nézünk
- state.V() = camera.V();
- state.P() = camera.P();
- }
-};
-```
-`wVup = [0, 1, 0]` vagy a gyorsulásból és a korábbi wVup átlagából kapjuk meg.
-
-## Keyboard polling
-```cpp
-bool keys[256]; // is pressed?
-void onKeyboard(unsigned char key, int pX, int pY)
-{
- keys[key] = true;
-}
-void onKeyboardUp(unsigned char key, int pX, int pY)
-{
- keys[key] = false;
-}
-```
-Egy tömbben tároljuk, hogy éppen mi a billentyűk állása, a fenti két eseményben állítjuk. `Simulate` közben ebből a tömbből polloljuk az állását.
-
-## Euler karakterisztika invariáns
-
-$\text{csúcs} - \text{él} + \text{lap} = \chi$
-
-$\chi$ a felület topológiájától függ.
-
-## Frenet keret
-> transzformációval érjük el, hogy a nézőpont/geometria kijelölt "feje" a sebesség irányába nézzen.
-
-
-
-
-$M =
-\begin{bmatrix}
-i' & 0 \\
-j' & 0 \\
-k' & 0 \\
-r & 1 \\
-\end{bmatrix}
-$
-
-Először kiszámoljuk a **nem ortonormál** formájában:
-
-*(ortonormál = vektorok mertőlegesek egymásra és egység hosszúak)*
-
-$j^* = v$
-
-$k^* = k'(1-\alpha) + a \cdot \alpha$
-
-$i^* = j' \times k^*$
-
-> $k'$? $\alpha$? Hogy? Mi?
-
-> $k'$: az előző ortonormalizált $k'$
-
-> $\alpha$: súlyozási tényező, lehetővé teszi hogy az új és az előző $k'$ előző között egy sima átmenetet biztosítsunk, és véde az $a = 0$ eset ellen is.
-
-Majd **ortogonalizáljuk**:
-
-$j' = \^{j^*}\qquad\qquad$ (normalizáljuk)
-
-$i' = \cfrac{j' \times k^* }{|j' \times k^*|}\quad~~$ (ezt is, csak nem tudom ugyan úgy jelölni)
-
-$k' = i' \times j'\qquad~$ (ezt már nem kell, hiszen két normalizált vektort keresztszoroztunk)
-
-Esélyes hogy $a$ és $v$ nincs megadva. $r$ első deriváltja $v$, második deriváltja $a$.
-
-> Ez kicsit leegyszerűsítve, $\alpha = 1$ esetben a következő:
-
-> $j' = \^v$
-
-> $i' = \^v \times \^a$
-
-> $k' = \^v \times \^a \times \^v$
-
-#### Ütközések
-```cpp
-dist = length(obj1.pos - obj2.pos)
-minDist = obj1.BoundingRadius() + obj2.BoundingRadius()
-if (dist < minDist)
- // collision
-```
-> Ez egy nagyon lebutított példa, ütközés szempontjából mindent gömbként kezelünk, és a távolságuk alapján döntjük el, hogy összeérnek-e. Ütközésről külön diplomát lehetne írni szóval a bácsi sem ment bele, és bármennyire is szeretném, nekem sincs időm rá.
-
-Probléma:
-
-
-
-Ha az objektum gyors, a delta time nagy, átmehetünk objektumokon anélkül, hogy ütköznénk (diszkrét eset).
-
-Megoldás:
-Folytonos ütközésdetektálás. Egy sugarat bocsátunk a mozgatás irányában, megnézzük hogy beleütközik-e valamibe.
-
-
-
-A koordinátákat az vizsgált objektumhoz rögzítjük.
-
-
-```cpp
-rel_pos = position - pos2
-rel_velocity = velocity - vel2
-Ray: rel_pos + rel_velocity * t
-
-if (ray intersects bounding sphere first && tintersect < dt)
- //collision
-```
-*(Bár még mindig nem tökéletes, a mozgatott objektumnak nem vesszük figyelembe a kiterjedését.)*
-
-#### Billboard
-> Mindig a kamera felé néző téglalap. Gyors!
-
-```cpp
-vec3 w = wEye - pos; // szem felé mutat
-vec3 r = cross(up, w); // billboard vízszintes (jobb)
-vec3 u = cross(r, w); // billboard függőleges (fel)
-r = normalize(r) * size; // normalizáljuk és beállítjuk a méretet
-u = normalize(u) * size;
-```
-
-Tehát a transzformációs mátrixa:
-
-$$ \bold{T} =
-\begin{bmatrix}
-r_x & r_y & r_z & 0 \newline
-u_x & u_y & u_z & 0 \newline
-0 & 0 & 1 & 0 \newline
-pos_x & pos_y & pos_z & 1
-\end{bmatrix}
-$$
-
-#### Részecskerendszer (particlesystem)
-> ez amúgy egy jó dolog de nem mennék részletekbe, mert aki tudja tudja és valszeg nem lesz a vizsgán
-
-> egy rakás billboard, de egyben kezeljük
-
-Példának vegyünk porszemcséket, amit a szél fúj. Ezt a szelet tekintsük egy erőtérnek.
-
-```
-pos: pos += velocity * dt
-velocity: velocity += acceleration * dt
-acceleration: acceleration = force / weight
-lifetime: random kezdeti érték
-age: age += dt; if (age > lifetime) Kill();
-size, dsize: size += dsize * dt;
-weight, dweight: weight += dweight * dt
-color, dcolor: color += dcolor * dt
-```
-
-### Kvíz
-
-> 1\. A virtuális világban egy pontszerű test és egy gömb mozog. A pontszerű test a szimulációs időlépés kezdetén a (1,2,5) pontban van (mértékegység parsec) és (3,5,2) parsec/sec sebességgel halad. A gömb középpontja a szimulációs időlépés kezdetén a (2,3,7) pontban van és (9,6,2) parsec/sec sebességgel halad. Mekkora az a minimális gömbsugár, amely felett a két objektum a dt=100 msec időlépésben az intervallum elején tesztelő diszkrét ütközésdetektálási algoritmus szerint ütközik?
-
-*Megoldás:*
-Váltsuk át a pontszerű test koordiniátáit a gömbhöz relatíven.
-
-$p_r = p_p - p_g = (1, 2, 5) - (2, 3, 7) = (-1, -1 -2)$
-
-$v_r = v_p - v_g = (3, 5, 2) - (9, 6, 2) = (-6, -1, 0)$
-
-Vegyük észre, hohgy a pont egyre csak méginkább távolodni fog a gömbtől, ha ütközést szeretnénk detektálni azt mihamarabb.
-
-> időlépés intervallum **elején** tesztelő, **diszkrét**
-
-Magyarán az első teszt $t = 0 \cdot dt$ időben fut le.
-
-Ekkor a távolságuk $|p_r| = \sqrt{6} \approx 2.45$
-
----
-> 2\. Egy test 3 darab különálló poliéder részből áll, és egyik rész sem tartalmaz lyukat. A testen összesen 10 csúcsot és 18 lapot számoltunk meg. Hány éle van?
-
-*Megoldás:*
-
-Euler karakterisztika invariánst felhasználva:
-
-$\text{csúcs} - \text{él} + \text{lap} = \chi$
-
-poliéderek esetén $\chi = 2$, nekünk $3$ poliéderünk van tehát $\chi = 2 \cdot 3 = 6$
-
-Behelyettesítve ez
-
-$6 = 10 - \text{él} + 18$
-
-$\text{él} = 22$
-
----
-> 5\. Egy billboard (plakát) referencia helyzetében az origóban van és az xy síkra fekszik. Adjuk meg a modellezési transzformáció elemeit egy értékes jegyre, ha a
-
-> - a billboard mérete nem változik a transzformáció során
-> - a szem a világ (4,2,7) pontjában van
-> - a billboard által reprezentált objektum a (1,2,3) pontban van
-> - a billboard preferált függőleges iránya a (0,1,0)
-
-*Megoldás:*
-
-```
-vec3 w = wEye - pos; // szem felé mutat
-vec3 r = cross(w, up); // billboard vízszintes (jobb)
-vec3 u = cross(r, w); // billboard függőleges (fel)
-r = normalize(r) * size; // normalizáljuk és beállítjuk a méretet
-u = normalize(u) * size;
-```
-
-Kiszámoljuk $w, r, u$ értékeket:
-
-$w = \text{eye} - \text{pos} = (3, 0, 4)$
-
-$r = \text{up} \times w = (4, 0, -3) \rightarrow \^{r} = (-0.8, 0, 0.6)$ *(normalizáljuk)*
-
-$u = r \times w = (0, 25, 0) \rightarrow \^{u} = (0, 1, 0)$ *(ezt is)*
-
-Behelyettesítünk:
-
-$$
-\begin{bmatrix}
-r_x & r_y & r_z & 0 \newline
-u_x & u_y & u_z & 0 \newline
-0 & 0 & 1 & 0 \newline
-pos_x & pos_y & pos_z & 1
-\end{bmatrix} =
-\begin{bmatrix}
-0.8 & 0 & -0.6 & 0 \newline
-0 & 1 & 0 & 0 \newline
-0 & 0 & 1 & 0 \newline
-1 & 2 & 3 & 1
-\end{bmatrix}
-$$
-
----
-> 6\. Egy FPS játékban az avatár pillanatnyi pozíciója (0, 0, 0), sebessége (6, 8, 0), gyorsulása (12, -9, 0). A kamera orientációt a Frenet kerettel állítjuk be. Mi lesz a kamera View transzformációja?
-
-*Megoldás:*
-Nincs mese, ki kell számolni.
-
-$r = (0, 0, 0)$
-
-$j' = \^v = (0.6, 0.8, 0)$
-
-$i' = \^v \times \^a = (0.6, 0.8, 0) \times (0.8, -0.6, 0) = (0,0,-1)$
-
-$k' = i' \times j' = (0.8, -0.6, 0)$
-
-Tehát a mátrixunk nem más, mint
-
-$$M =
-\begin{bmatrix}
-i' & 0 \newline
-j' & 0 \newline
-k' & 0 \newline
-r & 1 \newline
-\end{bmatrix}=
-\begin{bmatrix}
-0 & 0 & -1 & 0 \newline
-0.6 & 0.8 & 0 & 0 \newline
-0.8 & -0.6 & 0 & 0 \newline
-0 & 0 & 0 & 1
-\end{bmatrix}
-$$
-
-Majd aztán eltöltesz 2 órát azzal, hogy miért nem ez a megoldás. Ez kérlek egy transzformációs mátrix, nem a kamera View transzformációja. Tehát a helyes mátrix :salt::
-
-$$
-\bold{T}_V =
-\begin{bmatrix}
-1 & 0 & 0 & 0\newline
-0 & 1 & 0 & 0\newline
-0 & 0 & 1 & 0\newline
--e_x & -e_y & -e_z & 1\newline
-\end{bmatrix}
-\begin{bmatrix}
-u_x & u_y & u_z & 0\newline
-v_x & v_y & v_z & 0\newline
-w_x & w_y & w_z & 0\newline
-0 & 0 & 0 & 1\newline
-\end{bmatrix}^{-1}
-$$
-
-Ahol
-
-$e = r$
-
-$u = i$
-
-$v = k$
-
-$w = -j$ *(ügye nem felejtettük el, hogy a view $-z$ irányba néz, és azt szeretnénk, hogy a irányába nézzünk)*
-
-Megfeleltetés után, és annak tudatában, hogy a második mátrix ortonormál (tehát inverze önmaga transzponáltja)
-
-$$
-\begin{bmatrix}
-1 & 0 & 0 & 0\\
-0 & 1 & 0 & 0\\
-0 & 0 & 1 & 0\\
-0 & 0 & 0& 1\\
-\end{bmatrix}
-\begin{bmatrix}
-0 & 0 & -1 & 0 \\
-0.8 & -0.6 & 0 & 0 \\
--0.6 & -0.8 & 0 & 0 \\
-0 & 0 & 0 & 1
-\end{bmatrix}^{-1}=
-\begin{bmatrix}
-0 & 0.8 & -0.6 & 0 \\
-0 & -0.6 & -0.8 & 0 \\
--1 & 0 & 0 & 0 \\
-0 & 0 & 0 & 1 \\
-\end{bmatrix}
-$$
-
-
-
----
-> 7\. Egy játékobjektum orr iránya referencia helyzetben az y tengely, függőleges iránya pedig a z tengely. Az objektum pályája $r(t)=(\cos(t), \sin(t), t)$.
-Adjuk meg a modellezési transzformáció elemeit egy értékes jegyre a $t=\pi/4$-re, ha az objektumot Frenet keret módszerrel animáljuk.
-
-*Megoldás:*
-
-$r(t)=(\cos(t), \sin(t), t)$
-
-$v(t) = \.r(t)=(-\sin(t), \cos(t), 1)$
-
-$a(t) = \"r(t)=(-\cos(t), -\sin(t), 0)$
-
-Ezek a $t=\frac\pi 4$ helyen:
-
-$r(\frac\pi 4) = (\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, \frac\pi 4)$
-
-$v(\frac\pi 4) = (-\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, 1)$
-
-$a(\frac\pi 4) = (-\frac{\sqrt{2}} 2, -\frac{\sqrt{2}} 2, 0)$
-
-És akkor számolunk...
-
-$r = (\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, \frac\pi 4)$
-
-$j' = \^v = (-\frac 1 2, \frac 1 2, \frac{\sqrt{2}} 2)$
-
-$i' = \^v \times \^a = (\frac 1 2, -\frac 1 2, \frac{\sqrt{2}} 2) $
-
-$k' = i' \times j' = (-\frac{\sqrt{2}} 2, -\frac{\sqrt{2}} 2, 0)$
-
-
-Tehát a mátrixunk nem más, mint
-
-$$M =
-\begin{bmatrix}
-i' & 0 \\
-j' & 0 \\
-k' & 0 \\
-r & 1 \\
-\end{bmatrix}=
-\begin{bmatrix}
-\frac1 2 & -\frac 1 2 & \frac{\sqrt{2}} 2 & 0 \\
--\frac1 2 & \frac 1 2 & \frac{\sqrt{2}} 2 & 0 \\
--\frac{\sqrt{2}} 2 & -\frac{\sqrt{2}} 2 & 0 & 0 \\
-\frac{\sqrt{2}} 2 & \frac{\sqrt{2}} 2 & \frac\pi 4 & 1
-\end{bmatrix}=
-\begin{bmatrix}
-0.5 & -0.5 & 0.7 & 0 \\
--0.5 & 0.5 & 0.7 & 0 \\
--0.7 & -0.7 & 0 & 0 \\
-0.7 & 0.7 & 0.8 & 1
-\end{bmatrix}
-$$
-
----
-> 9\. Az alábbi programsorok egy szimulációs hurkot (game loop) valósítanak meg, de nem jól működik. Válassza ki a hibás sorokat:
-```cpp
-void onIdle ( ) { // idle call back
-1) float tend = 0;
-2) float tstart = tend;
-3) tend = glutGet(GLUT_ELAPSED_TIME)/1000;
-4) avatar->ProcessInput( );
-5) for(float t = tstart; t < tend; t += dt)
- {
-6) float Dt = min(dt, tend - t);
-7) for (GameObject * obj : objects) obj->Control(dt);
-8) for (GameObject * obj : objects) obj->Animate(dt);
- }
-9) onDisplay();
-}
-```
-
-*Hibás sorok:*
-
-- 1: `tend` vagy `static`, vagy a függvényen kívül kell léteznie, nem nullázhatjuk mindig
-- 3: nem kell leosztanunk milisecundumra
-- 8-9: először animálunk, utána irányítunk
-
----
-> Mely problémák megoldásánál használnak Gram-Schmidt ortogonalizációt?
-
-*Megoldás:*
-
-- [x] Billboard (plakát)
-- [x] Frenet keret
-- [x] 3D kamera transzformáció
-- [ ] Fizikai animáció
-- [ ] 2D kamera transzformáció
-
----
-> 10\. Egy kockát két szinten Catmull-Clark algoritmussal felosztunk. Hány háromszög keletkezik?
-
-*Megoldás:*
-
-Catmull-Clark algoritmusnál $1$ négyszögből csinálunk $4$-et. Ezt kétszer is megcsináljuk:
-
-$6 \cdot 4 \cdot 4 = 96$ négyszög, ami kétszer ennyi, azaz $192$ háromszög
-
-
-
-[Előző](./9.md)
-
-[Következő](./11.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/11.md b/docs/notes/sem4/computer_graphics/11.md
deleted file mode 100644
index ab80fb3..0000000
--- a/docs/notes/sem4/computer_graphics/11.md
+++ /dev/null
@@ -1,438 +0,0 @@
-
-
-# Vektorháború
-
-## 2D geometria = vektor algebra
-- koordinátákkal számolható, de szerkeszthető is (tenzor)
-- pont: $p = [x, y, 1]$
-- vektor: $v = [x, y, 0]$
-- eltolás: $p' = p + v$ *(Invertálható, van kivonás)*
-- eltolás, forgatás, skálázás:
- $[x', y', 1] = [x, y, 1] \begin{bmatrix}
- a & e & 0\\
- b & f & 0\\
- c & d & 0\\
- \end{bmatrix}$
-
-- nincs rendes szorzás
- - skaláris szorzás *(dot product)*
- - $v \cdot a = b \stackrel{def}{\implies} |v||a|\cos\alpha = b$
- - az eredmény egy skalár ($v$-nek $a$-ra vett vetületének hossza)
- - nem asszociatív
- - kommutatív (szimmetrikus)
- - disztibutív
- - nem invertálható
-
- - vektorális szorzás *(cross product)*
- - $v \times a = b \stackrel{def}{\implies} |v||a|\sin\alpha = |b|$ *(és $b$ merőleges mindkét vektorra + jobbkézszabály)*
- - csak 3D-ben 2 változós!
- - nem asszociatív
- - antikommutatív (ellentétes előjel)
- - disztributív
- - nem invertálható
-
- - külső szorzat (wedge product)
- - $v_1 \wedge v_2$
- - >ugyan úgy számolod ki, mint a kersztszorzást, de nem ugyan azt jelenti, nem használható ugyan úgy
- - def.: $|v_1 \wedge v_2| = |v_1| |v_2| \sin \alpha$
- - jelentése: irányított terület/térfogat
- 
- itt $B$ egy multivektor (azon belül is egy bivektor?)
- - asszociatív
- - antikommutatív
- - disztributív
-
-### Multivektor
-- $V = s + v + B$
-*(térfogat = skalár + vektor + bivektor, de ez csak egy példa, hogy miből állhat egy multivektor)*
-- műveletek bivektorokkal
- - skalárral szorzás: triviális
- - összeadás: 
- komponensenként adjuk össze
-
- - belső szorzás (skaláris): 
- $= s_1 \cdot s_2 + v_1 \cdot v_2$
-
-
-## 2D geometria = komplex szám
-- pont: $z_p = x_p + iy_p = Re^{i\alpha} = R \cos\alpha + iR \sin\alpha$
-- eltolás $z_t = x_t + iy_p$-vel:
-
- $$\boxed{ {z_p}' = z_p + z_t}$$
-
-- irányfüggetlen skálázás $z_s = s$-sel
-
- $$\boxed{ {z_p}' = z_p \cdot z_s}$$
-
-- forgatva nyújtás $z_r = x_r + iy_r = se^{i\varphi}$-vel
-
- $$\boxed{ {z_p}' = z_p \cdot z_r = Rs \cdot e^{i(\varphi + \alpha)}}$$
-
-- forgatás = előző, csak egység abszolút értékű komplex számmal ($s = 1$)
-
-
-## Geometria 3D-ben
-- eltolás (összeadás) és skálázás (skalárral szorzás) tetszőleges dimenzióban általánosítható
-- forgatás: lineáris művelet, tehát kell legyen egy $r' = R(r)$-hez tartozó mátrix
-
-$x'i + y'j + z'k = R(x + y + z) = xR(i) + yR(j) + zR(k)$
-
-$[x', y', z'] = [x, y, z]
-\begin{bmatrix}
-R(i)_x & R(i)_y & R(i)_z \newline
-R(j)_x & R(j)_y & R(j)_z \newline
-R(k)_x & R(k)_y & R(k)_z \newline
-\end{bmatrix}
-$
-
-## Rodrigues formula
-Origón átmenő $d$ tengely körüli forgatás.
-
-
-Magyarázat:
-
-- $d$ (zöld): forgatási tengely
-- $r$ (piros): forgatni kívánt vektor
-- $r_\parallel = r'_\parallel = d(r \cdot d)$ (barna): $d$-vel párhuzamos komponense $r$ és $r'$-nek (egyenlők)
-- $r_\perp = r - d(r \cdot d)$ (sötétkék): $r-r_\parallel$, azaz $r$-ből kivonjuk a párhuzamos komponenst, ami marad az már biztosan merőleges
-- $r_{\perp\perp} = d \times r_\perp = d \times r$ (világoskék): $d$-re és $r_{(\perp)}$-re merőleges
-
-- $r' = r'_\parallel + r'_\perp$ (lila): $r$ elforgatva, a párhuzamos és merőleges komponensek összege
-
- A merőleges komponenst pedig $r_\perp$, $r_{\perp\perp}$ és szögfüggvények segítségével az alábbi módon kaphatjuk meg:
-
-- $r'_\perp = r_\perp \cos\varphi + r_{\perp\perp} \sin\varphi$
-
-
-## Komplex számok 3D-ben
-- $z = x + yi + zj$ *(tippre ez 2 különböző $z$)*
-- összeadásnál és skálázásnál beláttuk, hogy dimenziófüggetlen
-- forgatás mint szorzás?
- - asszociatív, összeadásra disztributív
- - nem kommutatív: 
- *(más sorrendben forgatunk $\rightarrow$ más eredmény)*
- - invertálható
-
-## Hamilton: kvaternió (4D komplex szám)
-- $q = [s, x, y, z] = [s, d] = s + xi + yj + zk$
-- összeadás:
- $q_1 + q_2 = [s_1 + s_2, x_1 + x_2, y_1 + y_2, z_1 + z_2]$
-- skalárral szorzás:
- $aq = qa = [as, ax, ay, az]$
-- abszolút érték
- $|q| = \sqrt{s^2 + x^2 + y^2 + z^2}$
-
-- **szorzás** (fr this time):
-
- $\boxed{[s_1, d_1]\cdot[s_2, d_2] = [s_1s_2 - d_1 \cdot d_2, s_1 \cdot d_2 + s_2 \cdot d_1 + d_1 \times d_2]}$
-
- $\boxed{i^2 = j^2 = k^2 = ijk = -1}$
-
- $ij = k, ~~ ji = -k$
-
- $jk = i, ~~ kj = -i$
-
- $ki = j, ~~ ik = -j$
-
- - asszociatív
- - nem kommutatív
- - összeadásra disztributív
-
-- van egységelem: $[1, 0, 0, 0]$
-- van **inverz**: $q^{-1} = [s, -d]/|q|^2, q^{-1} \cdot q = q \cdot q^{-1} = [1, 0, 0, 0]$
-
-- **forgatás** origón átmenő $d$ tengely körül:
- - $q = [\cos(\alpha/2), d \sin(\alpha/2)]$, $d$ pedig normalizált azaz $|d| = 1$
- - $q \cdot [0, u] \cdot q^{-1} = [0, v]$, $v$ az $u$ elforgatottja a $d$ körül $\alpha$-val
- > - kvaterniót csak kvaternióval tudunk szorozni, tehát a valós részt 0-nak vesszük és mellé rakjuk $u$-t
- > - kétszer is szorzunk, ezért használunk csak $\alpha/2$-t
- - [egy nagyon jó interaktív videó a kvaterniókról, ami segít elképzelni (3b1b)](https://eater.net/quaternions/video/intro)
-
-## Implementáció
-```cpp
-struct vec4
-{
- float x, y, z, w; // w = s, ijk = xyz megefeleltetés!
- ...
-};
-vec4 qmul(vec4 q1, vec4 q2)
-{ // kvaternió szorzás
- vec3 d1(q1.x, q1.y, q1.z), d2(q2.x, q2.y, q2.z);
- return vec4(d2 * q1.w + d1 * q2.w + cross(d1, d2),
- q1.w * q2.w - dot(d1, d2));
-}
-vec4 quaternion(float ang, vec3 axis)
-{ // konstruálás
- vec3 d = normalize(axis) * sinf(ang / 2);
- return vec4(d.x, d.y, d.z, cosf(ang / 2));
-}
-vec3 Rotate(vec3 u, vec4 q)
-{
- vec4 qinv(-q.x, -q.y, -q.z, q.w); // conjugate
- vec4 qr = qmul(qmul(q, vec4(u.x, u.y, u.z, 0)), qinv);
- return vec3(qr.x, qr.y, qr.z);
-}
-```
-
-### GPU shaderprogram
-```c
-uniform vec4 q; // quaternion as uniform variable
-in vec3 u; // Varying input: vertex
-vec4 qmul(vec4 q1, vec4 q2)
-{
- vec3 d1 = q1.xyz, d2 = q2.xyz;
- return vec4(d2 * q1.w + d1 * q2.w + cross(d1, d2),
- q1.w * q2.w - dot(d1, d2));
-}
-void main()
-{ // vertex shader program
- vec4 qinv = vec4(-q.xyz, q.w); // conjugate
- vec3 v = qmul(qmul(q, vec4(u, 0)), qinv).xyz;
- gl_Position = vec4(v, 1);
-}
-```
-
-# Automatikus deriválás
-
-## Hogyan **NE**
-$f'(x) = \cfrac{f(x + \Delta) - f(x)}{\Delta}$
-
-Bajok:
-
-- kivonás miatt értékes jegyeket veszítünk
-- túl kicsi $\Delta \rightarrow$ zajos
-- túl nagy $\Delta \rightarrow$ pontatlan
-
-## Clifford algebra
-> azért mi mégis csak szeretnénk c++-ban valahogy deriválni
-
-### Hiperszám
-$z = x + iy$, ahol
-
-- $i^2 = -1$: komplex szám
-- $i^2 = 1$: hiperbolikus szám
-- $i^2 = 0$: **duális** szám
-
-### Duális számok ($i^2 = 0$)
-- összeadás, kivonás:
-
- $(x_1 + y_1i) \pm (x_2+y_2i) = (x_1 \pm x_2) + (y_1 \pm y_2)i$
-
-- szorzás:
-
- $(x_1+y_1i) \cdot (x_2+y_2i) = (x_1x_2) + (x_1y_2+y_1x_2)i +\xcancel{(y_1y_2)i^2}$
-
-- hányados:
-
- $
- \cfrac{x_1 + y_1i}{x_2 + y_2i} =
- \cfrac{(x_1 + y_1i)(x_2 - y_2i)}{(x_2 + y_2i)(x_2 - y_2i)}=
- \cfrac{x_1x_2 + (y_1x_2x_1y_2)i \xcancel{(y_1y_2)i^2}}{x^2_2 - \xcancel{y^2_2i^2}} =
- \cfrac{x_1}{x_2} + \cfrac{y_1x_2-x_1y_2}{x^2_2}i
- $
-
-Ezek valós tagja a függvény, az imaginárius rész ($\cdot i$) pedig a derviált
-
-### Implementáció
-Duális szám osztály
-```cpp
-struct Dnum
-{
- float f, d; // function and derivative values
- Dnum(float f0, float d0 = 0)
- { // constant’ = 0
- f = f0, d = d0;
- }
- Dnum operator+(Dnum r) { return Dnum(f + r.f, d + r.d); }
- Dnum operator-(Dnum r) { return Dnum(f - r.f, d - r.d); }
- Dnum operator*(Dnum r) { return Dnum(f * r.f, f * r.d + d * r.f); }
- Dnum operator/(Dnum r) { return Dnum(f / r.f, (d * r.f - f * r.d) / r.f / r.f); }
-};
-```
-
-Alkalmazása
-```cpp
-// diuális számok nélkül, alapból
-float t = value;
-float F = t * a / (t * t + b);
-
-
-// deriválással együtt
-Dnum F = Dnum(t,1) * Dnum(a,0) / (Dnum(t,1) * Dnum(t,1) + Dnum(b,0));
-
-// szebben
-Dnum t(value, 1);
-Dnum F = t * a / (t * t + b);
-```
-
-Elemi függvények
-```cpp
-struct Dnum
-{
- float f, d; // function and derivative values
- Dnum(float f0, float d0 = 0) { f = f0, d = d0; }
- ...
-};
-
-Dnum Sin(float t) { return Dnum(sinf(t), cosf(t)); }
-Dnum Cos(float t) { return Dnum(cosf(t), -sinf(t)); }
-...
-```
-
-Összetett függvényekre
-*(pl. egymásba ágyazott)*
-```cpp
-struct Dnum
-{
- float f, d; // function and derivative values
- Dnum(float f0, float d0 = 0) { f = f0, d = d0; }
- ...
-};
-
-Dnum Sin(Dnum g) { return Dnum(sinf(g.f), cosf(g.f) * g.d); }
-Dnum Cos(Dnum g) { return Dnum(cosf(g.f), -sinf(g.f) * g.d); }
-Dnum Tan(Dnum g) { return Sin(g)/Cos(g); }
-Dnum Log(Dnum g) { return Dnum(logf(g.f), 1/g.f * g.d); }
-Dnum Exp(Dnum g) { return Dnum(expf(g.f), expf(g.f) * g.d); }
-Dnum Pow(Dnum g, float n) { return Dnum(powf(g.f, n), n * powf(g.f, n - 1) * g.d); }
-```
-
-Többváltozós függvényeknél
-```cpp
-template
-struct Dnum
-{
- float f; // function value
- T d; // derivatives
- Dnum(float f0, T d0 = T(0)) { f = f0, d = d0; }
- Dnum operator+(Dnum r) { return Dnum(f + r.f, d + r.d); }
- Dnum operator*(Dnum r) { return Dnum(f * r.f, f * r.d + d * r.f); }
- Dnum operator/(Dnum r) { return Dnum(f / r.f, (d * r.f - f * r.d) / r.f / r.f); }
-};
-template
-Dnum Exp(Dnum g)
-{
- return Dnum(expf(g.f), expf(g.f) * g.d);
-}
-
-```
-Gradiensre példa
-```cpp
-float x, y, z;
-Dnum X(x,vec3(1,0,0)), Y(y,vec3(0,1,0)), Z(z,vec3(0,0,1));
-Dnum F = X*X/a + Y*Y/b + Z*Z/c – 1;
-vec3 grad = F.d;
-```
-
-Példa:
-
-Egy 2 dimenziós pályán haladunk, és azt szeretnénk, hogy mindig a sebesség irányába nézzünk.
-
-Pálya:
-
-$x(t) = \cfrac{\sin(t)(\sin(t)+3)4}{\tan(\cos(t)+2)}$
-
-$y(t) = \cfrac{(\cos(\sin(t))8+1)12+2}{(sin(t)sin(t))^3+2}$
-
-A sebességvektor, azaz hogy merre nézünk:
-
-$v(t) = (\.x(t), \.y(t))$
-
-Ezt biztos hogy le nem deriválom neked. De nem is kell mert majd ő kiszámolja.
-```cpp
-void Animate(float tt)
-{
- Dnum t(tt, 1);
- Dnum x = Sin(t)*(Sin(t)+3)*4 / (Tan(Cos(t))+2);
- Dnum y = (Cos(Sin(t)*8+1)*12+2)/(Pow(Sin(t)*Sin(t),3)+2);
- vec2 position(x.f, y.f), velocity(x.d, y.d);
- vec2 heading = normalize(velocity);
- Draw(position, heading);
-}
-```
-
-# Kvíz
-Bár elvileg az első vizsgán nem lesz kvaterniószámolás de ez egy nagyon erős elvileg.
-
-> 1\. Mi lesz az alábbi kvaternió szorzás eredményének első képzetes része, azaz az i szorzója?
-
-> $q \cdot u \cdot q^{-1}$
-
-> ha
-
-> $q=[\frac{\sqrt{2}}2, 0, 0, \frac{\sqrt{2}}2] $ és $u=[0, 10, 0, 0]$
-
-*Megoldás:*
-
-Emlékezzünk az alábbi képletekre:
-
-$[s_1, d_1]\cdot[s_2, d_2] = [s_1s_2 - d_1 \cdot d_2, s_1 \cdot d_2 + s_2 \cdot d_1 + d_1 \times d_2]$
-
-$q^{-1} = [s, -d]/|q|^2$
-
-Tehát
-
-$q^{-1} = [\frac{\sqrt{2}}2, 0, 0, - \frac{\sqrt{2}}2]$
-
-$q \cdot u = [0, (5\sqrt2, 0, 0) + (0, 0, 0) + (0, 5\sqrt2, 0)] = [0, 5\sqrt2, 5\sqrt2, 0]$
-
-Még meg kell szorozni $q^{-1}$-zel:
-
-$[0, (0,0,0) + (5, 5, 0) (-5, 5, 0)] = [0, 0, 10, 0]$
-
-Azaz $i = 0$.
-
----
-> 2\. Mi lesz az alábbi kvaternió szorzás eredményének második képzetes része, azaz a j szorzója?
-
-> $q \cdot u \cdot q^{-1}$
-
-> ha
-
-> $q=[\frac{\sqrt{2}}2, 0, 0, \frac{\sqrt{2}}2] $ és $u=[0, 6, 0, 0]$
-
-*Megoldás:*
-
-Hasonlóképpen. Ellenőrzésképp: $j = 6$.
-
----
-> 3\. Adott két kvaternió:
-
-> $q_1=1+2i +2j + 3k$
-
-> $q_2=1+0i +2j + 2k$
-
-> Mi lesz a $q_1 \cdot q_2$ első imaginárius része, azaz az i szorzója?
-
-*Megoldás:*
-
-Átírhatók $[s, d(i , j, k)]$ alakba, onnantól hasonlóképpen számoljuk.
-
-Ellenőrzésképp: $i = 0$.
-
----
-> 4\. Adott két kvaternió:
-
->$q_1=1+5i +3j + 1k$
-
->$q_2=4+4i +0j + 2k$
-
->Mi lesz a $q_1 \cdot q_2$ valós része?
-
-*Megoldás:*
-Hasonlóképpen. Ellenőrzésképp: $s = -18$.
-
----
-> 5\. A 3D forgatás művelet mely tulajdonságokkal rendelkezik az alábbiak közül?
-
-- [x] Van egységelem, azaz olyan forgatás, amely nem áltoztatja meg az alakzatot.
-- [x] Invertálható
-- [x] Az összeadással disztributív
-- [x] Asszociatív
-- [ ] Kommutatív *(nem az, szemléltetésnek a fenti dobókockás kép)*
-
-:3
-
-[Előző](./10.md)
-
-[Következő](./12.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/12.md b/docs/notes/sem4/computer_graphics/12.md
deleted file mode 100644
index a9ce37b..0000000
--- a/docs/notes/sem4/computer_graphics/12.md
+++ /dev/null
@@ -1,407 +0,0 @@
-
-
-# Fraktálok
-
-> Idáig a virtuális (euklideszi, gömbi, hiperbolikus) világunkat "simának" (tökéletes sík, egyenes) tekintettük, ez kicsiben is tökéletesen differenciálható
-
-> A természetben viszont aligha találkozhatunk ilyen ideális görbékkel, felületekkel, testekkel, belenagyítva minden érdes, tökéletlen, nem lineáris, nem differenciálható.
-
-## Koch görbe
-
-
-
-- adott iteráció hossza: $l_n = l_0 \bigg(\cfrac{4}{3}\bigg)^n \to \infin$
-- véges tartományban végtelen hosszú $\Rightarrow \text{Dimenzió} > 1$
-- területe zérus $\Rightarrow \text{Dimenzió} < 2$
-- folytonos
-- sehol sem differenciálható (tüskés, sehol sem sima eléggé)
-- önhasonló = le lehet fedni a saját kicsinyített változatával
-
-## Hausdorff dimenzió önhasonló objektumokra
-- vegyünk egy kiindulási alakzatot
-- erre $r$-szeres kicsinyítést alkalmazunk (mérete $\frac 1 r$-szeres lesz)
-- majd fedjük le a tartományt $N$ db ilyen kicsivel
-- ezt végtelenszer ismételjük
-- ha kész vagyunk, akkor a Hausdorff dimenziója $D$, ahol
-
- $N = 1/r^D \quad \Rightarrow \quad D = \frac{\log{N}}{\log(1/r)}$
-
-- pl. a fenti Koch görbe esetén $1/3$ méretűre kicsinyítettük a kiindulási szakaszt, és $4$-szer fedtük le vele a tartományt, tehát $D = \frac{\log 4}{\log 3} \approx 1.26$
-
-## Nem önhasonló objektumok: vonalzó dimenzió
-
-
-Önhasonló objektumokra
-
-
-$D = \cfrac{\log(\text{Hossz}(l))}{\log(l)} + 1$
-> (tippre $l$ a vonalzó egység hossza, $\text{Hossz}(l)$ a teljes hossz azaz $l \cdot db$)
-
-Alkalmazása: természetes objektumok elkülönítése és kategorizálása
-
-
-## Lindenmayer rendszerek
-> hogyan állítjuk elő ezeket?
-
-
-Odaképzeljük az elejére a comlogós teknőcöt, és készítünk egy előre (`F`) függvényt, ami rekurzívan hívja meg saját magát, majd fordulgat stb.
-> nyilván valami mélységet beállítasz neki, mert a matematikai végtelen valóságos stackoverflowhoz tud vezetni :innocent:
-
-
-
-
-## Fraktális zaj
-
-
-
-- perturbációk generálása véletlenszerűen
-- ezek szórását a finomabb szintek felé csökkentsük
-- gyyorsan csökken $\Rightarrow$ sima görbe
-- lassan csökken $\Rightarrow$ rücskösebb görbe
-
-## Perlin zaj
-> felhők, hegyek, minecraft világ generáláshoz
-
-
-
-- több skálán állítjuk elő a jelet
-- egyre kisebb szinteken egyre kisebb értékkészletből, de egyre több mintapontot generálunk
-- ezeket összeadva kapunk egy zajos tartományt
-
-> ÉK gyorsan csökken $\Rightarrow$ sima
-> ÉK lassan csökken $\Rightarrow$ rücskös
-
-
-# Káosz
-
-## Nyulak szigete
-
-> És nem, nem ússzuk meg a Margit-szigettel.
-> Itt a populáció modellre kell gondolni.
-
-$x_{n+1}=Cx_n(x_{max}x_n)$
-
-ahol
-
-- $x_n$: populáció az n-edik lépésben
-- $C$: szaporodási ráta (együttható)
-- $x_max$: maximális populáció (amit a környezet elbír)
-
-különbőző $C$ esetek:
-
-- $C$ kicsi: 
-- $C$ közepes: 
-- $C$ nagy: 
-
-
-## Iterált függvények, fix pontok
-
-
-> Volt ilyen analízisből, mindenki tudja és szereti.
-> Annyiból áll, hogy $x_{n+1}$-et (a következő elemet) adjuk meg $x_n$ (az előző elem) függvényében.
-
-Fix pont
-
-- azon $x^*$-ok, amit ha odaadunk a függvénynek önmagát kapjuk vissza (fix)
-- matematikailag ez annyit tesz, hogy $x^* = F(x^*)$ (képe önmaga)
-- fix pont viszont lehet stabil és labilis is: 
-- tehát azaz vagyis akkor tekintjük stabilnak, ha $|F'(x^*)| < 1$
-
-## Káosz
-
-- maga a rendszer teljesen determinisztikus (két ugyan arra a bemenetre mindig ugyan azt kapom vissza) de mégsem tudom megjósolni a működést, mert bármilyen kis változtatás a kezdeti állapoton teljesen más eredményt ad vissza
-> megint jó példa a minecraft, gondoljunk csak a seedre:
-> - kétszer ugyan azzal a seeddel generált világ teljesen ugyan az lesz
-> - ha már csak egy számjegyet is változtatok rajta, a két világ közti különbség ég és föld
-
-- kis perturbáció nagyon eltérő viselkedéshez vezet
- - ha a perturbáció a 0-hoz tart akkor se lesz ugyanaz
-- autokorrelációs függvény a nullához tart, tehát a kezdőérték nem befolyásolja, hogy később hogy fog működni
-
-- "megjósolhatatlanság"
-- teljesítmény sűrűség spektrum nem lehet sávkorlátozott / nem tart zérushoz $\to$ nagy frekvencia lehet *(jelentsen ez akármit is)*
-
-
-## Pszeudó véletlenszám generátor
-```c
-static uint x = 3;
-
-void seed(uint s) { x = s; }
-
-uint rand( )
-{
- x = F(x);
- return x;
-}
-```
-azaz tehát vagyis
-
-$x_{n+1} = F(x_n)$ és
-
-$|F'(x)| > 1$ nagy és állandó
-
-pl. legyen
-
-$F(x) = \{g \cdot x + c\}\quad$ ($\{\}$ a törtrészt jelenti)
-
-
-
-> ez viszont viszonlag determinisztikus, biztonsági okokból nem kimondottan a legmegfelelőbb
-
-
-# Kaotikus rendszerek a síkon
-
-
-
-- azt szeretnénk, hogy egy pontsorozatot adjon, ami kirajzol valamit
-- pont a 2D síkon
- - komplex szám
- - $x, y$ számpár
-
-> mi legyen $F$?
-
-pl.
-$F: z \mapsto z^2$
-
-
-
-- komplex szám abszolút értéke szerint 3 csoportra osztható
- - $|z| = 1 $: 1 marad a távolsága az origótól, körülötte forog
- - $|z| < 1 $: csökken a távolsága az origótól, spirális pályán konvergál felé
- - $|z| > 1 $: nő a távolsága az origótól, spirális pályán divergál
-
-- a kör szétválasztja a stabil és instabil tartományokat
-- a kör maga egy (ugyan labilis de) attraktor
- - $\approx$ bármely pontjára nézve $F$ függvény eredménye szintén egy pontja lesz
- $F(H) = H$
-
-> azért labilis, mert ha ettől egy picit is eltérünk akkor "elvisz a fenébe"
-
-## Attraktor felrajzolása
-- attraktor a divergens (labilis) és konvergens (stabil) határa
- - $\Rightarrow$ kitöltött attraktor = nem divergens pontok *(magyarán ami belül és rajta van)*
- - $z_{n+1} = z_n^2$: ha $|z_\infin| < \infin$ (azaz nem divergens) akkor fekete
-- iterálunk a pontokon és megnézzük merre mennek, színezünk
-- ha az attraktorhoz konvergálunk $\to$ attraktor stabil
-- labilis attraktorhoz soha nem konvergálunk
-- pl: $z_{n+1} = z_n^2$ attraktora labilis (nem a körvonalhoz konvergálunk hanem a középpontjához)
-
-## Inverz iterációs módszer
-
-
-
-$H=F(H) \Rightarrow H=F^{-1}(H)$
-
-$z_{n+1} = z_n^2 ~~\Rightarrow z_{n+1} = \pm \sqrt{z_n}$
-
-$r_{n+1} = \sqrt{r_n}$
-
-$\varphi_{n+1} = \varphi_n/2 + \pi\{0|1\}$ (azaz $\pi ~\cdot$ vagy $0$ vagy $1$, mert 2 gyök van)
-
-Midőn $n \to \infin$:
-
-$r_{n} = \sqrt[2^n]{r_0} \to 1$
-
-azaz vagyis tehát a körön lesz előbb vagy utóbb de leginkább csak közelíti
-
-- függvény attraktora (ha van neki) megegyezik az inverzével, de stabilitása ellentétes lesz (stabil $\rightleftarrows$ labilis)
-- $z^2$-nél távolabb visz (labilis), inverzénél ($\sqrt{z_n}$) közelebb visz (stabil) az iteráció az attraktorhoz
-
-## Többértékű leképzés: bolyongás
-
-- $\varphi_{n+1} = \varphi_n/2 + \pi\{0|1\}$
- azaz
- - a pozitív gyök esetén $\varphi \to 0$
- - a negatív gyök esetén $\varphi \to 1$
-- ha mindig csak egy irányba megyünk az nem lesz jó, véletlenszerűen bolyongunk benne
-
-## Julia halmaz
-$F: z \mapsto z^2 + c$
-Kölönböző $c$-k esetén:
-
-
-### Implementáció
-> 2 féle megközelítés:
-
-> - "gyökvezérelt": számoljuk a gyököket egy bizonyos mélységig, és az érintett pixeleket átszínezzük
-> - pixelvezérelt: minden pixelre a függvény inverzén iterálunk, az alapján színezünk
-> *(elég gettó megfogalmazás de nekem ez jött át, kódot nem kaptok \:P)*
-
-
-## Mandelbrot halmaz
-Azon c komplex számok, amelyekre a $z \mapsto z^2 + c$ Julia halmaza összefüggő.
-
-Egy videó, ami ugyan kicsit szájbarágósan de szerintem élvezhetően elmagyarázza a komplex számokat és a Mandelbrot halmazt: [The Mandelbrot Set (Vsauce)](https://youtu.be/MwjsO6aniig?t=71)
-
-Isten létezésének bizonyítása a Mandelbrot halmazzal (ennek mégkevesebb köze van az anyaghoz): [Proving God exists using Math](https://www.youtube.com/watch?v=z0hxb5UVaNE)
-
-A 3D változata Mandelbulb néven ismert.
-
-## ISF
-
-ISF = Iterált Funkciós Rendszer
-
-### Inverz feladat
-
-
-Inverz feladat, tehát $H$ ismert és $F$-et szeretnénk.
-
-$F$ szabadon vezérelt, legyen stabil attraktora:
-
-$H = F(H) = W_1(H) \cup W_2(H) \cup W_3(H) \cup W_4(H)$
-
-
-
-$\boxed{W_k (x,y) = [x,y]\cdot A_k + q}$
-
-Ez egyet pont lineáris transzformációját és eltolását határozza meg.
-
-$F = W_1 \vee W_2 \vee ... \vee W_m$
-
-Nem feltétlenül hasonlósági transzformáció!
-
-Nem csak önhasonló objektumokhoz használjuk.
-
-
-
-# Kvíz
-
-> 1\. Jelölje ki azon komplex számokat, amelyeket a Mandelbrot halmaz tartalmaz.
-
-*Megoldás:*
-
-*"Azon c komplex számok, amelyekre a $z \to z^2 + c$ Julia halmaza összefüggő."* Azaz ahol $z \to z^2 + c$ nem divergál.
-
-
-- [ ] -1+i
- $z_1 = -1+i$
- $z_2 = 1 -2i +i^2 + (-1+i) = -1-i$
- $z_3 = 1 +2i +i^2 + (-1+i) = -1+3i$
- $\vdots\quad$ belátjuk hogy elszáll
-- [x] -1
- $z_1 = -1$
- $z_2 = 1 - 1 = 0$
- $z_3 = 0 - 1 = -1$
- $\vdots\quad$ innen már oszcillál
-
-a többi példa gyakorlásnak:
-
-- [ ] 1
-- [x] 0
-- [x] i
-- [x] -i
-
-
----
-> 2\. Az $F(z)=e^z + c$ függvényt iteráljuk, ahol a kezdeti állapot $z_0=\frac{\ln(2)}{2} + {i}\frac{\pi}{4}$ és $c=-1-i$.
-Mennyi az első iteráció után az állapot valós része?
-
-*Megoldás:*
-
-$z_1 = e^{\frac{\ln(2)}{2}} \cdot e^{i\frac{\pi}{4}} -1 -i$
-
-$z_1 = \sqrt2 (\cos(\frac \pi 4)+ i \sin(\frac \pi 4)) -1 -i$
-
-$z_1 = \sqrt2 \cdot \frac{\sqrt 2}2 (1+ i) -1 -i = 0$
-
----
-> 4\. Mekkora a Hausdorff dimenziója az alábbi L-rendszer által definiált alakzatnak:
-F -> FFFFFFFFF
-
-*Megoldás:*
-
-Elképzeljük magunk előtt a teknőcöt, csak egyenesen megyünk, az eredmény egy 9 részből álló egyenes szakasz.
-Tehát ha nem ugrik be egyből, hogy ez $1$ dimenziós, akkor itt van levezetve:
-
-$D = \cfrac{\log{N}}{\log(1/r)} = \cfrac{\log 9}{\log{\frac 1 {\frac 1 9}}} = 1$
-
-
----
-> 5\. Mekkora a Hausdorff dimenziója az alábbi L-rendszer által definiált alakzatnak:
-F -> -90F+90F+90FF-90F-90FF+90F+90F
-
-*Megoldás:*
-Érdemes lerajzolni, szép négyszögjelféleség.
-A szakaszok hossza az egész kiterjedésnek $\frac 1 3$-a, és $9$ szakaszunk (ahogy 9 F betű is) van.
-
-$D = \cfrac{\log{N}}{\log(1/r)} = \cfrac{\log 9}{\log 3} = 2$
-
----
-> 6\. Nagy Britannia partvidékének hosszát megmérve 256 km-es vonalzóval, a hossz 2048 km-re adódott. Amikor megismételtük a mérést 128 km-es vonalzóval, akkor eredményül 2560 km-t kaptunk. Mekkora a partvidék vonalzó dimenziója?
-
-*Megoldás:*
-
-$r = \frac{128}{256}$
-
-$N = \frac{20}{8}$
-
-$D = \cfrac{\log{N}}{\log(1/r)} = 1.32$
-
-:neptunfej:
-
----
-> 7\. Tekintsük az alábbi iterált függvényt: $ F(x)=2x(1-x) $.
-Mekkora a függvény legnagyobb fixpontjának az értéke?
-
-Az $x = 2x(1-x)$ helyen.
-
-$x = 2x - 2x^2$
-
-$0 = 2x^2 - x$
-
-$x_1 = 0$
-
-$x_2 = \frac 1 2$, tehát a válasz $0.5$
-
-
----
-> 8\. Tekintsük az alábbi iterált függvényt: $ F(x)=Cx(1-x) $.
-Legalább mekkorának kell lennie a C faktornak, hogy az iteráció ne legyen konvergens?
-
-A stabil pontok:
-
-$x = Cx(1-x)$
-
-$x_1 = 0$
-
-$x_2 = \frac{C-1}{C}$
-
-$x_0$ pont akkor stabil, ha $|F'(x_0)| < 1$
-
-$F'(x) = C(1-2x)$
-
-$F'(x_1) = C$, tehát $|C| < 1$
-
-és
-
-$F'(x) = C(1-2x)$
-
-$F'(x_2) = -C + 2$, tehát $|-C+2| < 1$ azaz $1 < C < 3$ vagyis a válasz a $3$
-
----
-> 9\. Adja meg az alábbi Sierpinski szőnyeg Hausdorff dimenzióját:
-
-
-$r = \frac 1 3, N=8$
-
-$D = \cfrac{\log 8}{log 3} = 1.89$
-
----
-> 10\. Mekkora a Hausdoff dimenziója az alábbi alakzatnak (két értékes jegyre):
-
-
-$r = \frac 1 2, N=3$
-
-$D = \cfrac{\log 3}{log 2} = 1.58$
-
-
-
-[Előző](./11.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/2.md b/docs/notes/sem4/computer_graphics/2.md
deleted file mode 100644
index 1e32e90..0000000
--- a/docs/notes/sem4/computer_graphics/2.md
+++ /dev/null
@@ -1,234 +0,0 @@
-# Grafikus hardver és szoftver
-
-- **Szovtver architektúra:** *(legalábbis amit mi használunk)*
-
- - Az eseménykezeléshez glutot használunk, a lényeg, hogy a main-ben regisztrálunk event handlereket pl. onDisplay és az OS eseményeire a glut callback-ként hívja a mi függvényünk
-- OpenGL:
- 
- - VAO: vertex array object - ebben több VBO-t tárolhatunk, a műveletek (transzformációk, vágás) ezen történnek
- - VBO: vertex buffer object - ebben tárolunk pontokat és a hozzá tartozó alakzatokat
- - [VBO/VAO megértést segítő videó](https://www.youtube.com/watch?v=Rin5Cp-Hhj8)
- - Az OpenGL egy állapotgép = amit beállítok úgy marad
- - Kirajzolás:
- - GL_POINTS
- - GL_LINE_STRIP, GL_LINE_LOOP (bezárja a strip-et)
- - GL_TRIANGLES (mindig 3 egymás utáni pont egy háromszog)
- GL_TRIANGLESTRIP *(az utolsó pontot veszi hozzá az előző kettőhöz: (abc), (bcd), (cde)...)*
- GL_TRIANGLE_FAN: *(az első ponthoz veszi a legutóbbi kettőt: (abc), (acd), (ade) ...)*
- ```cpp
- glDrawArrays(MODE, first, count);
- ```
-
-- Input kezelés:
- - az operációs rendszernél a koordináta rendszer origója a bal felső sarokban található, az y tegnely fejjel lefelé van!
- - az glViewport viszont a bal alsó sarkot tekinti origónak, tehát valahogy így néz ki a dolog:
- - 
- - tehát ha a normalizált eszközkoordinátákat szeretnénk megmondani az ablak koordinátái alapján akkor
- - $ndcX = \cfrac{2(x − offsetX)}{viewWidth} − 1$
- - $ndcY = 1 − \cfrac{2(y − offsetY)}{viewHeight}$
-
-
-
-- Adatok feldolgozása:
- ```cpp
- glEnableVertexAttribArray(0); // engedélyezi az írást ezekbe a regiszterekbe
-
- // beállítja a regiszter tulajdonságait
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- // Paraméterek: id, hány darab számot tárol, milyen típusú, isFixedPoint, stride, offset
-
- // adatok feltöltése
- glBufferData(GL_ARRAY_BUFFER, size_in_bytes, &startOfArray[0], GL_STATIC_DRAW);
- // a mód lehet dinamikus is attól függően állítjuk, hogy gyakran cserélődik-e az adat
- ```
- - `gl_Position`: egy kötelező kimeneti regiszter (változó), ebbe várunk össze a rajzoláshoz megfelelő számú csúcspontot (pl. háromszögnél 3 darabot)
- - **Figyelem: ez mindig 4 dimenziós lesz és a 3D-s projektív geometriai szabályok szerint lesz értelmezve** *(mivel a 3. dimenziót egészítjük ki +1-gyel)*
-
- - Uniform változók: olyan változók, amik állíthatók a hader programban. Nem a pontok adatai közé tartoznak (pl. az MVP)
- - Mi a megvalósításnál dupla bufferelést használtunk *(a háttér buffert rajzoljuk, a előteret mutatjuk a usernek és ezt a kettőt cserélgetjük)*. Ezt a `glutSwapBuffers();` függvényhívással értük el.
-
-### Konvex burok (érdekesség)
-> Ezen a programon lett bemutatva az OpenGL használata
-> 
-> (ez nem az optimális algoritmus, de egészen használható)
-
----
-
-# Kvíz
-
-> 1\. Hány háromszöget próbál kirajzoltatni az alábbi programsor:
-> `glDrawArrays(GL_TRIANGLE_FAN, 5, 7);`
-
-- glDrawArrays(MODE, start, count) $\Rightarrow$ az 5-ös rész csak azt jelenti, hogy az 5. től kezdve szeretnénk kirajzolni 7 pontnyit
-- A GL_TRIANGLE_FAN az első 2 pontból még nem tud háromszöget rajzolni, úgyhogy csak a 3.-tól kezdve, viszont akkor minden új ponttal rajzol egy darab háromszöget
-- Vagyis 7-2 = 5 darabot tud rajzolni
-
-[*(Másik számokkal szemléltető kép)*](https://i.sstatic.net/G0JGo.png)
-
----
-> 2\. Az onMouse eseménykezelő egy eseményt kapott, amelyben az átadott koordináták 884,600 volt. Mi ennek a pontnak a normalizált eszközkoordinátarendszerbeli y koordinátája, ha az alkalmazásablak felbontása 1000x1000 az utolsó nézeti beállítás a glViewport(100, 200, 800, 700) volt.
-
-- Kis segítség: `glViewport(x, y, width, height)`, és a bal alsó sarokból veszi az offsetet, az egér viszont bal felülről számol.
-- Képletek és ábra fent, de nem garantálom hogy jók
-
----
-> 3\. Egészítsük ki egész számokkal az alábbi programot úgy, hogy a 10 elemeű vtxData tömb teljes egészéba a vbo-ba másolódjon.
-> A pos adattag a csúcspont árnyaló 0. regiszterébe
-> A norm adattag az 1. regiszterébe
-> A tex adattag a 2. regiszterébe
-
-
-- Magyrázat:
- - az elején a struktúrát megnézzük, akkor látjuk, hogy:
- 1 db vec3 az 3 float-ból
- 1 db VertexData az 3 vec3-ból áll
- - 360 azért annyi, mert byte-okban kell megadni és egy float az 4 byte, vagyis $4 \cdot 3 \cdot 3 \cdot 10$ byte lesz feltöltve
- - A 3 azért annyi, mert egy vec3 valójában 3 floatból áll, a 36 az a VertexData mérete, az offset pedig szintén byte-ban az adat pozíciójának offset-je
-
----
-> 4\. Mik igazak a gl_Position regiszterre?
-
-- Ha 3D euklideszi geometriában dolgozik a vertex shader, akkor ide a Descartes koordinátákat kell írni kiegészítve a w=1-gyel
-*(Magyarázat picit korábban volt, de a lényeg annyi, hogy perspektív térábrázolásra van kitalálva a GPU, ezért érdemes úgy használni $\Rightarrow$ `gl_Position = (vp.x, vp.y, vp.z, 1)`)*
-
-
-- Az ebbe pakolt pont koordinátáit a GPU a 3D projektív geometria szabályai szerint értelmezi, azzal a megkötéssel, hogy a nemnegatív w koordinátájú pontokat tartja meg csak a vágás.
-*(Ezt csak későbbi előadáson részleteztük, de érdemes megjegyezni, hogy ami nem látszik az le lesz vágva)*
-
----
-> 5\. Az alábbiak közül melyik OpenGL programokkal befolyásolhatjuk a pixel shader program működését
-
-- A glUniform - ez volt az egyetlen felsorolva, amire igaz volt, a többi az vagy független pl. viewport vagy már fragment shading
-
----
-> 6\. Válasszuk ki az igaz állításokat. Feltételezzük, hogy a GPU háromszögeket dolgoz fel aés a glDrawArrays(GL_TRIANGLES, 0, 30) OpenGL hívás hatására.
-
-- Egy helyes válasz volt:
- - Lehet olyan csúcspontárnyalót írni, amely esetén a GPU nem rajzol ki semmit a vbo tartalmától függetlenül
- ```cpp
- /* magyarázat: */ void main() { gl_Position = vec4(0, 0, 0, 0); }
- ```
-- A többi válasz miért helytelen:
- - A GPU csúcspont árnyaló programjában ki tudjuk számítani egy háromszög súlypontját.
- *(Nem tudjuk, egyszerre mindig csak egy csúcsponttal foglalkozunk egy számítási egységen)*
- - A csúcspontárnyaló dönthet arról, hogy a pontokat a háromszög csúcspontjaiként vagy háromszög legyezőként (GL_TRIANGLE_FAN) értelmezze.
- *(Nem, ezt mi állítjuk be. Az OpenGL állapotgép)*
- - Ha a háromszög súlypontját a pixel árnyalóban számoljuk ki, akkor azt elég egyetlen pixelre, és az eredményt át lehet adni a többi pixel árnyalójának.
- *(... no comment)*
- - A vágás során a primitív típusa (GL_TRIANGLES) lényegtelen.
- *(Nem lényegtelen, mert ettől függ mit rajzolunk ki $\Rightarrow$ különböző alakzatokat különböző módon kell vágni)*
- - A GPU pixel árnyaló programja eldönti, hogy melyik pixelt színezze ki a kért színre.
- *(ElDöNTi - nem, majd én döntöm el. Az OpenGL állapotgép)*
-
----
-> 7\. Válassza ki a helyes állításokat az OpenGL körrajzoló képességével kapcsolatban.
-
-- A helyes válaszok:
- - Az OpenGL nem tud kört rajzolni, mert projektív geometriában nincs távolság, ezért nincs kör sem, helyette kúpszeletek lehetnek, azok viszont túl bonyolultak lennének a vágás és raszterizáció hw. implementációjához.
- - Az OpenGL nem tud kört rajzolni, mert a művelet felesleges, hiszen a kör közelíthető szabályos sokszöggel.
-
----
-> 8\. Jelöljük be az alábbi programra vonatkozó igaz állításokat:
-```cpp
-#include
-#include
-#include
-
-void onDisplay(), onInitialization();
-
-int main(int argc, char * argv[]) {
- glutInit(&argc, argv);
- glutInitContextVersion(3, 3);
-
- glutInitWindowSize(600, 600);
- glutInitWindowPosition(100, 100);
- glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
- glutCreateWindow(“Hi Graphics");
-
- glewExperimental = true;
- glewInit();
- glViewport(0, 0, 600, 600);
-
- onInitialization();
- glutDisplayFunc(onDisplay);
- glutMainLoop();
-
- return 1;
-}
-```
-
-- Helyes állítások:
- - Csak Microsoft Windows operációs rendszer alatt fordul le.
- *(`#include `)*
- - A rajzolás célterülete a teljes alkalmazó ablak.
- *(a viewportot teljesen kitöltjük, nincs offset)*
- - Egy pixelt 64 biten fog a hardver tárolni a rasztertárban.
- *(`glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);` emiatt - 2 buffer, 4 channel, 8 bit / szín $\Rightarrow 2 \cdot 4 \cdot 8 = 64$)*
- - Egyetlen sor törlésével a program Unix alatt is fordíthatóvá válik.
- *(`#include `)*
-
-- Hamis állítások
- - Ha Visual Studiót használunk, akkor semmit sem kell installálni és a Web-ről letölteni, hogy leforduljon.
- - A nézeti téglalap 100x100 pixelből áll.
- - A glutCreateWindow után hívhatunk OpenGL függvényeket.
- *(nem, csak akkor hívhatók, ha inicializáltuk az OpenGL-t, ami az onInitialization-ban történik a framework-ben)*
- - Hibás, hogy az opengl.h nincs beinklúdolva.
- *(nem hibás, mert ezért van nekünk a glew könyvtár - ez segít eldönteni, hogy az OpenGL melyik verzióját vagunk képesek használni)*
- - Ez OpenGL 3.0-ás verzióra készül fel.
- *(a glew eldönti)*
- - Ez OpenGL 1.0-ás verzióra készül fel.
- *(a glew eldönti)*
-
----
-> 9\. Az alábbi program szándéka szerint egy zöld háromszöget rajzolna ki phi radiánnal elforgatva, de nem működik. Mely sorokban van hiba?
-
-```cpp
-void onDisplay( ) {
- glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT);
-
- int location = glGetUniformLocation(shaderProgram, "color");
-
- glUniform3f(location, vec3(0.0f, 1.0f, 0.0f)); // hiba: 3 float változót vár paraméternek
-
- float MVPtransf[4][4] = {
- cos(phi), sin(phi), 0, 0,
- -sin(phi), cos(phi), 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 1
- };
-
- location = glGetUniformLocation(shaderProgram, "MVP");
- glUniformMatrix4fv(location, 1, GL_FALSE, &MVPtransf[0][0]); // hiba: 1 dimenziós array-t vár az utolsó paraméternek
-
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 1, 3 ); // hiba: nem 1 darab háromszöget, hanem 3 darabot akar kirajzolni
- glutSwapBuffers( );
-}
-```
-
----
-> 10\. Mely könyvtárak szükségesek feltétlenül, azaz nem csupán opcionálisak, az GPU OpenGL könyvtáron keresztüli programozásához.
-
-- Válasz: OpenGL *(nincs további helyes opció)*
-
----
-> 11\. Hány csúcspontot fog tartalmazni az alábbi vbo?
-```cpp
-unsigned int vbo;
-glGenBuffers(1, &vbo);
-glBindBuffer(GL_ARRAY_BUFFER, vbo);
-
-double vertices[] = {1,2,3,4,5,6,7,8};
-glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
-glEnableVertexAttribArray(0); // AttribArray 0
-glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
-```
-
-- Válasz: 16
- - Mert nagyon trükkösen double arraybe lettek pakolva a pontok, de float-ként lesznek feltöltve. Mivel a Double kétszer annyi helyet használ fel, mint a float, ezért 16 float-nyi helyet fognak elfoglalni
-
-
-[Előző](1.md)
-
-[Következő](3.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/3.md b/docs/notes/sem4/computer_graphics/3.md
deleted file mode 100644
index 8bc9c5f..0000000
--- a/docs/notes/sem4/computer_graphics/3.md
+++ /dev/null
@@ -1,308 +0,0 @@
-# Pontok és klasszikus görbék
-> Ha bárkinek van erre ideje, ez egy érdekes videó, az első 21 perce még néhol fedi is a tananyagot: [The Continuity of Splines - Freya Holmér](https://youtu.be/jvPPXbo87ds)
-
-## Koordináták
-- Koordináták használata: mérés alapján történik
-- Koordinátarendszer: referencia alapján
-- Baricentrikus (homogén) koordináták: $r_i$ referencia pontokhoz tartozik $m_i$ súly érték
- - > Homogén: ahol +1 dimenzióban jelöltük, hogy ideális pont-e
- - Error $r$ súlypont az, amin a tárgy "meg tudna állni"
- $r$ pont az $r_1, r_2, ...$ **pontok kombinációja** $\displaystyle r = \frac{\sum_i m_i r_i}{\sum_i m_i} = \sum_i \alpha_i r_i$ *(ahol $a_i = \frac{m_i}{\text{összsúly}}$)*
- - Konvex kombináció: ha a súlyok nem negatívak *(ekkor $r$ a referencia pontok között lesz)*
- - Egy egynes / szakasz: 2 pont konvex kombinációja
- - Egy háromszög / sík: 3 pont konvex kombinációja
- - *Mire is jó ez nekünk?*
- - Arra, hogy görbéket ábrázoljunk
- - Az explicit egyenlet $y = mx+b$ nem jó nekünk, hiszen csak egyenest lehet vele rajzolni *(hiszen 1 y-hoz csak 1 értéket vehetünk fel)*
- - Az implicit egynlet $f(x,y) = 0$ ez már lehetőséget ad, de még picit komplikált megkonstruálni *(azt fogjuk megnézni, hogy hogyan lehet egyszerűbbé tenni)*
-
-### Kvadratikus görbék
-- Példák: $r(x,y)$ azon pontok, amik kielégítik az egyenletet
- - Kör: $(r - c)^2 - R^2 = 0$
- - Ellipszis: $|r - f_1| + |r - f_2| = C$ *($f_1, f_2$ fókuszpont és $C$ távolságra)*
- - Hiperbola: $|r - f_1| - |r - f_2| = C$
- - Parabola: $|r - f| = n \cdot (r - p)$ *(n normálvektorú és p helyvektorú egyenestől mért távolságú pontok)*
-- Megadásuk:
- - Implicit alakban:
- $f(x,y) = a_{11} x^2 + a_{22} y^2 + 2a_{12} xy + 2a_{13} xy + 2a_{23}y + a_{33} = 0$
- - Mátrix alakban:
- $\displaystyle \begin{bmatrix} x & y & 1 \end{bmatrix} \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}$
-
- *(igazából ezekkel már egész komplex görbéket meg lehet adni)*
-
-### Paraméteres egyenletek
-- Nem csak kvadratikus görbékkel, de parametrikus egyenletekkel *(r(t)-t használva)* is le lehet írni görbéket, például:
-
-- *Jó, de ez miben más? Ez mozgásként fogalmazza meg a görbét, nem pedig feltétel rendszerként, mint az implicit egyenletek*
-
-## Szabadformájú görbék
-- A lényeg, hogy meg akarunk adni pontokat, amik közett olyan szépen természetesen menjen egy görbe
- - *(folytonosságok: $C^0$ - a görbe nem szakad, $C^1$ - a t szerinti első derivált folytonos, vagyis a görbület nem ugrál - nem kanyarodik hirtelen nagyobbat)*
- - $C^2$ folytonosság - a második derivált is folytonos, a görbék között a sebesség is állandó *(nem kanyarodik át hirtelen a másik irányba, ha eddig az egyikbe kanyarodott)*
-- Fontos még, hogy a kontroll pontok lokális vezérelhetőséget adjanak
-- Általában valahogy így néznek ki:
- $\displaystyle x(t) = \sum_i a_i \cdot t^i \\ y(t) = \sum_i b_i \cdot t^i \\ z(t) = ...$
-
-## Lagrange interpoláció
-- Legyen $r_1, r_2, ..., r_n$ kontrollpontok, amikhez a $t_1, t_2, ..., t_n$ csomóértékek ("súlyok") tartoznak
-- Ez egy $n-1$-ed fokú polinom lesz
-$\displaystyle r(t) = \sum_i L_i(t) \cdot r_i$ ahol $L_i(t) = \frac{\prod_{j \neq i} (t-t_j)}{\prod_{j \neq i}(t_i - t_j)}$
-- *(az $L_i$-nél az $i$-t is lehetne egy paraméterként jelölni, de matematikailag így szebb)*
-
-
-- Ha $L_i(t)$-nél $t$ a $k.$ kontrollpont ($t_k$), akkor: $L_i(t_k) = 1$, ha $i = k$, különben $0$
-*(ehhez csak végig kell gondolni, hogy a produktum hogyan működik)*
-- Mi ennek a rákfenéje:
- - Minden súly hat minden pontra $\Rightarrow$ ha az egyik kontroll pontot odébb rakom, az a teljes görbét megvariálja $\Rightarrow$ NINCS lokális vezérelhetőség, vagyis nem alkalmazható bonyolult ig kell gondolni, hogy a produktum hogyan működik görbékre
-
-## Hermite interpoláció
-- A Lagrange interpoláció általánosítása (ugyanazokkal a bajokkal küzd)
-- A pontoknak meg lehet határozni egy pont sebességét, gyorsulását
-- *Csak azt az esetet vettük, ahol 2 pont $p_1, p_2$ van és csak a sebességük van megadva $v_1, v_2$*
- - 4 tulajdonsága van $\Rightarrow$ ennyi ismeretlennel kell tudni számolni $\Rightarrow$ 3-ad fokú polinom lesz:
- $r(t) = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i)^1 + a_0$
- - Mivel a deriváltra is van feltétel, ezért ezt is használjuk:
- $\dot{r}(t) = 3 a_3 (t - t_i)^2 + 2 a_2 (t - t_i) + a_1$
-- *Az egyenletekbe helyettesítsük be a megkötéseket (legyen $t_i$ a 0. időpont):*
- $r(t_i) = p_i = a_0 \qquad$ *(hiszen itt t = 0)*
- $r(t_{i+1}) = p_{i+1} = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i)^1 + a_0$
- $\dot{r}(t_i) = v_{i} = a_1$
- $\dot{r}(t_{i+1}) = v_{i+1} = 3 a_3 (t - t_i)^2 + 2 a_2 (t - t_i) + a_1$
- *(ez nem olyan fontos, inkább a megoldás lényeges)*
-- Az egyenletek megoldása:
- - $a_0 = p_i$
- - $a_1 = v_i$
- - $a_2 = \frac{3(p_{i+1} - p_i)}{(t_{i+1} - t_i)^2} - \frac{(v_{i+1} + 2 v_i)}{t_{i+1} - t_i}$
- - $a_3 = \frac{2 (p_i - p_{i+1})}{(t_{i+1} - t_i)^3} + \frac{v_{i+1} + v_i}{(t_{i+1} - t_i)^2}$
-
-## Beziér approximáció
-Az a cél, hogy a függvény ne oszcilláljon, amit eddig például az váltott ki, hogy a súlyok _pozitív és negatív_ értéket is felvehettek azaz $B_i(t) \geq 0$ minden esetben.
-
-!!! note
- Ez konvex kombináció, vagyis a súlypont a pontok által bezárt konvex burokban van - korábban tárgyaltuk.
-
-Egy másik kikötés, hogy a súlyok arányosan hassanak, azaz
-
-$$\sum_{i} B_i(t) = 1$$
-
-teljesül.
-
-Ehhez Beziér a Bernstein-polinomokat használta súlyfüggvényként, amelyek a következők:
-
-$$1^n = (t + (1-t))^n \overset{\text{*}}{=} \sum_{i = 0}^n \binom{n}{i} \cdot t^i (1-t)^{n-i}$$
-
-$*$: a binomiális tétel miatt
-
-???+ note $\binom{n}{k}$ emlékeztető
- $$\binom{n}{k} = \frac{n^k}{k! (n-k)!}$$
-
-### Súlyfüggvény és görbe
-
-Ezek alapján a $B_i(t)$ súlyfüggvény a következő lesz:
-
-$$\displaystyle B_i(t) = \binom{n}{i} \cdot t^i (1-t)^{n-i}$$
-
-Maga az $r(t)$ görbe pedig:
-
-$$r(t) = \sum_{i = 0}^{n} B_i(t) \cdot r_i$$
-
-!!! note
- Mivel $i$ az $0$-tól indul, ezért a "pontok száma $- 1$"-ig megyünk és $0$-tól kezdjük a pontok számozását.
-
-### Hátrányok
-
-Egy hátránya a módszernek az, hogy ha sok kontrollpontunk van, akkor az egyik változása elhanyagolható lesz. Ráadásul az éles változásokat is nehéz megjeleníteni, mert túl sok pont hat.
-
-## Catmull-Rom spline
-- A hiba eddig az volt, hogy nagyon magas fokú lett a polinom, a bonyolult görbén a pontok hatása vagy túl sok vagy túl kevés lett
-- Megoldás: spline - több görbe szegmenssel dolgozunk
- Minden 2 pont közé egy Hermite interpolációs görbét illesztünk.
- - Az egymás utáni szakaszokon a lezáró és kezdő pont megegyezik és a sebessége is megegyezik, így nem fog ugrásszerűen változni a görbe
- *($C^1$ folytonos)*
- - Ehhez kell valami függvény arra is, hogy a $v_i$-ket is meghatározzuk
- *(ez úgy fog menni, hogy pontnak a 2 szakaszát egyenes vonalú egyenletes mozgásnak venni és annak az átlagsebességét használni)*
- $\displaystyle v_i = \frac{1}{2}(\frac{r_{i+1} - r_i}{t_{i+1} - t_i} + \frac{r_i - r_{i-1}}{t_i - t_{i-1}})$
- - a többit pedig fentebb láttuk
-- itt a $t$ csomú értékeket mi határozzuk meg *(a számolós feladatban az i. ponthoz i értéke tartozott azt hiszem)*
-
----
-
-# Kvíz
-> 1\. Egy Bézier görbe kontrollpontjai (4,8), (7,9), (4,4)
-> Mi a Bézier görbe t=1.0 paraméterre felvett pontjának x koordinátája?
-
-- Van-e bármi trükk, hogy elkerüljük a számolást?
-Igen van, hiszen $t = 1$ esetén a görbe utolsó pontjánál járunk, amit a görbe biztosan érint vagyis $r(1) = (4,4) \Rightarrow$ a válasz $4$
-- De mégis hogyan kéne kiszámolni?
-$r(t) = \sum_{i = 0}^{n} B_i(t) \cdot r_i \qquad B_i(t) = \binom{n}{i} \cdot t^i (1-t)^{n-i} \\ \qquad$
- 1. $n = 0 \ : \ B_0(1) = \binom{2}{0} \cdot 1^0 (1-1)^{2-0} = \frac{2^0}{0! \cdot (2-0)!} \cdot 1 \cdot 0$
- $\Rightarrow 0 \cdot (4, 8) = (0, 0)$
- 2. $n = 1 \ : \ B_1(1) = \binom{2}{1} \cdot 1^1 (1-1)^{2-1} = \frac\\ \qquad{2^1}{1! \cdot (2-1)!} \cdot 1 \cdot 0$
- $\Rightarrow 0 \cdot (7, 9) = (0, 0)$
- 3. $n = 2 \ : \ B_2(1) = \binom{2}{2} \cdot 1^2 (1-1)^{2-2} = \frac{2^2}{2! \cdot (2-2)!} \cdot 1 \cdot 1$
- $\Rightarrow 1 \cdot (4, 4) = (4, 4)$
-
-$(0,0) + (0,0) + (4,4) = (4,4) \Rightarrow$ a válasz még mindig $4$
-
----
-> 2\. Egy Lagrange görbe kontrollpontjai és a csomóértékei:
-
-> $(x, y), \qquad t$
-
-> $(4,5), \qquad 0$
-
-> $(6,4), \qquad 1$
-
-> $(7,10),\quad \ \ 2$
-
-> Mi a Lagrange görbe $t=0.9$ paraméterre felvett pontjának az x koordinátája?
-
-- A képlet:
-$r(t) = \sum_i L_i(t) \cdot r_i \qquad L_i(t) = \frac{\prod_{j \neq i} (t-t_j)}{\prod_{j \neq i}(t_i - t_j)}$
-- Számolás: *(0-tól számozok mert úgy kényelmesebb)*
- - $i = 0: L_0(0.9) = \frac{(0.9 - 1) \cdot (0.9 - 2)}{(0 - 1) \cdot (0 - 2)} = \frac{0.11}{2}$
- - $i = 1: L_1(0.9) = \frac{(0.9 - 0) \cdot (0.9 - 2)}{(1 - 0) \cdot (1 - 2)} = \frac{-0.99}{-1}$
- - $i = 2: L_2(0.9) = \frac{(0.9 - 0) \cdot (0.9 - 1)}{(2 - 0) \cdot (2 - 1)} = \frac{-0.09}{2}$
-
-$\frac{0.11}{2} \cdot (4,5) + \frac{-0.99}{-1} \cdot(6,4) + \frac{-0.09}{2} \cdot (7, 10) = \\ (0.22, 0.275) + (5.94, 3.96) + (-0.315, -0.45) = (5.845, 3.785) \Rightarrow 5.845$
-
----
-> 7\. Egy Catmull-Rom görbe kontrollpontjai és a csomóértékei:
-
-> $(x, y), \qquad t$
-
-> $(4,8), \qquad 0$
-
-> $(7,9), \qquad 1$
-
-> $(4,4), \qquad 2$
-
-> $(7,3), \qquad 3$
-
-> Mi a Catmull-Rom görbe $t=1.5$ paraméterre felvett pontjátnak az x koordinátája?
-
-1. a $1 < t < 2$, vagyis ezek között a pontok között fogjuk vizsgálni
-2. $v_i$-k kiszámítása:
- - $\displaystyle v_i = \frac{1}{2}(\frac{r_{i+1} - r_i}{t_{i+1} - t_i} + \frac{r_i - r_{i-1}}{t_i - t_{i-1}}) \\ \quad$
- - $\displaystyle v_1 = \frac{1}{2}(\frac{(4,4) - (7,9)}{2-1} + \frac{(7,9) - (4,8)}{1-0}) =\frac{(0, -4)}{2} \\ \quad$
- - $\displaystyle v_2 = \frac{1}{2}(\frac{(7,3) - (4,4)}{3-2} + \frac{(4,4) - (7,9)}{2-1}) = \frac{(0,-6)}{2}$
-
-3. Hermite paraméterei:
- - $a_0 = p_i = (7,9)$
- - $a_1 = v_i = (0, -2) \\ \quad$
- - $\displaystyle a_2 = \frac{3(p_{i+1} - p_i)}{(t_{i+1} - t_i)^2} - \frac{(v_{i+1} + 2 v_i)}{t_{i+1} - t_i} = \\ \frac{3((4,4) - (7,9))}{1} - \frac{(0,-3) + 2 \cdot (0, -2)}{1} = (-9,-8) \\ \quad$
- - $\\ \displaystyle a_3 = \frac{2 (p_i - p_{i+1})}{(t_{i+1} - t_i)^3} + \frac{v_{i+1} + v_i}{(t_{i+1} - t_i)^2} = \\ \frac{2 ((7,9) - (4, 4))}{1} + \frac{(0,-3) + (0,-2)}{1} = (6, 5)$
-
-4. Maga a függvény:
- - $r(t) = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i)^1 + a_0$
- - $r(1.5) = a_3 (1.5 - 1)^3 + a_2 (1.5 - 1)^2 + a_1 (1.5 - 1)^1 + a_0$
- $r(1.5) = (6,5) \cdot 0.125 + (-9,-8) \cdot 0.25 + (0, -2) \cdot 0.5 + (7,9)$
- $r(1.5) = (0.75, 0.625) + (-2.25,-2) + (0, -1) + (7,9)$
- $r(1.5) = (5.5,6.625) \Rightarrow 5.5$ a válasz
- :skull:
-
-
-
----
-> 3\. Jelöljük be az igaz állításokat!
-
-- Igaz állítások:
- - A $B_i(t)$ Bezier bázisfüggények összege 1.
- - A $B_i(t)$ Bezier bázisfüggvények a Bernstein polinomok.
- - A Bezier görbe C2 folytonos.
- - A $B_i(t)$ Bezier bázisfüggényeknek nincs valós gyöke a 0-n és az 1-en kívül.
- - A $B_i(t)$ Bezier bázisfüggények nem negatívak.
-- Hamis állítások:
- - A Bezier görbe interpolálja a kontrollpontjait.
- *(a görbe nem megy át minden kontrollponton)*
- - Ha n pontunk van, akkor a $B_i(t)$ Bezier bázisfüggények n-ed fokú polinomok.
- *(0-tól megy, úgyhogy n-1)*
- - A Lagrange görbe a Bezier görbe speciális esete.
- *(a Lagrange görbének semmilyen ilyen megkötése nincs)*
- - A Bézier görbe a Lagrange görbe speciális esete.
- *(nem használja a Lagrange képletét)*
-
----
-> 4\. Jelöljük be az igaz állításokat!
-
-- Igaz állítások:
- - A súlyokat használva kombinációs faktorként, pontok konvex kombinációja mindig a súlypontot adja meg.
- *(ezt képzeld el egy háromszögre, ahol a súlyok konvex kombinációja valóban a súlypontot adja)*
- - Három nem egy egyenesbe eső pont kombinációjaként a három pont által definiált sík bármely pontja előállítható.
- *(igen, súlyozástól függ)*
-- Hamis állítások:
- - A súlypontra felírt forgatónyomatók mindig zérus, ha a pontjainkat bármilyen erővel is támadjuk.
- - A súlypontot megfogva, a test nem mozdítható el.
- *(ezen a ponton stabilan áll, de ettől még mozgatható)*
- - Ha $r_i$ pontba $m_i$ súlyt (i=1,2,...) helyezünk, akkor a rendszer súlypontja $\displaystyle\sum^i m_i \cdot r_i$
- *(ehhez még le kell osztani az összsúllyal $\displaystyle\sum^i m_i$-vel, hogy igaz legyen)*
-
----
-> 5\. Jelöljük be az igaz állításokat!
-
-- Igaz állítások:
- - A hiperbola megadható kvadratikus implicit függvénnyel.
- - Ahogy az x=cos(t), y=sin(t) körmozgást definiál, az x=cosh(t), y=sinh(t) egy hiperbolán való mozgást.
- - Ha van egy olyan függvényünk, amely kifejezi egy pont és egy alakzat távolságát, akkor a függvény az alakzat implicit függvénye.
-- Hamis állítások:
- - Az egyenes y=m*x+b alakú explicit egyenletével a sík bármely egyenese definiálható.
- *(az y tengellyel párhuzamos egyenesek nem)*
- - Egy körnek egyetlen parametrikus egyenlete van.
- *(ugyanazt a köregyenletet végtelen sok módon fel tudod írni)*
- - A körnek van explicit és parametrikus egyenlete, de implicit egyenlete nincs.
- *(implicit van neki, explicit esetekre bontással van igazából)*
- - A tractrix a körmozgás és a haladó mozgás szuperpozíciója.
- - A hegy tetejéről az aljáig leggyorsabban egyenespályán csúszhatunk le.
- - Ahogy az x=cos(t), y=sin(t) állandó sebességű körmozgást definiál, az x=cosh(t), y=sinh(t) egy hiperbolán való állandó sebességű mozgást.
- *(nem állandó sebességű)*
- - Egy implicit függvény az alakzat és egy pont távolságát adja meg.
- - Ha egy alakzatnak az implicit egyenlete nem `a*x+b*y+c=0` alakú, akkor az alakzat nem lehet egyenes.
- *(nagyon egyszerű ellenpélda: (ax + by + c)^2 = 0)*
-
----
-> 6\. Jelöljük be az igaz állításokat!
-
-- Igaz állítások:
- - Az $L_i(t)$ Lagrange bázisfüggények összege 1.
- *(az előadáson volt egy diagramm a piros, kék ... színekkel és a lényeg, hogy minden pont hatása összesen 1)*
- - A Lagrange görbe C2 folytonos.
- - Az $L_i(t)$ Lagrange bázisfüggényeknek a gyökei a csomóértékek a $t_i$-t kivéve.
- - A Lagrange interpoláció a Hermite interpoláció speciális esete.
-- Hamis állítások:
- - Az $L_i(t)$ Lagrange bázisfüggényeknek nincs valós gyöke.
- *(attól még, hogy magas fokú lehet neki)*
- - Az $L_i(t)$ Lagrange bázisfüggények nem negatívak.
- *(de van ilyen is, a számolós példában is)*
- - Az Hermite interpoláció a Lagrange interpoláció speciális esete.
- *(pont fordítva, az általánosítása)*
- - Ha n pontunk van, akkor az $L_i(t)$ Lagrange bázisfüggények n-ed fokú polinomok.
- *(n-1)*
- - A csomóértékek megválasztása nem befolyásolja a Lagrange görbe alakját.
- *(de benne vannak a képletben)*
-
----
-> 8\. Jelöljük be az igaz állításokat!
-
-- Igaz állítások:
- - A Catmull-Rom görbe Hermite interpolációs görbékből épül fel.
- *(csak nézz fel)*
- - A Catmull-Rom görbe bázisfüggények összege 1.
- *(igen, mivel a Hermite az általánosítása a Lagrange-nak)*
- - A Catmull-Rom görbe harmadfokú polinom a kontrollpontok számától függetlenül.
- *(igen, mert Hermite-t használ)*
-- Hamis állítások:
- - A Catmull-Rom görbe bázisfüggényei nem negatívak.
- *(de azok, mert Hermit-et használ)*
- - A Catmull-Rom görbe C2 folytonos.
- *(a szegmensek ezt így nem korlátozzák be)*
- - A Catmull-Rom görbe a kontrollpontok konvex burkán belül fut.
- - A Catmull-Rom görbe egy pontjára minden kontrollpont hat.
- *(pont úgy lett kialakítva, hogy ne)*
- - A Catmull-Rom spline a Bezier görbe speciális esete.
- *(nope)*
- - Ha n pontunk van, akkor a Catmull-Rom görbe n-1-ed fokú polinom.
- *(nem, mert szegmensekből áll)*
-
-[Előző](./2.md)
-
-[Következő](./4.md)
diff --git a/docs/notes/sem4/computer_graphics/4.md b/docs/notes/sem4/computer_graphics/4.md
deleted file mode 100644
index a5eeee8..0000000
--- a/docs/notes/sem4/computer_graphics/4.md
+++ /dev/null
@@ -1,126 +0,0 @@
-# Affin transzformációk
-- **Transzformáció:** ponthoz pontot (koordinátához koordinátát) rendel egyértelműen
-
-> Motiváció: Kirajzolásnál pontot, szakaszt és háromszögeket fogunk használni. Ezért szükségünk van olyan transzformációkra, amelyek egyenestartóak
-
-- **Affin transzformáció:** párhuzamos egyenest tartó transzformáció
- - Példák: eltolás, forgatás, tükrözés, scaling, irángyfüggő megnyújtás, perspektív vetítés (ez már párhuzamos tartó)
- - Ellenpélda: inverzió (egyenesből kört, vagy körből egyenest csinál)
-
-> Ha nem pontot/szakaszt/háromszöget szeretnék kirajzolni vagy nem egyenestartó transzformációt használni, mit csináljak?
-
-> - Szilvásbuktát. Mert azt szeretem.
-> - Végezzük el a transzformációt és a végeredményt alakítsuk szakaszokra, háromszögekre
-
-- Cél: Mátrixok használata transzformációknál, mert asszociatívak, vagyis:
-$(((v \cdot M_1) \cdot M_2) ... \cdot M_n) = v \cdot (M_1 \cdot M_2 \cdot ... \cdot M_n)$
-- OpenGL-ben mátrixok feltöltése:
-```cpp
-// location (e.g. "MVP"), count, is transpose, the matrix (in a 1d array format)
-glUniformMatrix4fv(location, 1, GL_TRUE, &matrix[0])
-```
-
-## Gyakran használt mátrixok:
-> nem gondolnám, hogy fejből kell tudni őket
-
-- Affin transzformációk mátrixai:
- - Az origó a fix pontjuk (pl. forgatás középpontja, de az eltolásnak nincs)
- - A 4. oszlop $[0, 0, 0, 1]^T$
-
-- Forgatás (z tengely körül):
- $\begin{pmatrix}
- \cos(\varphi) & \sin(\varphi) & 0 & 0 \\
- -\sin(\varphi) & \cos(\varphi) & 0 & 0 \\
- 0 & 0 & 1 & 0 \\
- 0 & 0 & 0 & 1 \\
- \end{pmatrix}$
-- Eltolás:
- $\begin{pmatrix}
- 1 & 0 & 0 & 0 \\
- 0 & 1 & 0 & 0 \\
- 0 & 0 & 1 & 0 \\
- v_x & v_y & v_z & 1 \\
- \end{pmatrix}$
-- Skálázás:
- $\begin{pmatrix}
- s_x & 0 & 0 & 0 \\
- 0 & s_y & 0 & 0 \\
- 0 & 0 & s_z & 0 \\
- 0 & 0 & 0 & 1 \\
- \end{pmatrix}$
-
-# Kvíz
-
-> 1\. Egy affin transzformáció a (0,0) pontot az (3,4) pontra, az (1,0) pontot az (4,3) pontra, (0,1) pontot az (2,4) pontra képezi le. Mi lesz az (4,4) pont képének x koordinátája?
-
-$(0, 0) \to (3, 4) \\ \qquad 0 \cdot a + 0 \cdot b + c = 3 \\ \qquad 0 \cdot d + 0 \cdot e + f = 4 \\ \qquad c = 3, f= 4$
-$(1, 0) \to (4, 3) \\ \qquad 1 \cdot a + 0 \cdot b + 3 = 4 \\ \qquad 1 \cdot d + 0 \cdot e + 4 = 3 \\ \qquad a = 1, d = -1$
-$(0, 1) \to (2, 4) \\ \qquad 0 \cdot 1 + 1 \cdot b + 3 = 2 \\ \qquad 0 \cdot (-1) + 1 \cdot e + 4 = 4 \\ \qquad b = -1, e= 0$
-
-$(4, 4) \Rightarrow \\ \quad 4 \cdot 1 + 4 \cdot (-1) + 3 = ? \\ \quad 4 \cdot (-1) + 4 \cdot 0 + 4 = ? \\ \quad (3, 0) \Rightarrow 3$ a válasz
-
----
-> 2\. A 2D világba tett kamera középpontja (168,968) a kameraablak szélessége 14 magassága 7. Mi lesz az (221,16) világkoordinátarendszerbeli pont megfelelőjének x koordinátája normalizált eszközkoordinátarendszerben?
-
-*(Nem kell túlgondolni)*
-
-- A kamera középpontja a normalizált eszkkoord. rendszerben: $(0, 0)$
-- Az innen relative $+(7, 3.5)$ világkoordináta lesz a $(0.5, 0.5)$ *(ez az ablak szélességből látszik)*
-- Vagyis a kapott pontunk pozíciója: $\displaystyle \left(\frac{(221 - 168)}{14 / 2}, \frac{(16 - 968)}{7 / 2} \right) = \left(\frac{53}{7}, \frac{-952}{3.5} \right) = (7.5714, -272)$
-*(azért kell /2-vel számítani a képernyőszélességet, mert a normalizált az [-1, 1] intervallumon van, vagyis a szélessége 2 lenne)*
-
----
-> 3\. Melyek az alábbiak közül affin transzformációk?
-
-- Helyes válaszok: *(mindegyik az, az inverzió lenne a kivétel, de az nem szerepelt)*
- - Eltolás
- - x tengelyre vetítés
- - Az (1, 3) pont körüli forgatás
- - Nyírás: x'=x; y'=y+ax
- - Origóra tükrözés
- - Helyben hagyás
- - x tengely mentén végrehajtott skálázás
-
----
-> 4\. Adott két egyenes implicit egyenletükkel:
-
-> $4x+5y+2.5=0$
-
-> $12x+15y+14=0$
-
-> Számítsuk ki a metszéspont w harmadik homogén koordinátáját.
-
-- Keresztszorzást használva találjuk meg a metszéspontot
-
- $p = (4, 5, 2.5) \times (12,15,14)$
- $p.x = a.y \cdot b.w - a.w \cdot b.y = (5 \cdot 14) - (2.5 \cdot 15) = 32.5$
- $p.y = a.w \cdot b.x - a.x \cdot b.w = (2.5 \cdot 12) - (4 \cdot 14) = -26$
- $p.w = a.x \cdot b.y - a.y \cdot b.x = (4 \cdot 15) - (5 \cdot 12) = 0$
- $\Rightarrow 0$ a válasz
-
----
-> 5\. Egy sík implicit egyenlete: $8.5x+7y+4.4z+2.1=0$.
-
-> A síkot a $(4,3,5)$ vektorral eltoltuk.
-> Mennyi a transzformált sík normálvektorában az x és y komponensek aránya, azaz n.x/n.y.
-
-- Az eltolás nem változtat azon, hogy merre áll a sík *(csak azon, hogy hol van)*
-$\Rightarrow$ a válasz továbbra is $8.5 / 7 \approx 1.2143$
-
----
-> 6\. A síkgeometriában egy háromszög három csúcsának homogén koordinátái [0,0,3],[2,0,2] és [2,4,2]. Mekkora a háromszög területe?
-
-*(ez egy igaz-hamis-os jelölés volt egyébként)*
-
-Válasz: 1
-
-Magyarázat:
-
-1. A pontokat átalakítom:
-$(0,0,1), (1,0,1), (1,2,1)$
-1. A háromszög területét kiszámolom: *(az alap 1 széles, a magasága pedig 2)*
-$T = \frac{a \cdot m_a}{2}$
-
-[Előző](3.md)
-
-[Következő](5.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/5.md b/docs/notes/sem4/computer_graphics/5.md
deleted file mode 100644
index dce9629..0000000
--- a/docs/notes/sem4/computer_graphics/5.md
+++ /dev/null
@@ -1,285 +0,0 @@
-# 2D képszintézis
-> Van egy világ amit reprezentálni akarunk, ez világ koordinátarendszert használ, nekünk a célunk ebből a releváns részt a kamera ablakban megjeleníteni, a viewportba felrajzolni
-
-## Pixel vezérelt 2D képszintézis
-Fogunk minden viewport-beli pixelt és visszakeressük, hogy az világkoordinátarendszerben melyik pontot reprezentálja
-
-- Előny, hogy bármilyen transzformációt használhatunk, de hátrány hogy lassú
-- Egy másik hátrány, hogy nem minden alakzatnál tudjuk megállapítani, hogy benne vagyunk-e.
- - Megoldás lehet az implicit egyenlet, ahol ha $f(x,y) = 0$, akkor a határon, ha $< 0$ akkor benne, különben pedig kívül vagyunk.
- - Parametrikus görbéknél más a megoldás pl. van az a színezési módszer, ahol az dönti el, hogy páros vagy páratlan számúszor mentünk át az alakzat határán *(de ennek a hátrányairól órán nem beszéltünk)*
-
-- Az hogy mi legyen épp az előtérbe legjobb esetben egy listából halászható vissza
-
-## Objektum vezérelt képszintézis
-Alakzatokat mozgatunk a világkoordinátarendszerben, a viewportban a kirajzolás hátulról *(kis prioritásúaktól)* kezdődik, így az van az előtérbe renderelve, ami legelöl van. Ráadásul nem is lassú
-
-Megjelenítés menete:
-
-
-1. vektorizáció (a modellt kirakjuk - pl. a kis háromszögeket)
- **CPU $\Rightarrow$ GPU VAO**
-2. a modelltranszformációval elrakjuk valahova a világba
- **GPU Vertex shader**
-3. a kameratranszformáció eltranszformálja a normalizált eszközkoordinátarendszerbe *(persze mi is csak akkor fogjuk látni, ha a kamera látná)*
- **GPU pipeline**
-4. ezután a nézet hatása alá kerül és ki lesz vágva, ami felesleges
- **GPU pipeline**
-5. raszterializáljuk a képet *(pixelenként felrajzoljuk ami látszik)*
- **GPU fragment shader + frame buffer**
-
-## Vektorizáció
-> Hogyan alakítjuk pontokra, szakaszokra és háromszögekre az alakzatainkat?
-
-- A görbéket $n$ pici szakaszra bontjuk, ahol a szakasz $i.$ pontja $r(t_i)$ érték *(akkor tudjuk pontosan lekövetni a görbét, ha kicsi a különbség)*
-$t_i = t_{\text{start}} + (t_{\text{end}} - t_{\text{start}}) \cdot i / n$
-- A sokszögeket háromszögekre bontjuk:
- - A konvex sokszögeknél van $O(n)$-es algoritmus
- - A konkáv $O(n^3)$
-- **Tétel:** minden 4+ csúcsú, egyszerű sokszögnek van diagonálja, azaz mindegyik felbontható diagonálok mentén
- > egyszerű sokszög: ceruza felemelés nélkül megrajzolható és a határainak pontjait nem érinti kétszer
- - Ez a konkáv alakzatokra is igaz
- - ***Bizonyítás:*** *veszünk egy csúcsot és a két szomszédját összekötjük 1 vonallal, ekkor két dolog történhet:*
- 1. *az így kapott háromszögben nincs további csúcs $\Rightarrow$ egy diagonált húztunk be*
- 2. *ez a háromszög tartalmaz csúcsokat, (mert mondjuk egy konkáv cucc és kívülről még belógnak dolgok a berajzolt él fölött) ekkor az eredetileg kiválasztott csúcshoz legközelebbi belógó csúcsot diagonállal kötjük*
-- Konkáv alakzatok felvágása:
- - itt egyenként kell tesztelni a diagonál jelölteket, hogy nem metsz másik éleket és hogy a poligonon belül fut
- - azért ilyen magas a komplexitás, mert: $O(n)$ darab diagonál jelölt csúcspontunk van, amikre $O(n \cdot (n - 3)/2)$ élet kell tesztelni.
-
-- Fülvágó algoritmus:
- - ha van egy olyan $p_i$ pont aminek a szomszédait diagonál köti össze, akkor a fül levágható
- - *(Már csak azt kell belátni ehhez, hogy minden poligonnak van füle)*
- - **2 fül tétel:** minden 4+ csúcsú egyszerű sokszögnek van legalább 2 füle
- - *Bizonyítás:* már beláttuk, hogy minden ilyen alakzat háromszögesíthető. Ekkor ha háromszögekre bontjuk az alakzatot és a területek legyenek gráf csúcsai *(az élek pedig a diagonálok)*
- - Ez a gráf összefüggő, mert az alakzat összefüggő, továbbá nem tartaklmaz kört *(mert ha tartalmazna és elvágnánk egy élét, akkor az összefüggése megmaradna)* $\Rightarrow$ ez egy fa gráf $\Rightarrow$ minden fának van legalább 2 levele $\Rightarrow$ mindig lesz mit levágni
- - 
-
-## Kamera transzformáció
-- 2 fontos lépése van:
- 1. **View transzformáció:** a kamera középpontját az origóba kell viszatolni
- $x_{cam} = x_{world} - c_x \qquad y_{cam} = y_{world} - c_y$
- *(ahol $c_x, c_y$ a kamera közepe)*
- $\begin{pmatrix}
- 1 & 0 & 0 & 0 \\
- 0 & 1 & 0 & 0 \\
- 0 & 0 & 1 & 0 \\
- -c_x & -c_y & 0 & 1 \\
- \end{pmatrix}$
- 2. **Projekció:** a kamera ablakot a normalizált eszköz koordinátarendszerbe kell tenni
- $\begin{pmatrix}
- 2 / w_x & 0 & 0 & 0 \\
- 0 & 2 / w_y & 0 & 0 \\
- 0 & 0 & 1 & 0 \\
- 0 & 0 & 0 & 1 \\
- \end{pmatrix}$
-- Ezeket megszorozva a modellezési transzformációs mátrixszal a világkoordinátarendszerből az ablak terébe tudunk mozgatni mindent
-- Ennek a 3 mátrixnak a szorzata az **MVP** mátrix (Model View Projection)
-- *(a vertex-ek MVP mátrixal történő szorzását a vertex shader-ben kell megírni)*
-
-## Vágás
-- Mégis hogyan döntjük el, hogy mi az ami nincs benne a viewportban?
- - Minden pont ami belül van $-1$ és $1$ közötti koordinátákkal rendelkezik $\Rightarrow$ a 4 oldal mentén körbemegyünk és azokat a pontokat kivágjuk, amik nem teljesítik
- 
- - ez pontokra egészen jól működik, de a szakaszok meg háromszögek sarkainak kivágása nem túl optimális.
-- **Szakasz vágás:**
- - ha $x > x_{\text{max}}$, akkor mit lehet tenni
- 1. mivel a szakasz az egy egyenes, aminek van két végpontja, ezért felírható:
- $x(t) = x_1 + (x_2 - x_1) \cdot t$
- 2. $x_{\text{max}}$-ot az alábbi $t$ értéknél metszik:
- $\displaystyle t = \frac{(x_{\text{max}} - x_1)}{(x_2 - x_1)}$
- 3. akkor a túl lógó pontot helyettesítsük:
- $\displaystyle \left(x_{\text{max}} \ , \ y_1 + (y_2 - y_1) \cdot \frac{(x_{\text{max}} - x_1)}{(x_2 - x_1)} \right)$
-- Poligon vágás:
-
-
-
-- 3D Vágás homogén koordinátákkal:
- - $X(t) = X_1 \cdot (1 - t) + X_2 \cdot t$
- - Ekkor a cél, hogy:
- $-1 < x = X / w < 1$
- Amit valójában a GPU úgy valósít meg, hogy:
- $-w < X < w$
- - Ha vágni kell, akkor a szakasz vágáshoz hasonlóan csinálja
- *(persze nem csak X, hanem Y és Z koordinátára is)*
-
-### Viewport transzformáció
-- Amikor normalizált eszközkoordinátákból képernyő koordinátákba visszük át (pixelekre)
-
-
- *(ahol `glViewport(vx, vy, vw, vh)`)*
-
-$x_{pix} = v_w (x_{norm} + 1) / 2 + v_x$
-
-$y_{pix} = v_h (y_{norm} + 1) / 2 + v_y$
-
-## Raszterizáció
-- **Pontok kirajzolása**: mivel a pont nem biztos, hogy egy egész helyen van, ezért kerekítjük a koordinátáit és azon a helyen lévő pixelt rajzoljuk ki
-
-- **Szakaszok kirajzolása**:
- - $y = mx+b$ alapon növeljük x-et és az $y$ értéket kerekítve megkapjuk a pixelt, amit ki kell színezni
- - De ez lassú! Minden pont kiszínezéséhez egy szorzást meg egy összeadást kell elvégezni + kerekíteni
- - Megoldás: inkrementális elv, 1-szer kiszámoljuk az m-et és mindig csak hozzáadjuk
- $y(x) = y(x-1) + m$
- - De itt még mindig kerekíteni kell
- - *(csak azt az esetet tárgyaltuk amikor $m > 0$)*
- - Fixpontos inkrementális számítási elv:
- ```cpp
- const int T = 12; // fractional bits
-
- LineFix (short x1, short y1, short x2, short y2) {
- int m = ((y2 - y1) << T) / (x2 - x1);
- int y = (y1 << T) + (1 << (T - 1)); // +0.5
-
- for(short x = x1; x <= x2; x++) {
- short Y = y >> T; // trunc
- write(x, Y, color);
- y = y + m;
- }
- }
- ```
- - a lényeg, hogy ugyanúgy inkrementális, csak a bit shifttel végzi el a kerekítést, ami már nagyon gyors
- - Ezt egy [DDA](https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm)) szakaszkirajzoló hardver végezheti el, amivel még sokkal gyorsabb *(szimplán 3 regiszter, meg 1 összegző)*
-- **Háromszög kitöltés**:
- - itt is inkrementális elv és soronként érdemes csinálni és ha egy határt érintünk, akkor kezdődik a háromszög
- - az inkrementális elv a textúrázásnál is fontos lehet, hiszen a csúcsok között ahogy lépegetünk úgy tudjuk interpolálni a megadott textúrát
-
----
-
-# Kvíz
-
-> 1\. Hány diagonálja van egy szabályos 5-szögnek?
-
-Válasz: 5
-
-Magyarázat: Szabályos sokszögeknél az átlók száma ($\frac{n \cdot (n-3)}{2}$)
-
----
-> 2\. A 2D világba tett kamera középpontja (168,968) a kameraablak szélessége 14 magassága 7. Mi lesz az (221,16) világkoordinátarendszerbeli pont megfelelőjének x koordinátája normalizált eszközkoordinátarendszerben?
-
-*(Nem kell túlgondolni)*
-
-- A kamera középpontja a normalizált eszkkoord. rendszerben: $(0, 0)$
-- Az innen relative $+(7, 3.5)$ világkoordináta lesz a $(0.5, 0.5)$ *(ez az ablak szélességből látszik)*
-- Vagyis a kapott pontunk pozíciója: $\displaystyle \left(\frac{(221 - 168)}{14 / 2}, \frac{(16 - 968)}{7 / 2} \right) = \left(\frac{53}{7}, \frac{-952}{3.5} \right) = (7.5714, -272)$
-
- *(azért kell /2-vel számítani a képernyőszélességet, mert a normalizált az [-1, 1] intervallumon van, vagyis a szélessége 2 lenne)*
-
----
-> 3\. Nevezzük a szorzást és az osztást összefoglalóan bonyolult műveletnek, az összeadást és kivonást pedig egyszerűnek. Hány bonyolult műveletet hajt végre egy inkrementális háromszögkitöltő algoritmus az
-
-> (279,644), (14,770), (537,748)
-
-> csúcsú (pixelkoordinátákban) háromszög kitöltésekor?
-
-
-- A háromszög 3 oldalán lévő egyenesek meredekségét fogjuk osztással kiszámolni $\Rightarrow$ 3 osztás történik
-
-
----
-> 4\. A szakasz két végpontjának koordinátái normalizált eszközkoordinátarendszerben:
-
-> (-3.7;0.2;-0.5), (4.7;0.2;-0.5)
-
-> Mi lesz az első pont x koordinátája a vágás után?
-
-Válasz: -1
-
-Magyarázat: ha túl megy a határon, akkor le kell vágni. Ilyenkor a vágott rész a határhoz kerül
-
-
----
-> 5\. Hány diagonálja van az alábbi 5-szögnek?
-> 
-
-Válasz: 0
-Nem tudsz úgy berajzolni, hogy az ne az alakzaton kívül legyen
-
----
-> 6\. DDA algoritmus 16 bites törtrésszel dolgozik. Mennyivel nő a y regiszter értéke egészként értelmezve a tárolt bináris számot, két egymást követő pixel között, ha a szakasz két végpontja pixel koordinátákban:
-
-> (29,21), (86,39)
-
-$T = 16$
-
-$M = ((y_2 - y_1) << T) / (x_2 - x_1)$
-
-Vagyis $M = ((39 - 21) << 16) / (86 - 29) = 18 \cdot 2^{16} / 57 = 20 695$
-
-*(itt a törtrészt le kell vágni, mert int-re cast-olunk)*
-
----
-> 7\. Melyek az alábbiak közül az igaz állítások?
-
-- Igaz állítások:
- - Minden fagráfnak van legalább két levele.
- - Minden több mint három csúcsú egyszerű sokszög felbontható háromszögekre a diagonáljai mentén.
- - Van olyan több mint három csúcsú sokszög, amelynek nincs diagonálja.
- *(kettővel fentebb a példa)*
- - A diagonálok mentén végrehajtott felbontás nem egyértelmű.
- - Minden több mint három csúcsú egyszerű sokszögnek van legalább két füle.
-- Hamis állítások:
- - A háromszögeket egy gráf csomópontjainak tekintve, a diagonálokat pedig a két oldalukon lévő háromszögeknek megfelelő csomópontok közötti élnek, a keletkező gráf tartalmazhat kört.
- - Minden több mint három csúcsú sokszögnek van legalább két füle.
- *(nem, ha nem egyszerű)*
-
----
-> 8\. Melyek az alábbiak közül affin transzformációk?
-
-- Az (1, 3) pont körüli forgatás
- *(ez egy eltolás és forgatás)*
-- Helyben hagyás
-- x tengely mentén végrehajtott skálázás
-- Origóra tükrözés
-- Nyírás: x'=x; y'= y+ax
- *(igen, ez is tekinthető annak)*
-- Eltolás
-- x tengelyre vetítés
-
-
----
-> 9\. Az alábbi 2D homogén lineáris transzformációs mátrix hány fokos elforgatást valósít meg:
-
-> 0, -1, 0
- 1, 0, 0
- 0, 0, 1
-
-> Nyilván végtelen sok helyes válasz van, amelyek 360 fok egész számú többszörösében különböznek. A minimális abszolút értékű megoldást várjuk.
-
-$\cos(\varphi) = 0$ és $\sin(\varphi) = -1 \Rightarrow \varphi = -90$
-
----
-> 10\. Hány füle van az alábbi 5-szögnek?
-
-> 
-
-Válasz: 0
-
-Magyarázat: Ha nincs diagonálja, akkor füle sincs *(mert a fül az amikor egy pont szomszédai összeköthetők diagonállal)*
-
----
-> 11\. Nevezzük a szorzást és az osztást összefoglalóan bonyolult műveletnek, az összeadást és kivonást pedig egyszerűnek. Hány bonyolult műveletet hajt végre a GPU a fix műveleti egységben összesen egészen a pixel árnyalóig, egységmátrix MVP és az alábbi kételemű vbo által definiált szakasz feldolgozásakor és alábbi csúcspont árnyalót feltételezve:
-
-> `VBO = (0, 0.1, -0.4, 0.5), (-0.2, -0.3, 0.2, 0.9)`
-
-> Csúcspont átnyaló program:
-```cpp
-uniform mat4 MVP;
-layout(location = 0) in vec4 v;
-void main() {
- gl_Position = v * MVP;
-}
-```
-
-Válasz: 7
-
-Magyarázat:
-
-- $2 \cdot 4$ a pontok és az MVP szorzása.
- - MVP egy egységmátrix, meg amúgyis 4 szorzás lenne
- - Viszont ott ahol 0-val szoroznánk, ott tolhatunk egy `return 0`-t vagyis -1 szorzást végzünk el
-- A DDA-hoz tartozó osztás pedig azért nem számít, mert az már a raszterializálásnál a csúcspont árnyalás után történik
-$\Rightarrow 8-1 = 7$
-
-[Előző](./4.md)
-
-[Következő](./6.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/6.md b/docs/notes/sem4/computer_graphics/6.md
deleted file mode 100644
index 7e314bd..0000000
--- a/docs/notes/sem4/computer_graphics/6.md
+++ /dev/null
@@ -1,166 +0,0 @@
-
-
-# 2D Textúrázás
-
-> 2D textúrát szeretnénk ráragasztani egy alakzatra, kell egy megfeleltetés hogy adott pixelekhez a textúra melyik texele (textúra pixele) tartozik.
-
-
-## Textúraszűrés
-
-Adott pixelközéppontra megcsináljuk a lineáris leképezést, megnézzük textúratérben hol lenne $\Rightarrow$ UV koordináta a textúratérben
-
-### Nearest neighbor szűrés
-A UV koordináták alapján megkeressük a hozzá legközelebbi texelt, és az lesz a pixel színe.
-> Eredmény: éles textúra, látható pixelek
-
-
-
-```cpp
-// külön állíthatjuk a szűrést kicsinyítés illetve nagyítás esetén
-glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
-glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
-```
-
-### Mip-map
-**Probléma**: Minification esetén a pixel kiterjedése a textúrán egy nagyobb területet fed ezáltal több texelt is lefed. Mi viszont csak a pixel középpontjához leközelebb eső egyetlen texelt vesszük figyelembe. Ez zajos, pontatlan képeket eredményez.
-
-**Megoldás**: Mip-mapok, előre lekicsinyítjük a textúrát, minifikáció mértéke alapján különböző mip-map szinten keressük a texelt. Mivel a kicsinyített textúrában kisebb az eltérés az egy pixel és az egy texel által fedett terület között, ezért egy pontosabb színt kapunk.
-
-> (A mip-mapokat a GPU generálja, szintenként negyedakkora lesz a textúra, előre kiszámolja 4 pixel átlagszínét)
-
-```cpp
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); // Mip-mapping
-
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Tri-linear filtering
-```
-
-### Bilineáris szűrés
-A pixelünk UV koordinátája általában nem esik egyértelműen egy texelre. Bilineáris szűrésnél az UV koordinátát közrefogó 4 texelt vesszük figyelembe, és azok színeinek vesszük súlyozott átlagát $\Rightarrow$ színátmenetes lesz pixeles helyett.
-
-
-
-> Azért bilinear, mert 2 lineáris szűrést csinálunk, vízszintesen, majd függőlegesen. Igen, valójában 3 átlagot számolunk, de ez nem ugyan az, mint a lineáris szűrés.
-
-```cpp
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-```
-
-## Textúrázás a GPU-n
-
-
-
-### Textúra feltöltése a GPU-ra
-```cpp
-glGenTextures(1, &textureId);
-glBindTexture(GL_TEXTURE_2D, textureId); // binding
-glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, &image[0]); //Texture -> GPU
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-```
-
-### Objektumok felszerelése textúra (UV) koordinátákkal
-> Minden csúcsnak eltároljuk a hozzá tartozó UV koordinátáját. *(UV koordináta mondja meg, hogy adott csúcs a textúra mely pontjának felel meg.)* Ezt több féle képpen lehet, pl. stride (ugyan abban a VBO-ban, egymás után felváltva koordináták és uv koordináták) vagy külön VBO-ban (de ugyan abban a VAO-ban).
-
-Utóbbira (külön VBO) példa:
-```cpp
-glGenVertexArrays(1, &vao);
-glBindVertexArray(vao);
-glGenBuffers(2, vbo);// Generate 2 vertex buffer objects
-// vertex coordinates: vbo[0] -> Attrib Array 0 -> vertices
-glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
-float vtxs[] = {x1, y1, x2, y2, …};
-glBufferData(GL_ARRAY_BUFFER, sizeof(vtxs),vtxs, GL_STATIC_DRAW);
-glEnableVertexAttribArray(0);
-glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
-// vertex coordinates: vbo[1] -> Attrib Array 1 -> uvs
-glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
-float uvs[] = {u1, v1, u2, v2, …};
-glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);
-glEnableVertexAttribArray(1);
-glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
-```
-### Vertex és pixel shader
-
-
-Vertex shader:
-```cpp
-// a két bemeneti regiszterében kapja meg a poziíciót és az UV koordinátát
-layout(location = 0) in vec2 vtxPos;
-layout(location = 1) in vec2 vtxUV;
-
-// a kimenet egyetlen textúra koordináta
-out vec2 texcoord;
-void main() {
- gl_Position = vec4(vtxPos, 0, 1) * MVP;
- texcoord = vtxUV;
- ...
-}
-```
-
-Ennek kimenetét kapja meg a pixel shader:
-
-```cpp
-uniform sampler2D samplerUnit;
-// a pixelshader bemenete
-in vec2 texcoord;
-out vec4 fragmentColor;
-void main() {
- // a megfelelő sampler és a textúrakoordináta segítségével kiszámolja a megjelenítendő színt
- fragmentColor = texture(samplerUnit, texcoord);
-}
-```
-
-> Megértést segítő [videó](https://www.youtube.com/watch?v=3mfvZ-mdtZQ)
-
-
-# Kvíz
-
-> 1\. glTexParameteri(GL_TEXTURE_2D, melyik, milyen) OpenGL függvényre vonatkozóan válasszuk ki az alábbi állítások közül az igaz állításokat.
-
-- [x] A milyen=GL_LINEAR esetén a textúrázandó képnek csak a 0-as szintjét kell feltölteni.
-- [x] A milyen=GL_NEAREST-nél nagyításnál, és kicsinyítésnél is van jobb megoldás. *(mi számít jobbnak...)*
-- [x] A milyen=GL_LINEAR bi-lineáris interpolációt kapcsol be.
-
-- [ ] A milyen=GL_LINEAR esetén a rajzolás négyszer lassabb, mint a milyen=GL_NEAREST-nél
-- [ ] A milyen=GL_LINEAR_MIPMAP_NEAREST mindig jó, ha a textúrát a egyetlen glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, &image[0]); hívással töltöttük fel a textúrát.
-
----
-> 3\. Jelöljük be az glTexImage2D(target, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, address); utasítással kapcsolatos igaz állításokat.
-
-- [x] Az address azon CPU memóriaterület kezdőcíme, ahonnan a GPU-ra az adatokat átmásoljuk.
-- [x] A target lehet GL_TEXTURE_2D, ami azt jelenti, hogy az utoljára a GL_TEXTURE_2D-hez bindolt textúrát töltjük éppen fel. *(mást is fel lehet tölteni pl normalmap)*
-- [x] A glTexImage2D függvénnyel kell feltölteni akkor is a textúrát, ha mip-map-elést szeretnénk, de többször kell meghívni ezt a függvényt. *(miért kéne többször??? nem gpu generál neked mipmapet what?)*
-
-
-- [ ] A GL_FLOAT utolsó előtti paraméter az írja elő, hogy a GPU memóriában a texelek lebegőpontos formátumban tárolódjanak. *(nem, mert a színeket fogja ilyen típusban tárolni (miért tárolnád floatban na mindegy))*
-- [ ] A w és h paraméterek csak 2 hatványok lehetnek. *(nem)*
-- [ ] Az OpenGL-nek nem lehet unsigned char textúrákat átadni. *(lehet csak elég retro lesz)*
-- [ ] A harmadik, GL_RGBA paraméter azt fejezi ki, hogy a feltöltendő tömbben egy texelt a három színcsatornán és átlátszósággal adunk meg. *(nem a feltöltendő tömbbre vonatkozik hanem a képre amit megadsz neki)*
-- [ ] A második, 0 paraméter azt jelenti, hogy a texelek hézagmentesen vannak a textúrában. *(a textúra (mipmap) szintjét jelenti)*
-
-
----
-> 4\. Tekintsük az alábbi pixel shader programot:
-```cpp
-uniform sampler2D samplerUnit;
-in vec2 texcoord;
-out vec4 fragmentColor;
-void main() {
- fragmentColor = texture(samplerUnit, texcoord);
-}
-```
-
-- [x] A program változatlanul használható `glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);` beállítás és `glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);` beállításnál is.
-
-- [ ] A samplerUnit változót értékét a glGenTextures függvénnyel kell létrehozni.
-- [ ] A texture(samplerUnit, texcoord) azon texel színét adja vissza mindig, amelyhez a texcoord a legközelebb van. *(mindig redflag, samplertől függ)*
-- [ ] A fragmentColor változó w mezője automatikusan 1 értékű lesz. *(neeem általában ez az alpha csatorna és külön értéke lesz ugyan úgy)*
-
-[Előző](./5.md)
-
-[Következő](./7.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/7.md b/docs/notes/sem4/computer_graphics/7.md
deleted file mode 100644
index bb8a69a..0000000
--- a/docs/notes/sem4/computer_graphics/7.md
+++ /dev/null
@@ -1,249 +0,0 @@
-
-
-# 3D képszintézis
-
-## Színérzékelés
-
-- Monokromatikus = egyetlen hullámhossz kelt színérzetet
-- Polikromatikus = több, azokat keverve kapunk egy színérzetet, lineáris
-
-## 3D képszintézis fizikai alapmodellje
-
-> A való világban fényforrásaink vannak, azokból a fénysugarak egy adott út bejárása után a szemünkben képet keltenek. Ezt az illúziót szeretnénk kelteni a képernyőn.
-
-### Radiancia (sugársűrűség)
-Egységnyi vetített terület által egységnyi térszögbe sugárzott teljesítmény
-$[Watt/sr/m^2]$
-
-$L(r, v) = \cfrac{\Delta \Phi}{\Delta A ~ \cos \theta ~ \Delta \omega}$
-
-
-
-*Magyarázat:*
-
-- $r$ pontban felveszünk egy $\Delta A$ területet
-- $V$ irányban felveszünk egy $\Delta \omega$ térszöget
-- nézzük meg, hogy a $\Delta A$ felület a $\Delta \omega$ térszögben összesen mekkora teljesítménnyel sugároz $= \Delta \Phi$
-
-- ezt elosztjuk a térszög nagyságával ($\Delta \omega$) és a látható felület nagyságával ($\Delta A ~ \cos \theta$) *(látható nagysága az, hogy $\theta$ szögből mekkorának látom)*
-
-### Fényforrások
-Saját fényt emittál (waow)
-
-Absztrakt fényforrások:
-
-- irányféynforrás *(directional light)*: egyetlen irányban párhuzamos fénysugarak, pozíciótol független intenzitás
-- pozícionális fényforrás *(point light)*: egyetlen pontból sugároz, intenzitás a távolság négyzetével csökken
-
-> A foton energiája arányos a frekvenciájával. A foton hullámhossza rugalmas ütközésnél nem változik (néha elnyelődhet, de ez energiafüggő).
-$m=\frac{E}{c^2}=\frac{hf}{c^2}$
-
-### Fresnel egyenlet
-Sima felületeknél (1 pixelben síknak tekintjük) használjuk.
-A fény visszaverődhet és/vagy behatolhat az anyagba.
-
-
-
-*Magyarázat*
-
-- Fresnel faktor: hányadrésze verődik vissza a fénynek ($F$)
-- $n$: törésmutató, sebességarány, $n = \cfrac{\sin \theta^\text{in}}{\sin \theta}$ (dimenziótlan érték)
-- $\kappa$: kioltási tényező (*$\approx$ a hullám egy fényhullámnyi hosszon mennyit veszít az amplitúdójából*, dimenziótlan)
- - általában elhanyagolható, fémeknél van jelentősége
-
-$F(\theta^\text{in}) \approx F_0 + (1 - F_0) \cdot (1 - \cos \theta^\text{in})^5$
-*(de ez csak numerikus approximáció, van rá spicy komplex számos képlet)*
-
-$F_0 = \cfrac{(n-1)^2 + \kappa^2}{(n+1)^2 + \kappa^2}$
-*(mennyi részét veri vissza a beérkező fénynek, ha merőlegesen világítjuk meg)*
-
-### Tükörirány
-
-
-*Magyarázat*
-
-- milyen szögben verődik vissza (duh)
-
-$\cos \alpha = -v \cdot N$
-$R = v + 2N \cos \alpha$
-
-### Törésirány
-
-
-
-*Magyarázat*
-
-- milyen szögben töri meg a fényt
-
-$N_\perp = \cfrac{v + N \cos \alpha}{\sin \alpha}$
-$T = N_\perp \sin \beta - N \cos \beta$
-
-
-### Rücskös felületek
-Az 1 pixelben látható felület rücskös, a beérkező fényt több irányban veri vissza.
-
-
-
-*A fényt minden irányba szórja, de az elméleti visszaverődési irányba jobban.*
-
-### Fény-felület kölcsönhatás
-
-
-
-
-$\overbrace{L(\bold{r}, \bold{V})}^\text{Radiancia} = \overbrace{L^\text{in}(\bold{r}, \bold{L}) \cdot \cos \theta^\text{in}}^\text{Irradiancia} \cdot \overbrace{f_r(\bold{L}, \bold{r}, \bold{V})}^\text{BRDF}$
-
-$\qquad\qquad\qquad\qquad\quad\underbrace{\qquad\qquad\qquad\qquad~}_{\text{L-ből V-be vert arány}}$
-
-
-$f_r(\bold{L}, \bold{r}, \bold{V}) \stackrel{def}{=} \cfrac{L(\bold{r}, \bold{V})}{L^\text{in}(\bold{r}, \bold{L}) \cdot \cos \theta^\text{in}}$
-
-> Helmholtz tv.: $f_r(\bold{L}, \bold{r}, \bold{V}) = f_r(\bold{V}, \bold{r}, \bold{L})$ *(becsapódás és visszaverődés iránya felcserélhető)*
-
-*Magyarázat (tippre)*
-
-- $\bold{r}$: a pont ahová a fény becsapódik
-- $\bold{V}$: az irány amivel a fény visszaverődik
-- $\bold{L}$: a beeső fény iránya
-- $\theta^\text{in}$: a beesési szög
-- $L^\text{in}$: a beeső fény radianciája
-- $L$: a visszavert fény radianciája
-- $f$ mn. $\text{BRDF}$: az arányossági tényező *(anyagfüggő függvény, mely megadja, hogy adott irányból adott pontba érkező adott irányba mekkora valószínűséggel verődik vissza a foton (asszem))*
-
-### Diffúz visszaverődés
-- nagyon rücskös anyagokra jellemző
-- nézeti iránytól független
-
-- BRDF a nézeti iránytól független és
-- BRDF Helmholtz tv. miatt a megvilágítás irányától is független
-$f_r(\bold{L}, \bold{r}, \bold{V}) = k_d(\bold{r}, \lambda)$
-- színes
-- DE a megvilágítás irányától függ
-
-> Lambert törvény: a sugársűrűség függ a megvilágítási iránytól
-> $L^\text{ref} = L^\text{in} ~ k_d ~ \cos^+ \theta^\text{in}$
-> $\cos \theta^\text{in} = \bold{N} \cdot \bold{L}$
->
-> *($\cos^+$: nemnegatív cos, ha negatívba menne, akkor nullának tekintjük)*
-
-
-### Spekuláris visszaverődés (Phong - Blinn modell)
-Csillogó felületek is minden irányban visszaverik a fényt, de máshogy néznek ki különböző irányokból.
-
-Nem tökéletes minden esetben.
-
-
-
-*Magyarázat* `( ._.)`
-> \>felbontjuk egy diffúz és csillogós komponensre
-
-> \>???
-
-> \>profit
-
-$L^\text{ref} = L^\text{in} ~ k_d ~ \cos^+ \theta^\text{in} + L^\text{in} ~ k_s ~ (\cos^+ \delta)^\text{shine}\\
-\qquad = L^\text{in} ~ (k_d + k_s \cfrac{(\cos^+ \delta)^\text{shine}}{\cos^+ \theta^\text{in}}) ~ \cos^+ \theta^\text{in}$
-
-
-
-
-### Fényelnyelő
-
-> Az értelmezést az olvasóra bízzuk (lövésem sincs miez).
-
-
-
-- a sugarak egy része elakad
-- $\text{hányan ütköztek?} = \text{hányan léptek be} \cdot \text{ütközés valószínűsége}$
-
-
-# Kvíz
-
-> 1\. Jelöljük be az igaz állításokat.
-
-- [x] A Bezier felület a kontrollpontok konvex burkában van.
-- [x] A Lagrange interpolációs felület kétváltozós súlyfüggvényeinek összege mindig 1.
-- [ ] Parametrikus felület normálvektora a gradiens. *(parametrikus felületnél parciálisan deriválunk)*
-- [ ] Minden forgásfelület parametrikus egyenletében szükségképpen van sin és cos.
-- [ ] Minden felület megadható explicit egyenlettel.
-
----
-> 2\. Mely állítások igazak az alábbiak közül?
-
-- [x] Egy kiterjedt felületről induló fénysugár sugársűrűsége a sugár mentén állandó.
-- [x] Egy pontszerű fényforrásból induló fénysugár sugársűrűsége a forrástól vett távolság négyzetével csökken.
-- [x] A fotontranszport szimulációnál a látható tartományba eső frekvenciájú fotonok elektronokkal rugalmasan ütközve sohasem változtatják meg a frekvenciájukat.
-- [x] A törésmutató a két közegbeli fénysebességek arányával egyezik meg.
-- [x] A Fresnel függvény értékkészlete a [0,1] tartomány. *(arány)*
-
-- [ ] Csak a 444, 526 és 645 nm hullámhosszú fényből állítható elő bármilyen színérzet additív keveréssel. *(ez az rgb de nem csak eszerint oszthatjuk fel, és ez sem képes lefedni az egész színspektrumot)*
-- [ ] Az emberi szem kizárólag a 444, 526 és 645 nm hullámhosszú fényre érzékeny. *(a látható teljes spektrumra érzékeny, csak hullámhosszok különböző mértékben ingerlik a csapokat )*
-- [ ] A Fresnel függvény mértékegysége [W/m^2/st] (Watt per négyzetméter per szteradián). *(a Fresnel egy arányt ad meg, a [W/m^2/st] a radiancia mértékegysége)*
-- [ ] A fotontranszport szimulációnál a fotonok elektronokkal rugalmasan ütközve sohasem változtatják meg a frekvenciájukat.
-
----
-> 3\. Egy dielektrikum (nem fém, kioltási tényező közelítőleg zérus) törésmutatója 1.2. Hány százalékát veri vissza a belépő fotonoknak merőleges megvilágításkor?
-
-*Megoldás:*
-Egyszerű Fresnel.
-$F_0 = \cfrac{(n-1)^2 + \kappa^2}{(n+1)^2 + \kappa^2}$
-$\kappa$ elhanyagolható, $n$ a törésmutató.
-Behelyettesítve $\approx 0.826 \%$.
-
----
-> 4\. Az N=(0, 0, 1) normálvektorú felületet a (0,3,4) irányból világítja meg egy 4 W/m^2/st sugársűrűségű irányfényforrás. A felület diffúz visszaverődési tényezője 0.1. Mekkora sugársűrűséget detektál a ponttól az (1,2,3) irányban lévő kamera?
-
-*Megoldás:*
-Lambert tv. segítségével.
-> $L^\text{ref} = L^\text{in} ~ k_d ~ \cos^+ \theta^\text{in}$
-> $\cos \theta^\text{in} = \bold{N} \cdot \bold{L}$
-
-$\bold{L}$ egy irány, tehát normalizálnunk kell.
-$\bold{L} = (0, 0.6, 0.8)$
-
-
-$4 \cdot 0.1 \cdot \bold{N} \cdot \bold{L} = 0.32$
-
-
----
-> 5\. A fénysugár egy 1/0.1 törésmutatójú közegből érkezik a közeg határára. A határ másik oldalán levegő van. Legalább hány fokos szöget kell bezárnia fénysugár irányának és a levegő felé mutató felületi normálisnak, hogy a fénysugárból semmi se tudjon kilépni a közegből és teljes visszaverődés következzen be.
-
-*Megoldás:*
-Snellius-Descartes képlet:
-$n = \cfrac{\sin \theta^\text{in}}{\sin \theta} = \frac{1}{0.1} = 10$
-
-Keressük azt a $\theta$ szöget, ahol $\theta^\text{in} \geq 90°$, hogy ne legyen az anyagból kilépő fénysugár. Ennek is a minimumát (legalább) keressük tehát meg kell nézni, hogy hol áll fent az egyenlőség.
-
-$10 = \cfrac{1}{\sin \theta}$
-$\theta^\text{in} = \arcsin(\frac{1}{10}) = 5.74°$
-
-
-
----
-> 6\. Az N=(0, 0, 1) normálvektorú felületet a (0,3,4) irányból világítja meg egy 4 W/m^2/st sugársűrűségű irányfényforrás. A felület spekuláris visszaverődési tényezője $\sqrt{2}$, a shininess 3. Mekkora sugársűrűséget detektál a ponttól az (0,4,3) irányban lévő kamera?
-
-*Megoldás:*
-Jó diák módjára behelyettesítünk a képletbe.
-Mégjobb diák módjára nem felejtjük el normalizálni $L$ és $V$ vektorokat.
-
-$L^\text{in} ~ (k_d + k_s \cfrac{(\cos^+ \delta)^\text{shine}}{\cos^+ \theta^\text{in}}) ~ \cos^+ \theta^\text{in}$
-Ahol
-$\cos \delta = N \cdot H = N \cdot \cfrac{L+V}{|L+V|}$
-$\cos \delta = (0, 0, 1) \cdot \cfrac{(0,0.6,0.8)+(0,0.8,0.6)}{|(0,0.6,0.8)+(0,0.8,0.6)|} = 0.7071$
-és
-$\cos \theta = N \cdot L = 0.8$
-
-$4 \cdot (0 + \sqrt{2} \cfrac{0.7071^3}{0.8}) \cdot 0.8 = 2$
-
----
-> 7\. Határozza meg az $f(x,y,z)=x^2/3 + y^2/3 - z^2/3 - K$ implicit felület n=(nx,ny,nz) normálvektorára a nx/ny arányt az (3,3,2) pontban!
-
-*Megoldás:*
-Kiszámítható, mint a felületi gradiens.
-$\text{grad}f = \bigg(\cfrac{\partial \frac{x^2}{3}}{\partial x}, \cfrac{\partial \frac{y^2}{3}}{\partial y}, -\cfrac{\partial \frac{z^2}{3}}{\partial z}, \bigg) = \bigg(\cfrac{2x}{3}, \cfrac{2y}{3}, -\cfrac{2z}{3} \bigg)$
-Ami a $(3,3,2)$ pontban
-$n = (2, 2, -\frac{4}{3})$, tehát az arányuk $1$.
-
-[Előző](./6.md)
-
-[Következő](./8.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/8.md b/docs/notes/sem4/computer_graphics/8.md
deleted file mode 100644
index 1ed4a4d..0000000
--- a/docs/notes/sem4/computer_graphics/8.md
+++ /dev/null
@@ -1,273 +0,0 @@
-
-
-# Sugárkövetés
-
-> A dolog lényege, hogy egy 3D világ illúziójának képét szeretnénk a képernyőnkök látni, ezért kiszámoljuk, hogy bizonyos pixelekre a fény milyen úton jut el.
-
-## Lokális illumináció
-Csak absztrakt fényforrásokatat veszünk figyelembe, azokat is csak ha direkt módon világítják meg a testeket.
-
-
-
-$L(V) \approx \sum_l {L^\text{in}}_l \cdot f_r(L_l, N, V) \cdot \cos^+ {\theta^\text{in}}_l
-\\
-\qquad~~ = \sum_l {L^\text{in}}_l \cdot \{ k_d \cdot (L_l \cdot N)^+ + k_s \cdot \big((H_l \cdot N)^+\big)^\text{shine} \}$
-
-## Ambiens tag
-> Lokális illuminációnál azok a helyek, amiket semmilyen fény nem világít meg direktben, teljesen feketék lesznek. A való életben ez nem így van (golbális illumináció). Ennek egy olcsó megoldása, hogy mindent kivilágosítunk egy kicsit. Ez az ambiens fény.
-
-Az ambiens tagot minden visszakövetett sugárhoz hozzáadjuk (csak egyszer!).
-
-$L(V) \approx \sum_l {L^\text{in}}_l \cdot f_r(L_l, N, V) \cdot \cos^+ {\theta^\text{in}}_l + \boxed{k_a \cdot L_a}$
-
-## Láthatóság
-Adott pixelből elindítjuk a sugarat, meg kell keresnünk a legközelebbi objektumot, amibe a sugarunk beleütközik.
-
-
-```cpp
-Hit firstIntersect(Ray ray) {
- Hit bestHit;
- for(Intersectable * obj : objects) {
- Hit hit = obj->intersect(ray); // hit.t < 0 ha nincs metszés
- if(hit.t > 0 && (bestHit.t < 0 || hit.t < bestHit.t))
- bestHit = hit;
- }
- if (dot(ray.dir, bestHit.normal) > 0)
- bestHit.normal *= -1; // mindenképpen felénk nézzen a normális
- return bestHit;
-}
-```
-
-## Metszéspontszámítás
-### Gömb
-
-
-- Felület pontjai azon $r$ pontok, ahol $|r-c|^2 = R^2$
-- Metszéspont:
-Kiszámoljuk a másodfokú egyenletet, ahol $t$ az ismeretlen.
-Ha két gyökünk van, a közelebbit tekintjük.
-$|\text{ray}(t) - c|^2 = R^2 \\ \text{Megoldás: . . .}$
-- Normálvektor: $N = (\text{ray}(t)-c)/R$
-
-
-### Implicit felületek
-- A felület pontjai azon $r$ pontok, ahol $f(r) = 0$
-- Sugár: $\text{ray}(t) = s + d \cdot t$
-- Legyen $t^*$ azon paraméter, ahol $\text{ray}(t^*) = r^*$ pontban a sugár metszi a felületet, azaz $f(r^*) = 0$
-- Tehát a metszéspont: $r^*$
-- Normálvektor: $N = \text{grad}f(r^*)$
-
-### Kvadratikus felületek:
-- A felület pontjai: $f(r) = \begin{bmatrix} r & 1 \end{bmatrix} \cdot Q \cdot \begin{bmatrix}r \\ 1\end{bmatrix} = 0$
-*(Q szimmetrikus)*
-- Metszésparaméter és metszéspont: $t^*$ és $r^*$ hasonlóképpen.
-- Normálvektor: $N = \text{grad}f(r^*) = Q \cdot \begin{bmatrix} r^* \\ 1 \end{bmatrix}$ *első három koordinátája*
-
-
-### Háromszögek, poligonok
-
-
-- Pontjai:
-
- > Először megkeressük, hogy a háromszög síkját hol metszi, majd ellenőrizzük, hogy az adott pont benne van-e a háromszögben.
-
- 1. Síkmetszés:
-
- $(\text{ray}(t) - r1) \cdot n = 0 \qquad (t>0)$
-
- $$\boxed{t = \cfrac{(r1 - \text{start}) \cdot n}{\text{dir} \cdot n}}$$
-
- 2. Belül van-e:
-
- $((r2 r1) \times (\bold{p} r1)) \cdot n > 0$
-
- $((r3 r2) \times (\bold{p} r2)) \cdot n > 0$
-
- $((r1 r3) \times (\bold{p} r3)) \cdot n > 0$
-
-- Normálvektor: $n$ *(vagy shaderrel állítjuk)*
-
-## Render
-
-```py
-for p in pixels:
- ray = getray(eye, pixel)
- color = trace(ray)
- write_pixel(p, color)
-```
-
-### `getray`
-
-
-```js
-p = lookat + a * right + b * up // a, b in [-1, 1] (normalizált eszköz koordináták)
-// ray:
-start = eye
-dir = p - eye
-```
-
-## Rekurzív sugárkövetés
-
-
-> Eddig csak a direkt megvilágítást vizsgáltuk, most belevesszük a tükröződést, fénytörést is.
-
-$L(V) = \begin{cases}
-k_a \cdot L_a + \sum_l {L^\text{in}}_l \cdot \{ k_d \cdot (L_l \cdot N)^+ + k_s \cdot \big((H_l \cdot N)^+\big)^\text{shine} \} \\
-% yeah
-\underbrace{F(V \cdot N)}_{\text{Fresnel}} \cdot \underbrace{L^\text{in}(R)}_{\text{Tükör irányból érkező fény}} + \underbrace{\big(1 - F(V \cdot N)\big)}_{\text{1 - Fresnel}} \cdot \underbrace{L^\text{in}(T)}_{\text{Törési irányból érkező fény}}
-\end{cases}$
-
-
-# Kvíz
-
-> 1\. Az $f(r)=[r, 1] \cdot Q \cdot [r, 1]^T=0$ implicit egyenletű kvadratikus felület és a $ray(t)=s + d \cdot t$ egyenletű sugár metszéspontjához a következő másodfokú egyenletet kell megoldani: $at^2+bt+c=0$.
-Mi lesz a $b$?
-
-*Megoldás:*
-Széttrancsírozzuk...
-
-$
-0 = f(r) = [r, 1] \cdot Q \cdot [r, 1]^T \newline
-0 = [s + d \cdot t, 1] \cdot Q \cdot [s + d \cdot t, 1]^T \newline
-0 = ([s, 1] + t[d, 0]) \cdot Q \cdot ([s, 1] + t[d, 0])^T \newline
-0 = [s,1]Q[s,1]^T + t([s,1]Q[d,0]^T) + t([d,0]Q[s,1]^T) + t^2([d,0]Q[d,0]^T)
-$
-
-Ahol
-
-$b = [s,1]Q[d,0]^T + [d,0]Q[s,1]^T$
-
-És mivel $Q$ szimmetrikus *(nagyon remélem hogy ezért mert tényleg nem értem hogy másképp jön ki xdd)*
-
-$b = 2[s,1]Q[d,0]^T = 2[d,0]Q[s,1]^T$
-
-
----
-> 2\. Egy kvadratikus felület mátrixa az alábbi:
-0, 0, 0, 1
-0, 0, 0, 1
-0, 0, 0, 1
-1, 1, 1, -2
-A felületet sugárkövetéssel jelenítjük meg, a szem az origóban van, a sugár irányvektora az (1, 1, 1).
-Mennyi a kvadratikus felület normálvektorában az x és z komponensek aránya (n.x/n.z) ott, ahol a sugár először metszi a kvadratikus felületet.
-
-*Megoldás (habár triviális):*
-A sugár: $\text{ray}(t) = s + d \cdot t = (0, 0, 0) + (1, 1, 1) \cdot t = (t, t, t)$
-
-A metszéspont:
-$
-0 = (t, t, t, 1)
-\begin{pmatrix}
- 0 & 0 & 0 & 1 \\
- 0 & 0 & 0 & 1 \\
- 0 & 0 & 0 & 1 \\
- 1 & 1 & 1 & -2 \\
-\end{pmatrix}
-(t, t, t, 1)^T
-\\
-...\\
-0 = 6t - 2\\
-t = 1/3\\
-r^* = (\frac 1 3,\frac 1 3,\frac 1 3)
-$
-
-Innen a normálvektor csak hab a tortán:
-$N = \text{grad}f(r^*) = Q[r^*, 1]^T = (1, 1, 1, -1)$
-Tehát az arányuk bosszantóan de kereken $1$.
-
----
-> 3\. A sugár kezdőpontja (0, 0, 0), irányvektora (2,0,0). Hol metszi ez a sugár a (8,0,0) középpontú, 8 sugarú gömböt, pozitív sugárparaméterrel? Válaszként a metszéspont x koordinátáját várjuk.
-
-*Megoldás:*
-Elképzeljük leli szemeink előtt hogy a sugarunk a gömböt a $(0, 0, 0)$ és a $(16, 0, 0)$ pontokban metszi. Az első esetben a sugárparaméter $0$ a feladat viszont pozitívat kér, tehát a válasz $16$.
-
----
-> 4\. A sugár irányvektora (9, 0, 0) és egy (1, 1, 1) középpontú gömb (4, 5, 1) pontját találja el. Milyen irányban halad tovább, ha a gömb optikailag sima, törő, és a gömb anyagának relatív törésmutatója 1.0? Válaszként az egység hosszú irányvektor x komponensét várjuk.
-
-*Megoldás:*
-$1$.
-Mivel a gömb anyagának relatív törésmutatója 1 és a gömb optikailag törő, a törésirány nem változik, tehát a sugár nem hajlik meg. Vagy nem tudom.
-
----
-> 5\. Egy háromszög három csúcsa (8,3,9), (8,3,1), (8,4,2). Hol metszi a (0,0,0) kezdőpontú (1,0,0) irányvektorú sugár a háromszög síkját? A metszéspont x koordinátáját várjuk válaszként.
-
-*Megoldás:*
-Ha bárhol is metszük a háromszöget akkor annak $x$ koordinátája biztosan 8, a többit nem kérdezi.
-Ha szeretnéd az idődet pazarolni akkor síkmetszés + megnézed benne vagy-e.
-
----
-> 6\. A sugár irányvektora (9, 0, 0) és egy (1, 1, 1) középpontú gömb (4, 5, 1) pontját találja el. Milyen irányban halad tovább, ha a gömb optikailag sima, tükröző? Válaszként az egység hosszú irányvektor x komponensét várjuk.
-
-*Megoldás:*
-
-A gömb sugara:
-
-$R = |(4, 5, 1) - (1, 1, 1)| = 5$
-
-A gömb normálvektora:
-
-$N = (\text{ray}(t)-c)/R = ((4, 5, 1) - (1, 1, 1))/5 = (0.6, 0.8, 0)$
-
-Már bizonyára a könyökünkön csöpög, hogy
-
-$n = \cfrac{\sin \theta ^\text{in}}{\sin \theta}$
-
-És mint a jógyerekek normalizáltuk a sugárirányt:
-
-$v = (1, 0, 0)$ *(vagy $d$)*
-
-Kiszámoljuk a visszavert sugarat:
-
-$\cos \alpha = -v \cdot N = -0.6$
-
-$R = v + 2N \cos \alpha$ *(az egyszerűség kedvéért ez egy másik $R$, nem a sugár)*
-
-$R = (1, 0, 0) + 2(0.6, 0.8, 0) \cdot (-0.6) = (0.28, -0.96)$
-
----
-> 7\. Az alábbi osztály egy origó középpontú és axes.x, axes.y, axes.z fél főtengelyhosszú ellipszoidot valósít meg, amelyre a sugár metszéspontszámítást implementáltuk. A vec3-ra az osztást GLSL stílusban, azaz koordinátánként függetlenül valósítottuk meg. Kérjük a hibás sorok sorszámát!
-
-```cpp
-class Ellipsoid : public Intersectable {
- vec3 axes;
-public:
- Hit intersect(const Ray& ray) {
- Hit hit;
-
-1) float a = dot(ray.dir/axes, ray.dir/axes);
-2) float b = dot(ray.start/axes, ray.dir/axes) * 2;
-3) float c = dot(ray.start/axes, ray.start/axes) ;
-4) float discr = b * b - 4 * a * c;
-5) if (discr < 0) return hit; else discr = sqrtf(discr);
-6) float t1 = (-b + discr)/2/a, t2 = (-b - discr)/2/a;
-7) if (t1 <= 0) return hit; // t1 >= t2 for sure
-8) hit.t = (t2 > 0) ? t2 : t1;
-9) hit.position = ray.start + ray.dir * hit.t;
-10) hit.normal = (hit.position - center)/radius;
- hit.material = material;
- return hit;
- }
-};
-```
-*Megoldás:*
-10\. sor, normálist így **csak** a gömbnél számolhatunk.
-
----
-> 8\. Egy $f(r) = r \cdot r - a \cdot r$ implicit egyenletű felületet, ahol $a = (3, 4, 0)$, az $r = (3, 4, 0) $ pontban talált el egy $(9,7,8)$ kezdőpontú sugár . Mi a felület normálvektorában az $x$ és $y$ komponensek aránya a metszéspontban?
-
-*Egoldás:*
-Kisujjból tudunk gradienst számolni már:
-
-$N = \text{grad}f(r) = (2x-3, 2y-4, 2z)$
-
-Ami a $(3, 4, 0)$ pontban:
-
-$N = (3, 4, 0)$
-
-És így nagyon szépen kijön, hogy $0.75$
-
-:cake:
-
-[Előző](./7.md)
-
-[Következő](./9.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/9.md b/docs/notes/sem4/computer_graphics/9.md
deleted file mode 100644
index 7f9708e..0000000
--- a/docs/notes/sem4/computer_graphics/9.md
+++ /dev/null
@@ -1,750 +0,0 @@
-
-
-# Inkrementális 3D képszintézis
-
-> Eddig úgymond pixelvezérelt 3D képszintézissel foglalkoztunk, ez viszont meglehetősen lassú és erőforrásigyényes folyamat.
-
-> $\sim \text{Pixelszám} \times \text{Objektumszám} \times (\text{Fényforrásszám} + 1)$
-
-> Most egy objektumvezérelt irányból fogjuk megközelíteni a dolgot, ennek sokkal egyszerűbb a hardveres implementációja, támogathatósága.
-
-
-
-## Tesszeláció
-
-= felületek háromszögekre bontása
-
-
-
-Magyarázat:
-
-- felület parametrikus egyenletét használjuk
-- paramétertér az egységnégyzet, innen behelyettesíthetünk bármilyen $u, v$ párost a felület egyenletébe
-- kapott pontokat kössük össze háromszögekkel (értelemszerűen úgy, hogy azok a paramétertérben szomszédosak)
-
-$r_{n, m} = r(u_n, v_m)$
-
-Továbbá szükségünk lesz valamilyen normálvektorra is:
-
-- csúcsonként kiszámoljuk a normálvektort
- > az eredmény egy retro/low-poly hatás, jól elkülönülnek a háromszögek, még sima felületeknél is.
- > ha azt szeretnénk, hogy sima legyen:
-- a normálvektorokat később interpoláljuk 
-
-Emléketzető paraméteres felületek normálvektorának kiszámításához *(parciálisan deriváltakat keresztszorozzuk)*:
-
-$N = \cfrac{\partial r(u, v)}{\partial u} \times \cfrac{\partial r(u, v)}{\partial v}$
-
-## Implementáció
-
-
-```cpp
-class Geometry
-{
-protected:
- unsigned int vao, vbo;
-
-public:
- Geometry()
- {
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- glGenBuffers(1, &vbo);
- }
- virtual void Draw() = 0;
- ~Geometry()
- {
- glDeleteBuffers(1, &vbo);
- glDeleteVertexArrays(1, &vao);
- }
-};
-```
-
-```cpp
-class ParamSurface : public Geometry
-{
- unsigned int nVtxStrip, nStrips;
- struct VertexData
- {
- vec3 pos, norm;
- vec2 tex;
- };
- virtual VertexData GenVertexData(float u, float v) = 0;
-
-public:
- void Create(int N, int M);
- void Draw()
- {
- glBindVertexArray(vao);
- for (int i = 0; i < nStrips; i++)
- glDrawArrays(GL_TRIANGLE_STRIP, i * nVtxStrip, nVtxStrip);
- }
-};
-```
-
-```cpp
-void ParamSurface::Create(int N, int M)
-{
- nVtxStrip = (M + 1) * 2;
- nStrips = N;
- vector vtxData; // CPU-n
- for (int i = 0; i < N; i++) for (int j = 0; j <= M; j++)
- {
- vtxData.push_back(GenVertexData((float)j / M, (float)i / N));
- vtxData.push_back(GenVertexData((float)j / M, (float)(i + 1) / N));
- // u // v
- }
- glBindVertexArray(vao);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, vtxData.size() * sizeof(VertexData),
- &vtxData[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0); // AttArr 0 = POSITION
- glEnableVertexAttribArray(1); // AttArr 1 = NORMAL
- glEnableVertexAttribArray(2); // AttArr 2 = UV
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *)offsetof(VertexData, pos));
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *)offsetof(VertexData, norm));
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *)offsetof(VertexData, tex));
-}
-```
-Ez utóbbihoz egy kis magyarázat:
-
-- az első funky for ciklus lehet egy kicsit érdekesebb, mi is történik itt?
- - kigeneráljuk a paramétertér adott sorának és adott oszlopának térbeli pozícióját
- - majd ugyan így a következő sorét
- > miért jó ez?
- > ha sorban haladnánk, abból egymás utáni pontokat kapunk, ezeket nem lenne értelme háromszögként értelmezni
- > ehelyett egy cikk-cakkos *"legyező"* mintát követünk
- > ezt `GL_TRIANGLE_STRIP`-ként *(legyező)* kezelve egyszerűen ki tudjuk rajzolni
- 
-- figyeljük meg hogy a csúcspontok generálásakor egy `VertexData` objektumot kapunk vissza, ez tartalmazza a pozíciót, a normálist, és a textúra (UV) koordinátákat is
-- ki hogy szereti, stride vagy több VBO, Szirmay több VBO-val szereti
-- szét is szedjük 3 külön VBO-ba, a vertexdata megfelelő értékeivel feltöltve
-
-## Transzformációk
-
-(**M** odel) Modellezési transzformáció:
-
-$$
-[r, 1] \bold{T}_\text{Model} = [r_\text{world}, 1] \\
-\bold{T}_\text{Model}^{-1}[N, 0]^T = [N_\text{world}, d]^T
-$$
-
-(**V** iew) Kamera transzformáció:
-
-$$
-[r_\text{world}, 1] \bold{T}_\text{View} = [r_\text{camera}, 1]
-$$
-
-(**P** rojection) Perspektív transzformáció:
-
-$$
-[r_\text{camera}, 1] \bold{T}_\text{Proj} = [r_\text{ndc}w, w]
-$$
-
-**MVP** transzformáció:
-
-> a fenti hármat kiszámolhatjuk egyben is, nem kell csúcspontonként háromszor mátrixszorozni
-
-$$
-\bold{T}_\text{MVP} = \bold{T}_\text{Model} \bold{T}_\text{View} \bold{T}_\text{Proj}
-$$
-
-### Modellezési (Model) transzformáció
-- a pontjaink referenciahelyzetben vannak meg
-- Descartes koordinátákat át kell váltanunk homogén koordinátákba
-- kell egy mátrix ami
- 1. skálázza
- 2. elforgatja
- 3. eltolja
-
- az alakzatot
-
-1. skálázás
- $s_x, s_y, s_z$-vel való átméretezés
- $$
- \begin{bmatrix}
- s_x & 0 & 0 & 0 \newline
- 0 & s_y & 0 & 0 \newline
- 0 & 0 & s_z & 0 \newline
- 0 & 0 & 0 & 1 \newline
- \end{bmatrix}
- $$
-
-2. orientáció
- $d$ egységvektor körül $\varphi$ szöggel való forgatás *(tehát $d$ lesz a forgás tengelye)*
- $$
- \begin{bmatrix}
- i_x & i_y & i_z & 0\newline
- j_x & j_y & j_z & 0\newline
- k_x & k_y & k_z & 0\newline
- 0 & 0 & 0 & 1\newline
- \end{bmatrix}
- $$
- $i, j, k$ vektorokat úgy kapjuk meg, hogy a hozzájuk tartozó bázisvektorokra alkalmazzuk az alábbi képletet:
-
- $$r' = r \cos(\varphi) + d(r \cdot d) (1 - \cos(\varphi)) + (d \times r) \sin(\varphi)$$
-
-3. pozíció
- $v_x, v_y, v_z$-vel való eltolás
- $$
- \begin{bmatrix}
- 1 & 0 & 0 & 0\newline
- 0 & 1 & 0 & 0\newline
- 0 & 0 & 1 & 0\newline
- v_x & v_y & v_z & 1\newline
- \end{bmatrix}
- $$
-
-- tehát a modellezési transzformáció mátrixunk a
- $$
- \bold{T}_\text{M} =
- \begin{bmatrix}
- s_x & 0 & 0 & 0\newline
- 0 & s_y & 0 & 0\newline
- 0 & 0 & s_z & 0\newline
- 0 & 0 & 0 & 1\newline
- \end{bmatrix}
- \begin{bmatrix}
- i_x & i_y & i_z & 0\newline
- j_x & j_y & j_z & 0\newline
- k_x & k_y & k_z & 0\newline
- 0 & 0 & 0 & 1\newline
- \end{bmatrix}
- \begin{bmatrix}
- 1 & 0 & 0 & 0\newline
- 0 & 1 & 0 & 0\newline
- 0 & 0 & 1 & 0\newline
- v_x & v_y & v_z & 1\newline
- \end{bmatrix}
- $$
- $4 \times 4$-es mátrix lesz
-
-- normálvektorhoz a mátrix inverzével szorozzuk a normál vektor transzponáltját
-
-### Kamera (View) transzformáció
-
-> eltolás, elforgatás, annak érdekében, úgy, hogy a kameránk legyen az origó(ban) és a $-z$ irányba nézzen (affin)
-
-
-
-- ${e}$: eye - szem pozíciója
-- $\text{lookat}$: ide nézünk, a nézetünk/képernyő téglalap középpontja
-- $\text{vup}$: a függőlegesen felfelének tekintett irány
-- $\text{fov}$: field of view = látószög
-- $\text{asp}$: aspect = képarány (vízszintes $\ratio$ függőleges)
-- $\text{fp, bp}$: front plane, back plane = első és hátsó vágósík, ami ezeken kívül esik azokat figyelmen kívül hagyjuk
-
-
-> *van egy ilyen ábra is hurrá, nem teljesen sikerült értelmezni de:*
-
-a különböző terek, koordináta rendszerek, sorban
-
-E modell szerinti kamera (view) transzformációs mátrix tehát:
-
-
-
-$w = (e - \text{lookat})/|e-\text{lookat}|$ *(leosztunk a hosszával avagy normalizáljuk)*
-
-$u = (\text{vup} \times w)/|\text{vup} \times w|$ *(úgyszintén)*
-
-$v = w \times u$
-
-$$
-\bold{T}_V =
-\begin{bmatrix}
-1 & 0 & 0 & 0\newline
-0 & 1 & 0 & 0\newline
-0 & 0 & 1 & 0\newline
--e_x & -e_y & -e_z & 1\newline
-\end{bmatrix}
-\begin{bmatrix}
-u_x & u_y & u_z & 0\newline
-v_x & v_y & v_z & 0\newline
-w_x & w_y & w_z & 0\newline
-0 & 0 & 0 & 1\newline
-\end{bmatrix}^{-1}
-$$
-> invertálás: a mátrixunk egy ortonormál mátrix (ahol a sorok egységvektorok és egymásra merőlegesek)
-> ilyen mátrix inverze a saját transzponáltja
-
-### Perspektív (Projection) transzformáció:
-
-Látószög normalizálás:
-
-$$
-\begin{bmatrix}
-\cfrac 1 {\tan(\frac {\text{fov}} 2 ) \cdot \text{asp}} & 0 & 0 & 0\newline
-0 & \cfrac 1 {\tan(\frac {\text{fov}} 2 )} & 0 & 0\newline
-0 & 0 & 1 & 0\newline
-0 & 0 & 0 & 1\newline
-\end{bmatrix}
-$$
-> Miért jó ez? Ezzel skálázzuk a nézetet hogy stimmeljen a látószög (itt 90°) és a képarány.
-
-Perspektíva:
-
-
-> A sugaraink jelenleg mind a kamerából indulnak, így viszont torz képet kapnánk. Ha azt szeretnénk, hogy tényleg pespektívának tűnjön, ahhoz párhuzamos sugarak kellenek.
-
-Kis emlékeztető (egyenes egyenlete): $y = m \cdot x + b$
-
-Origón átmenő: $y = m \cdot x$
-
-Vízszintes: $y = b$
-
-$(-m_x z, -m_y z, z)$ -ből kell tehát valahogyan $(m_x, m_y, z^*)$-ot előállítani
-
-Homogén koordinátákkal ez úgy néz ki, hogy:
-
-$[-m_x z, -m_y z, z, 1] \rightarrow [-m_x, -m_y, z^*, 1] \sim [-m_x z, -m_y z, -zz^*, -z]$
-
-Ezt valamilyen
-
-$$
-\begin{bmatrix}
-1 & 0 & 0 & 0\newline
-0 & 1 & 0 & 0\newline
-0 & 0 & \alpha & -1\newline
-0 & 0 & \beta & 0\newline
-\end{bmatrix}
-$$
-
-mátrixszal tudnák elérni.
-
-Keressük tehát $\alpha$-t és $\beta$-t:
-
-$-zz^* = \alpha z + \beta \rightarrow z^* = -\alpha -\beta / z$
-
-Ábrán is látszik, hogy $-fp$-t tekintjük majd $-1$-nek, $-bp$-t pedig $1$-nek.
-
-Felírhatjuk ezeket egyenletekként:
-
-$-1 = \alpha \cdot (-fp) + \beta$
-
-$ 1 = \alpha \cdot (-bp) + \beta$
-
-Átrendezve pedig kijön, hogy
-
-$\alpha = \cfrac{(fp+bp)}{bpfp}$
-
-$\beta = \cfrac{2fp \cdot bp}{bpfp}$
-
-Helyettesítsük be és szorozzuk meg a látószög normalizáláshoz használt mátrixszal:
-
-$$
-\bold{T}_P =
-\begin{bmatrix}
-\frac 1 {\tan(\frac {\text{fov}} 2 )\text{asp}} & 0 & 0 & 0\newline
-0 & \frac 1 {\tan(\frac {\text{fov}} 2 )} & 0 & 0\newline
-0 & 0 & \frac{(fp+bp)}{bp - fp} & -1\newline
-0 & 0 & \frac{2fp \cdot bp}{bp - fp} & 0\newline
-\end{bmatrix}
-$$
-
-Tömör gyönyör :3c
-
-### Z-fighting
-
-$z^*$ nem lineáris függvénye a $z$-nek, távolban lévő pontokról nem tudjuk eldönteni, hogy melyik van közelebb.
-
-**$\cfrac{fp}{bp}$ nem lehet kicsi!**
-
-
-
-Perspektív torzítás = homogén osztás
-
-$(x^*, y^*, z^*) = (X/w, Y/w, Z/w) \qquad \boxed{w = z_c}$
-
-($z_c$: kamera szerinti koordináta)
-
-
-## Implementáció
-### Camera osztály
-```cpp
-class Camera
-{
- vec3 wEye, wLookat, wVup; // extrinsic parameters
- float fov, asp, fp, bp; // intrinsic parameters
-public:
- mat4 V()
- { // view matrix
- vec3 w = normalize(wEye - wLookat);
- vec3 u = normalize(cross(wVup, w));
- vec3 v = cross(w, u);
- return TranslateMatrix(-wEye) * mat4(u.x, v.x, w.x, 0,
- u.y, v.y, w.y, 0,
- u.z, v.z, w.z, 0,
- 0, 0, 0, 1);
- }
- mat4 P()
- { // projection matrix
- float sy = 1 / tanf(fov / 2);
- return mat4(sy / asp, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, -(fp + bp) / (bp - fp), -1,
- 0, 0, -2 * fp * bp / (bp - fp), 0);
- }
-};
-```
-
-## Transzformációk előkészítése a GPU-n
-```cpp
-void Draw()
-{
- mat4 M = ScaleMatrix(scale) *
- RotationMatrix(rotAng, rotAxis) *
- TranslateMatrix(pos);
- mat4 Minv = TranslateMatrix(-pos) *
- RotationMatrix(-rotAngle, rotAxis) *
- ScaleMatrix(1 / scale);
- mat4 MVP = M * camera.V() * camera.P();
- shader->setUniform(M, "M"); //
- shader->setUniform(Minv, "Minv"); // GPU változóinak állítása
- shader->setUniform(MVP, "MVP"); //
- glBindVertexArray(vao);
- glDrawArrays(...);
-}
-```
-
-A hozzá tartozó csúcspontárnyaló (vertex shader)
-```c
-uniform mat4 M, Minv, MVP;
-layout(location = 0) in vec3 vtxPos;
-layout(location = 1) in vec3 vtxNorm;
-out vec4 color;
-void main()
-{
- gl_Position = vec4(vtxPos, 1) * MVP;
- vec4 wPos = vec4(vtxPos, 1) * M;
- vec4 wNormal = Minv * vec4(vtxNorm, 0);
- color = Illumination(wPos, wNormal);
-}
-```
-
-## Vágás
-> Mit látok? Normalizáltunk mindent is, minden tengelyen a $(-1, 1)$ intervallumot kell csak figyelembe vennem, hogy jó legyen.
-
-A normalizált eszközkoordinátarendszerben, homogén koordinátákkal:
-
-$$
--1 < X/w < 1 \\
--1 < Y/w < 1 \\
--1 < Z/w < 1 \\
-\text{és}\\
-\boxed{w = - z_c \quad (w > 0)}\\
-\Downarrow \\
--w < X < w \\
--w < Y < w \\
--w < Z < w \\
-$$
-
-## Viewport transzformáció
-Normalizáltból (NDC) képernyőkoordinátákba:
-
-
-
-*$\text{Magyarázat: ...}$*
-
-## Transzformációs csővezeték
-Az egyes transzformációkat külön a CPU-n:
-
-- MVP
-- Modell
-- Modell-inverz
-
-Ezeket átadjuk a csúcspontárnyalónak.
-Vágás homogén koordinátákban, utána visszatérhetünk Descartes koordinátákba.
-
-## Takarás
-
-
-Képernyő koordinátarendszerben
-
-- sugarak a $z$ tengyellyel párhuzamosak tehát
-- sugárparaméter = $z$ koordináta
-- $(x, y, z)$ pont az $(x, y)$ pixelben látszik
-
-> Az alapján, hogy hogyan határozzuk meg, hogy mi látszik közelebb beszélhetünk:
-
-Objektumtér algoritmusok (folytonos):
-
-- láthatóságfelbontás nem függ a felbontástól
-
-Képtér algoritmusok (diszkrét):
-
-- mi látszik a pixelben?
-- pl. sugárkövetésnél
-
-## Backface culling (hátsólap eldobás)
-> tldr: azon háromszögeket amik nem felénk néznek, azt fogjuk csinálni amit a tárgy okozta fájdalmainkkal: ignoráljuk
-
-
-> *Fun fact: óramutató járásával megegyeznek a pontok, ezért van r3 és r2 más sorrendben.*
-
-Nem felénk néző háromszögeket eldobjuk.
-Felénk néz, ha $n_z < 0$
-
-Feltételezés: kívülről általában a csúcsok óramutatóval megegyező körüljárásúak
-
-
-## Z-buffer
-
-
-- objektumcentrikus
-- a pixelek sugárparamétereit *(azaz $z$ koordinátáit, ezért z-buffer)* egy tömbben tartjuk nyilván
-- ezt minimum kereséshez fogjuk használni, tehát maximális mélységűre ($1$-re) fogjuk inicializálni
-- háromszögeket egyesével meglátogatjuk és jó prog1-et végzett hallgató módjára ha kisebbek vagyunk a minimumnál akkor felülírjuk stb.
-
-### Lineáris interpoláció
-
-
-Minden egyes soron, azon belül az oszlopain végiglépegetünk, és kiszámoljuk $z$-t. Ez költséges művelet, amit úgy tudunk felgyorsítani, hogy kiszámoljuk a sor első $z$ koordinátáját, majd a következő cellánál ezt az eredményt felhasználjuk, hozzáadunk egy $a$ értéket. $a$ megadja, hogy egy pixelt az $x$ irányba lépve $z$ mennyit változik *(kvázi meredekség)*. Ezt azért tehetjük meg mert a háromszög felülete lapos, $z$ lineárisan változik.
-
-Tehát $a = \cfrac{-n_x}{n_z}$
-
-## Takarás OpenGL-ben
-```cpp
-int main(int argc, char *argv[])
-{
- ...
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
- glEnable(GL_DEPTH_TEST); // z-buffer is on
- glDisable(GL_CULL_FACE); // backface culling is off
- ...
-}
-```
-
-## Árnyalás
-### Lokális illumináció árnyék nélkül
-Röhögve tudjuk már a képletet fejből, hogy:
-
-$L(V) \approx \sum_l {L^\text{in}}_l \cdot f_r(L_l, N, V) \cdot \cos^+ {\theta^\text{in}}_l$
-
-Nade ezt mégse kéne pixelenként (lassú).
-
-- csúcspontonként: csúcspontokon belül az $L$ "szín" interpolációja
- > Gouraud árnyalás (per-vertex shading)
-
-- Pixelenként: belül a normál vektort interpoláljuk:
- > Phong árnyalás (per-pixel shading)
-
-### Gouraud árnyalás
-
-
-> yadda yadda megszokott módon csúcsokra kiszámoljuk, okos diák módjára tudjuk már hogy kell jól interpolálni stb stb, DE
-
-Sok sebből vérzik:
-
-- anyagtulajdonság konstans
-- árnyék nincs *(nem tudna különben színt interpolálni)*
-- durva tesszcelláció mellet csúnya a spekuláris *(a komponens huplija elveszhet, mert a függvény erősen nem lináris)*
-
-Vertex shader:
-```c
-uniform mat4 MVP, M, Minv; // MVP, Model, Model-inverse
-uniform vec4 kd, ks, ka; // diffuse, specular, ambient ref
-uniform float shine; // shininess for specular ref
-uniform vec4 La, Le; // ambient and point sources
-uniform vec4 wLiPos; // pos of light source in world
-uniform vec3 wEye; // pos of eye in world
-layout(location = 0) in vec3 vtxPos; // pos in modeling space
-layout(location = 1) in vec3 vtxNorm; // normal in modeling space
-out vec4 color; // computed vertex color
-void main()
-{
- gl_Position = vec4(vtxPos, 1) * MVP; // to NDC
- vec4 wPos = vec4(vtxPos, 1) * M;
- vec3 L = normalize(wLiPos.xyz * wPos.w - wPos.xyz * wLiPos.w);
- vec3 V = normalize(wEye - wPos.xyz / wPos.w);
- vec4 wNormal = Minv * vec4(vtxNorm, 0);
- vec3 N = normalize(wNormal.xyz);
- vec3 H = normalize(L + V);
- float cost = max(dot(N, L), 0), cosd = max(dot(N, H), 0);
- color = ka * La + (kd * cost + ks * pow(cosd, shine)) * Le;
-}
-```
-Pixel shader:
-```c
-in vec4 color; // interpolated color of vertex shader
-out vec4 fragmentColor; // output goes to frame buffer
-void main()
-{
- fragmentColor = color;
-}
-```
-
-### Phong árnyalás
-> hasonló a történet
-
-
-
-- csúcspontokban tehát tudjuk a tulajdonságait
-- belső pixelenként elvégezzük a vektorok lineáris interpolációját
-- nem felejtük el normalizálni a interpolációval kapott vektorokat, hogy egység hosszúak legyenek *(ugyanis ez nem garantált)*
-
-Vertex shader:
-```c
-uniform mat4 MVP, M, Minv; // MVP, Model, Model-inverse
-uniform vec4 wLiPos; // pos of light source
-uniform vec3 wEye; // pos of eye
-layout(location = 0) in vec3 vtxPos; // pos in model sp
-layout(location = 1) in vec3 vtxNorm; // normal in model sp
-out vec3 wNormal; // normal in world space
-out vec3 wView; // view in world space
-out vec3 wLight; // light dir in world space
-void main()
-{
- gl_Position = vec4(vtxPos, 1) * MVP; // to NDC
- vec4 wPos = vec4(vtxPos, 1) * M;
- wLight = wLiPos.xyz * wPos.w - wPos.xyz * wLiPos.w;
- wView = wEye - wPos.xyz / wPos.w;
- wNormal = (Minv * vec4(vtxNorm, 0)).xyz;
-}
-```
-Pixel shader:
-```c
-uniform vec3 kd, ks, ka; // diffuse, specular, ambient ref
-uniform float shine; // shininess for specular ref
-uniform vec3 La, Le; // ambient and dir/point source rad
-in vec3 wNormal; // interpolated world sp normal
-in vec3 wView; // interpolated world sp view
-in vec3 wLight; // interpolated world sp illum dir
-out vec4 fragmentColor; // output goes to frame buffer
-void main()
-{
- vec3 N = normalize(wNormal);
- vec3 V = normalize(wView);
- vec3 L = normalize(wLight);
- vec3 H = normalize(L + V);
- float cost = max(dot(N, L), 0), cosd = max(dot(N, H), 0);
- vec3 color = ka * La + (kd * cost + ks * pow(cosd, shine)) * Le;
- fragmentColor = vec4(color, 1);
-}
-```
-
-## 2D textúrázás ismét
-
-
-Ez történik ha linárisan interpoláljuk a textúrát.
-
-> nem követi a perspektívát
-> oké de akkor hogy csináljuk jól?
-
-Kiszámoljuk az affin transzformációt a 2D és a 3D háromszög között, ennek az inverzével meg tudjuk határozni a pixel pozícióját textúratérben.
-
-## Inkrementális képszintézis csővezeték
-Azért transzformáltunk, hogy a láthatósági feladatot és a vetítést képernyő koordináta-rendszerben oldhassuk meg
-
-- Triviális hátsó lap eldobás
-- Z-buffer algoritmus
-- Vetítés = z eldobása, 3D háromszög = 2D háromszög
-
-Per-pixel árnyalás:
-
-- Vektorokat csúcspontonként számítjuk és pixelekre interpoláljuk
-- Illuminációs képlet pixelenként
-
-
-
-# Kvíz
-> 1\. A parametrikus felület tesszellációjánál a egységnégyzet paraméter tartományban 8x8 pontot vettünk fel szabályos rácsban. A felületet GL_TRIANGLES típussal jelentíjük meg. Hány csúcspontból fog állni a VBO.
-
-*Megoldás:*
-
-Vigyázunk hogy cselesen `GL_TRIANGLES`-t kér. Tehát háromszögenként 3 csúcs.
-
-$8 \times 8$ **pont** rács, elképzelhetjük egy $7 \times 7$-es táblázatként, cellánként $2$ háromszög, háromszögenként $3$ csúcs, azaz
-
-$7 \cdot 7 \cdot 2 \cdot 3 = 294$
-
----
-> 2\. Egy paraméteres felület:
-$$
-x(u,v)=3u+6.7v+3uv \newline
-y(u,v)=6.5u+6.7v+3 uv \newline
-z(u,v)=1.3u+6.7v+3 uv \newline
-$$
-Mekkora az nx/nz, azaz a normálvektor x és z komponensének aránya az (u,v)=(1,1) pontban?
-
-*Megoldás:*
-
-Meglátjuk, hogy paraméteres, és mint az őrült nekiállunk parciálisan deriválni:
-
-$x(u, v)$:
-$$
-\cfrac{\partial x}{\partial u} = 3 + 3v\\ ~\\
-\cfrac{\partial x}{\partial v} = 6.7 + 3u\\
-$$
-$y(u, v)$:
-$$
-\cfrac{\partial y}{\partial u} = 6.5 + 3v\\ ~\\
-\cfrac{\partial y}{\partial v} = 6.7 + 3u\\
-$$
-$z(u, v)$:
-$$
-\cfrac{\partial z}{\partial u} = 1.3 + 3v\\~\\
-\cfrac{\partial z}{\partial v} = 6.7 + 3u\\
-$$
-
-Emlékszünk, hogy
-
-$N = \cfrac{\partial r(u, v)}{\partial u} \times \cfrac{\partial r(u, v)}{\partial v}$
-
-Ez pedig nem más, mint
-
-$$N =
-\bigg(
- \cfrac{\partial x}{\partial u}\bigg|_{(1, 1)},
- \cfrac{\partial y}{\partial u}\bigg|_{(1, 1)},
- \cfrac{\partial z}{\partial u}\bigg|_{(1, 1)}
-\bigg)
-\times
-\bigg(
- \cfrac{\partial x}{\partial v}\bigg|_{(1, 1)},
- \cfrac{\partial y}{\partial v}\bigg|_{(1, 1)},
- \cfrac{\partial z}{\partial v}\bigg|_{(1, 1)}
-\bigg)
-\\~\\
-= (6, 9.5, 4.3) \times (9.7, 9.7, 9.7) = (50.44, -16.49, -33.95)
-$$
-
-Tehát az arányuk
-$\cfrac{n_x}{n_y} = \cfrac{50.44}{-33.95} = -1.485$
-
-
----
-> 3\. A parametrikus felület tesszellációjánál a egységnégyzet paraméter tartományban 7x7 pontot vettünk fel szabályos rácsban. A felületet GL_TRIANGLE_STRIP típussal jelentíjük meg. Hány csúcspontból fog állni a VBO.
-
-*Megoldás:*
-
-Itt `GL_TRIANGLE_STRIP`-ben kéri.
-
-Ezt legjobban a példakód magyarázza el.
-
-$7 \times 7$ pontunk van, $6$ sor $7$ pont**páros**án megyünk végig, azaz $6 \cdot 7 \cdot 2 = 84$ pontunk lesz a VBO-ban.
-
----
-> 4\. Egy háromszög három csúcsa képernyő koordinátarendszerben:
- (13, 67, 0.6)
- (56, 80, 0.7)
- (78, 13, 0.9)
-
-> Mennyivel változik a z koordináta, amikor a kitöltés során egy pixelről a jobboldali szomszéd pixelre lépünk?
-
-*Megoldás:*
-
-Interpolálni mindenki tud ügyebár, ki kell számolnunk az $a$ értékét.
-
-Előtte viszont szükségünk van a normálvektorra. Ez háromszögeknél:
-
-$n = (r3 - r1) \times (r2 - r1) = (65, -54, 0.3) \times (43, 13, 0.1) = (-9.3, 6.4, 3167)$
-
-$a$ pedig nem más, mint
-
-$a = \cfrac{-n_x}{n_z} = \cfrac{9.3}{3167} = 0.003$
-
-:people_hugging:
-
-[Előző](./8.md)
-
-[Következő](./10.md)
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/appendix/math_appendix.md b/docs/notes/sem4/computer_graphics/appendix/math_appendix.md
new file mode 100644
index 0000000..a708149
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/appendix/math_appendix.md
@@ -0,0 +1,264 @@
+# Matematikai kifejezések
+
+A jegyzetben sok matematikai kifejezéssel találkozhatunk, melyeknek egy részét a tárgy már feltételezi, hogy mindenki ismeri. Ebben a függelékben megpróbáljuk definiálni a legtöbb ilyen kifejezést, illetve egy példát adni rájuk.
+
+## Műveleti tulajdonságok
+
+### Asszociativitás
+
+!!! info Definíció
+ Egy (kétváltozós) műveletre (legyen most $\ast$) akkor mondjuk, hogy asszociatív, ha "nem számít az elvégzésének sorrendje", azaz szabadon zárójelezhető:
+
+ $$
+ (u * v) * w = u * (v * w) = u * v * w
+ $$
+
+Ha egy művelet _nem_ asszociatív, akkor az azt jelenti, hogy $(u * v) * w \neq u * (v * w)$. Egy példa egy nem asszociatív műveletre az osztás:
+
+$$
+\frac{1}{6} = \frac{\frac{1}{2}}{3} = \underbrace{(1/2)/3 \neq 1/(2/3)}_{
+ \footnotesize (u * v) * w \neq u * (v * w)
+} = \frac{1}{\frac{2}{3}} = \frac{3}{2}
+$$
+
+### Kommutativitás
+
+!!! info Definíció
+ Egy (kétváltozós) műveletre (legyen most $\ast$) akkor mondjuk, hogy kommutatív, ha "nem számít az operandusok sorrendje", azaz:
+
+ $$
+ u * v = v * u
+ $$
+
+Ha egy művelet _nem_ kommutatív (antikommutatív), akkor az azt jelenti, hogy $u * v \neq v * u$. Egy példa egy nem kommutatív műveletre az kivonás:
+
+$$
+-1 = \underbrace{1 - 2 \neq 2 - 1}_{
+ \footnotesize u * v \neq v * u
+} = 1
+$$
+
+### Disztributivitás
+
+Ez a fogalom már egy picit összetettebb, hiszen itt már két különböző műveletünk is van.
+
+!!! info Definíció
+ Két (kétváltozós) művelet (legyen most $+$ és $\ast$) esetén akkor mondjuk, hogy a $\ast$ művelet disztributív a $+$ műveletre nézve, ha "felbonthatjuk a zárójelet", azaz:
+
+ $$
+ c * (a + b) = (c * a) + (c * b)
+ $$
+
+Fontos, hogy az, hogy "az $\ast$ művelet disztributív a $+$ műveletre nézve" nem jelenti azt, hogy "az $+$ művelet disztributív az $\ast$ műveletre nézve". Ezt könnyen láthatjuk, hogy az összeadás és szorzás műveleteit nézzük:
+
+$$
+25 = 5 * 5 = \underbrace{5 * (2 + 3) = (5 * 2) + (5 * 3)}_{c * (a + b) = (c * a) + (c * b)} = 10 + 15 = 25
+$$
+
+a fenti azt demonstrálja, hogy az $\ast$ művelet disztributív a $+$ műveletre nézve, viszont ha megcserélnénk a műveleteket:
+
+$$
+11 = 5 + 6 = \underbrace{5 + (2 * 3) \neq (5 + 2) * (5 + 3)}_{c + (a * b) \neq (c + a) * (c + b)} = 7 * 8 = 56
+$$
+
+### Skálázhatóság
+
+Elsősorban vektorok esetén beszélünk róla.
+
+
+!!! info Definíció
+ Egy műveletre (legyen most $\ast$) akkor mondjuk, hogy skálázható, ha $a, b \in \R^n$ és $s \in \R$ esetén:
+
+ $$
+ sa \ast b = s(a \ast b)
+ $$
+
+ tehát a skálázást "kiemelhetjük", és elvégezhetjük az $\ast$ művelet eredményére is.
+
+Egy példa erre a jegyzetben is említett skaláris szorzás.
+
+## Kombinatorika
+
+### Binomiális tétel
+
+!!! info Tétel
+ Két, $a, b \in \R$ és $n \in \N$ esetén:
+
+ $$
+ (a + b)^n = \sum_{k=0}^{n} \binom{n}{k} \cdot a^{n-k} \cdot b^{k}
+ $$
+
+ ahol a $\binom{n}{k}$ binomiális együtthatót a következő képpen számoljuk:
+
+ $$
+ \binom{n}{k} = \frac{n^k}{k! (n-k)!}
+ $$
+
+ ahol $n!$ az n szám faktoriálisát jelenti.
+
+Tehát például $n=2$-re:
+
+$$
+(x + y)(x + y) = x^2 + 2xy + y^2
+$$
+
+a binomiális tételt felhasználva is eljuthatunk ide:
+
+$$
+\begin{align*}
+(x + y)^2 &= \sum_{k=0}^{2} \binom{2}{k} \cdot x^{2 - k} \cdot y^{k} \\
+&= \binom{2}{0} \cdot x^{2} \cdot y^{0} + \binom{2}{1} \cdot x^{1} \cdot y^{1} + \binom{2}{2} \cdot x^{0} \cdot y^{2} \\
+&= x^2 + 2xy + y^2
+\end{align*}
+$$
+
+## Függvénytulajdonságok
+
+### Folytonosság
+
+
+!!! info Definíció (egyszerűsített...)
+ Az $f$ függvény folytonos az $a$ pontban, ha
+
+ $$
+ \forall \varepsilon \in \R^{+} \; \exists \delta \in \R^{+} \; \forall x \in \text{Dom}(f) : \big( |x - a| < \delta \implies |f(x) - f(a)| < \varepsilon \big)
+ $$
+
+ Az $f$ függvény _folytonos_, ha az értelmezési tartományának összes pontjában folytonos.
+
+A jegyzetben találkozhatunk $C^1$ és $C^2$ folytonossággal. Azokat az $f$ függvényeket, amelyek a fenti definíciónak eleget tesznek $C^0$ folytonosnak nevezzük. Egy függvényt $C^n$ folytonosnak nevezünk, ha az $n$. deriváltja is folytonos, azaz $f^{(n)}$ folytonos.
+
+Például vegyük az $f: x \mapsto x^2 + 2$ függvényt. [Belátható](https://cdn.discordapp.com/emojis/1394642603701571605.webp?size=240), hogy $C^0$ folytonos. Nézzük a deriváltjait:
+
+$$
+\begin{align*}
+f'(x) &= 2x \\
+f''(x) &= 2 \\
+f'''(x) &= 0 \\
+&\vdots
+\end{align*}
+$$
+
+láthatjuk, hogy itt $f$ összes deriváltja továbbra is folytonos, hogy tehát $f$-re igaz az, hogy $C^1$ vagy éppen $C^2$ folytonos.
+
+Nézhetünk egy ellenpéldát is. Legyen $g(x) = \begin{cases} x^2 &\text{ha } x \gt 0 \\ 0 &\text{ha } x \le 0 \end{cases}$. Ez persze $C^0$ folytonos, de ha kétszer deriváljuk, akkor azt kapjuk, hogy:
+
+$$
+g''(x) = \begin{cases} 2 &\text{ha } x \gt 0 \\ 0 &\text{ha } x \le 0 \end{cases}
+$$
+
+ami már nem egy folytonos függvény, tehát $g$ nem $C^2$ folytonos.
+
+## Absztrakt algebra
+
+### Gyűrűk, testek, csoportok, stb...
+
+(Az alábbi egy egyszerűsítés, akit mélyebben érdekel a téma annak ajánlok pár félévet az [ELTE Matematika BSc. képzésén](https://ttk.elte.hu/content/matematika-bsc.t.7680))
+
+Az absztrakt algebrában elkezdünk elmozdulni a hétköznapi, megszokott rendszerekben való számolásoktól, és inkább magukkal a _rendszerekkel_ akarunk foglalkozni. Sok ezer évig nagyon sok dolgot magától értetődőnek vettek a matematikusok. Ha megkérdeznéd Euklidészt, vagy akár Newtont, akkor nekik valószínűleg gőzük sem lenne ahhoz, hogy mi az a "kommutativitás". Persze tudják, hogy $2 + 1 = 1 + 2$, és hogy $2 - 1 \neq 1 - 2$, hiszen ez "egyértelmű", de ha megkérdeznéd, hogy miért van ez így, akkor ők is csak megvonnák a vállukat.
+
+A huszadik század eleje felé a matematikusokat elkezdte érdekelni, hogy "oké, de most komolyan, miért tudom megcserélni a tényezőkeg az összeadásnál, de a kivonásnál nem?", és még fontosabban "mi lenne, ha mégis meg tudnám?". Nagyon sok áttörés született ebben a korban, az absztrakt algebrán kívül a [halmazelmélet](https://en.wikipedia.org/wiki/Zermelo%E2%80%93Fraenkel_set_theory) pontos definíciója, a [matematikai logika](https://en.wikipedia.org/wiki/Mathematical_logic), [topológia](https://hu.wikipedia.org/wiki/Topol%C3%B3gia), azon belül is a [mértékelmélet](https://hu.wikipedia.org/wiki/M%C3%A9rt%C3%A9k_(matematika)), mind ekkor jöttek létre.
+
+Nézzünk egy példát a gyűrű fogalmára:
+
+!!! example Gyűrű
+ Az egész számok $\Z$ halmaza az összeadás ($+$) és szorzás ($\ast$) műveletekkel egy gyűrűt alkot.
+
+Igen, tényleg csak ennyi! Ha fogod az egész számok halmazát, és az általános iskolában tanult összeadás és szorzás műveleteket értelmezed rajta, az egy gyűrű! Nézzük meg pontosabban is:
+
+!!! info Definíció
+ Egy $R$ halmazt, két bináris művelettel ($+$, $\ast$) felszerelve egy _gyűrűnek_ nevezünk, ha betartja a _gyűrű axiómákat:_
+
+ 1. $R$ az $+$ művelettel együtt egy _Ábel-csoportot_ alkot, ami azt jelenti, hogy:
+ - Az $+$ asszociatív $R$-ben.
+ - Az $+$ kommutatív $R$-ben.
+ - Létezik olyan $0 \in R$, hogy $a + 0 = a$ minden $a \in R$. (additív identitás)
+ - Minden $a \in R$-re létezik egy $-a \in R$, melyekre igaz, hogy $a + (-a) = 0$. (additív inverz)
+ 2. $R$ a $\ast$ művelettel együtt egy _[Monoid](math_appendix.md#monoid)_, ami azt jelenti, hogy:
+ - A $\ast$ művelet asszociatív $R$-ben.
+ - Létezik olyan $1 \in R$, hogy $1 \ast a = a \ast 1 = a$ minden $a \in R$. (multiplikatív identitás)
+ 3. A $\ast$ művelet disztributív a $+$ műveletre nézve.
+
+Ezeknek a nagy részére az lehet a reakciónk, hogy "hát persze, ez nem triviális?", és igazunk is lenne, hiszen több ezer évbe telt, mire a matematikusoknak eszébe jutott, hogy ezeket meg kéne fogalmazni, és össze kéne szedni egy listába.
+
+Léteznek további kibővítések is, például a _kommutatív gyűrű_ egy olyan gyűrű, ahol a $\ast$ művelet is kommutatív. A fent említett egész számok halmaza is egy kommutatív gyűrűt alkot.
+
+A jegyzetben amikor gyűrűkről van szó, akkor általában magától értetődő, vagy "megszokott" műveleti tulajdonságokról beszélünk, amiket éppen most soroltunk fel pontosan.
+
+A test (angolul _field_) fogalma is nagyon hasonló mint a gyűrűnek, csak még több "triviális" tulajdonságot köt meg. Vegyük észre például, hogy a fenti gyűrű definíciónkkal nem tudnánk a racionális számok halmazát definiálni. Nem köti meg, hogy kell léteznie multiplikatív inverzeknek, tehát nem tudnánk például definiálni az $1/2$-edet. A testek pont ezért lényegében egy olyan gyűrűk, ahol a $0$-tól különböző elemeknek van multiplikatív inverze. Precízebben a _test axiómák_ határozzák meg, hogy mi egy test, melyeket itt nem sorolnék fel, de online sok helyen elérhetőek[.](https://en.wikipedia.org/wiki/Field_(mathematics)#Classic_definition)
+
+### Monoid
+
+Ez a kifejezés bár nem szerepel a jegyzetben, de nagyon sok relevanciája van az informatika világában is, szóval röviden megemlítem.
+
+A [gyűrű axiómáknál](math_appendix.md#gyűrűk-testek-csoportok-stb) már meg volt említve a Monoid:
+
+!!! info Definíció
+ Egy $S$ halmaz egy $\ast$ bináris operátorral együtt egy _Monoidot_ alkot, ha az alábbi két axiómának eleget tesznek:
+
+ 1. A $\ast$ művelet asszociatív $S$-ben.
+ 2. Létezik olyan $e \in S$, melyre $a \ast s = s \ast a = a$ igaz minden $a$-ra $S$-ből.
+
+Első ránézésre semmi köze sincs a programozáshoz, viszont a _funkcionális programozás_ világában egy eléggé fontos fogalom. Vegyük példának a "lista" fogalmát (láncolt lista). Ez vajon egy monoid? Legyen $L$ az összes lista halmaza. Ekkor például `[1,2,3]` $\in L$, vagy `["Almafa", "karika"]` $\in L$. Tudnánk találni egy olyan bináris műveletet, amellyel együtt $L$ teljesíti a monoid axiómákat?
+
+Ennek a műveletnek asszociatívnak kell lennie, és két listából egy listát kell csinálnia. Mi lenne, ha az lenne a műveletünk, hogy két listát egymás után fűzünk. Jelölje ezt a műveletet `++`. Ekkor teljesül, hogy
+
+```hs
+[1, 2] ++ ([3, 4] ++ [5, 6]) == ([1, 2] ++ [3, 4]) ++ [5, 6]
+```
+
+Eddig jók vagyunk! Létezik vajon identitás elemünk? Igen, az üres lista! Láthatjuk, hogy
+
+```hs
+[1, 2, 3] ++ [] == [] ++ [1, 2, 3] == [1, 2, 3]
+```
+
+tehát a listák halmaza $L$ és a `++` művelet tényleg egy monoidot alkotnak.
+
+Ez nekünk miért hasznos? Nézzünk egy másik példát. Az egész számok és az $+$ is egy monoidot alkotnak. Ez nekünk azért jó, mert kihasználva a monoid axiómákat egy nagyobb számítást tetszőleges sok kisebb számításra bonthatunk, amelyek részeredményeit a végén összefűzhetünk. Például vegyük ezt, hogy Java-ban van egy listányi számunk, és arra vagyunk kíváncsi, hogy mennyi az összes szám összege:
+
+```java
+public static void main(String[] args) {
+ // A listánk (halmazunk)
+ List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+ // Mennyi a `numbers` listában tárolt számok összege?
+}
+```
+
+Ehhez egy kezdő programozó egy `for` ciklust használna:
+
+```java
+// ...
+List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+int sum = 0;
+for (int i : numbers)
+ sum = sum + i;
+
+// ...
+```
+
+Az elegáns megoldáshoz használjuk ki, hogy egy monoiddal van dolgunk. Egyszerre mindig csak két számot szeretnénk összeadni, tehát valami olyasmit szeretnénk, ami végigmegy a listánkon, és _akkumulálja_ a részösszegeket, ahogy összeadogatjuk a szomszédos számokat. A Monoid elvén alapuló `reduce` függvény pontosan ezt csinálja nekünk:
+
+```java
+// ...
+List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+// Párhuzamos feldolgozás
+// A stream több részre oszlik, a részek külön-külön akkumulálódnak,
+// majd az eredmények összeadódnak.
+int sum = numbers.parallelStream().reduce(
+ 0, // additív identitás
+ (a, b) -> a + b, // bináris művelet: két elemet kombinál
+ (a, b) -> a + b // összeadja a párhuzamosan számolt részösszegeket
+);
+
+//...
+```
+
+Mivel az összeadás asszociatív, a program feldarabolhatja az összeadást. Például az `(1 + 2 + 3) + (4 + 5 + 6)` ugyanazt az eredményt adja, mint az `1 + (2 + 3) + 4 + (5 + 6)`. Így tehát akár több szálon is össze tudjuk adni a listának egy-egy részlistáját, amiket a végén szintén összeadunk. Ennél az elemi példánál persze a `for` ciklus is megfelelő, viszont bonyolultabb számítások esetén az, hogy lényegében "ingyen" kaptuk meg a párhuzamosságot az nagyon kényelmes.
+
+Ha elindulunk ezen az úton, akkor eljuthatunk a _monádok_ fogalmáig, amiket már minden programozó használt életében, és szerette őket, akkor is, ha pontosan nem tudta, hogy azt használta. Ha használtál már Javascriptben `Promise`-t, vagy Kotlinban `?.` operátort, vagy ha [hívtál már meg több függvényt egymás után](https://en.wikipedia.org/wiki/Function_composition_(computer_science)#Composing_function_calls) akkor már használtál monádokat.
+
+A napjainkban egyre több modern nyelvben van sok funkcionális elem (Rust, Kotlin, Swift, Go) és régebbi nyelvek új verziói is sokat tartalmaznak (Java, C++). Az alapképzésben sajnos alig jut idő a funkcionális programozásra, viszont az OO-t a torkunkon is lenyomják. Ha mélyebben érdekel a téma, akkor nagyon tudom ajánlani a [Haskell nyelv](https://learnyouahaskell.github.io/introduction.html) megtanulását, illetve a [Deklaratív programozás](https://portal.vik.bme.hu/kepzes/targyak/VISZAD01/) kötvál és a [Funkcionális programozás C++-ban](https://portal.vik.bme.hu/kepzes/targyak/VITMAV47) szabvál elvégzését.
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/img/10_classdiagram.png b/docs/notes/sem4/computer_graphics/img/10_classdiagram.png
deleted file mode 100644
index 5abd91f..0000000
Binary files a/docs/notes/sem4/computer_graphics/img/10_classdiagram.png and /dev/null differ
diff --git a/docs/notes/sem4/computer_graphics/img/2_io.png b/docs/notes/sem4/computer_graphics/img/2_io.png
deleted file mode 100644
index 6e702ff..0000000
Binary files a/docs/notes/sem4/computer_graphics/img/2_io.png and /dev/null differ
diff --git a/docs/notes/sem4/computer_graphics/img/5_megjelenites.png b/docs/notes/sem4/computer_graphics/img/5_megjelenites.png
deleted file mode 100644
index b689ad1..0000000
Binary files a/docs/notes/sem4/computer_graphics/img/5_megjelenites.png and /dev/null differ
diff --git a/docs/notes/sem4/computer_graphics/img/7_reflect.png b/docs/notes/sem4/computer_graphics/img/7_reflect.png
deleted file mode 100644
index 4f89d8c..0000000
Binary files a/docs/notes/sem4/computer_graphics/img/7_reflect.png and /dev/null differ
diff --git "a/docs/notes/sem4/computer_graphics/img/7_r\303\274csi.png" "b/docs/notes/sem4/computer_graphics/img/7_r\303\274csi.png"
deleted file mode 100644
index a288cbe..0000000
Binary files "a/docs/notes/sem4/computer_graphics/img/7_r\303\274csi.png" and /dev/null differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_1/1_central_proj.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_central_proj.png
new file mode 100644
index 0000000..747df17
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_1/1_central_proj.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/1_gauss_gorbulet.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_gauss_gorbulet.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_gauss_gorbulet.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_gauss_gorbulet.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_gorbulet.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_gorbulet.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_gorbulet.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_gorbulet.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_hazi_help.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_hazi_help.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_hazi_help.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_hazi_help.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_hiberbolikus.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_hiberbolikus.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_hiberbolikus.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_hiberbolikus.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_idealis_pont.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_idealis_pont.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_idealis_pont.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_idealis_pont.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_kerulet.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_kerulet.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_kerulet.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_kerulet.png
diff --git a/docs/notes/sem4/computer_graphics/img/1_kviz_notes.jpg b/docs/notes/sem4/computer_graphics/img/chapter_1/1_kviz_notes.jpg
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_kviz_notes.jpg
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_kviz_notes.jpg
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_1/1_mercator_proj.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_mercator_proj.png
new file mode 100644
index 0000000..ea0d828
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_1/1_mercator_proj.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/1_projektiv.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_projektiv.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_projektiv.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_projektiv.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_1/1_stereo_proj.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_stereo_proj.png
new file mode 100644
index 0000000..e5993a1
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_1/1_stereo_proj.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/1_vetites.png b/docs/notes/sem4/computer_graphics/img/chapter_1/1_vetites.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/1_vetites.png
rename to docs/notes/sem4/computer_graphics/img/chapter_1/1_vetites.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_10/10_classdiagram.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_classdiagram.png
new file mode 100644
index 0000000..338ff75
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_10/10_classdiagram.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/10_collision_problem.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_collision_problem.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/10_collision_problem.png
rename to docs/notes/sem4/computer_graphics/img/chapter_10/10_collision_problem.png
diff --git a/docs/notes/sem4/computer_graphics/img/10_frenet_egye_meg.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_frenet_egye_meg.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/10_frenet_egye_meg.png
rename to docs/notes/sem4/computer_graphics/img/chapter_10/10_frenet_egye_meg.png
diff --git a/docs/notes/sem4/computer_graphics/img/10_rel.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_rel.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/10_rel.png
rename to docs/notes/sem4/computer_graphics/img/chapter_10/10_rel.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_10/10_see_through.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_see_through.png
new file mode 100644
index 0000000..cff18f6
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_10/10_see_through.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/10_volumetric.png b/docs/notes/sem4/computer_graphics/img/chapter_10/10_volumetric.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/10_volumetric.png
rename to docs/notes/sem4/computer_graphics/img/chapter_10/10_volumetric.png
diff --git a/docs/notes/sem4/computer_graphics/img/11_mv_add.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_mv_add.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/11_mv_add.png
rename to docs/notes/sem4/computer_graphics/img/chapter_11/11_mv_add.png
diff --git a/docs/notes/sem4/computer_graphics/img/11_mv_dot.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_mv_dot.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/11_mv_dot.png
rename to docs/notes/sem4/computer_graphics/img/chapter_11/11_mv_dot.png
diff --git a/docs/notes/sem4/computer_graphics/img/11_non_commutative_rot.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_non_commutative_rot.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/11_non_commutative_rot.png
rename to docs/notes/sem4/computer_graphics/img/chapter_11/11_non_commutative_rot.png
diff --git a/docs/notes/sem4/computer_graphics/img/11_rodrigues.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_rodrigues.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/11_rodrigues.png
rename to docs/notes/sem4/computer_graphics/img/chapter_11/11_rodrigues.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_11/11_rotate_expl.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_rotate_expl.png
new file mode 100644
index 0000000..8b84b6b
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_11/11_rotate_expl.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/11_wedge_sesh.png b/docs/notes/sem4/computer_graphics/img/chapter_11/11_wedge_sesh.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/11_wedge_sesh.png
rename to docs/notes/sem4/computer_graphics/img/chapter_11/11_wedge_sesh.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_blooyhell.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_blooyhell.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_blooyhell.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_blooyhell.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_c_beeg.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_c_beeg.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_c_beeg.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_c_beeg.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_c_mid.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_c_mid.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_c_mid.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_c_mid.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_c_smol.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_c_smol.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_c_smol.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_c_smol.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_chaos_example_1.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_example_1.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_chaos_example_1.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_example_1.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_chaos_example_2.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_example_2.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_chaos_example_2.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_example_2.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_chaos_flat.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_flat.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_chaos_flat.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_chaos_flat.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_comlogo.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_comlogo.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_comlogo.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_comlogo.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_12/12_double_pendulum.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_double_pendulum.png
new file mode 100644
index 0000000..7eb24bd
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_12/12_double_pendulum.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/12_fractal_noise.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_fractal_noise.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_fractal_noise.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_fractal_noise.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_hausdorff_tri.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_hausdorff_tri.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_hausdorff_tri.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_hausdorff_tri.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_inverse_isf.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_inverse_isf.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_inverse_isf.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_inverse_isf.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_iterated.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_iterated.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_iterated.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_iterated.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_julia.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_julia.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_julia.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_julia.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_12/12_julia_very_simple.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_julia_very_simple.png
new file mode 100644
index 0000000..212e5be
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_12/12_julia_very_simple.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/12_koch_g.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_koch_g.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_koch_g.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_koch_g.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_lindenmayer_flora.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_lindenmayer_flora.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_lindenmayer_flora.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_lindenmayer_flora.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_my_mental_state.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_my_mental_state.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_my_mental_state.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_my_mental_state.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_perlin_noise.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_perlin_noise.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_perlin_noise.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_perlin_noise.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_pseudorandom.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_pseudorandom.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_pseudorandom.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_pseudorandom.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_self_contained_universe.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_self_contained_universe.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_self_contained_universe.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_self_contained_universe.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_sierpinksi.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_sierpinksi.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_sierpinksi.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_sierpinksi.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_outside.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_outside.png
new file mode 100644
index 0000000..4fe4d00
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_outside.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_plus.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_plus.png
new file mode 100644
index 0000000..724f5ef
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_12/12_sqrt_plus.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/12_whatthefuckever.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_whatthefuckever.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_whatthefuckever.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_whatthefuckever.png
diff --git a/docs/notes/sem4/computer_graphics/img/12_wk.png b/docs/notes/sem4/computer_graphics/img/chapter_12/12_wk.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/12_wk.png
rename to docs/notes/sem4/computer_graphics/img/chapter_12/12_wk.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_2/2_func_model.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_func_model.png
new file mode 100644
index 0000000..1030f9e
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_2/2_func_model.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_2/2_io.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_io.png
new file mode 100644
index 0000000..a7ccbef
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_2/2_io.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/2_kovex_burok.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_kovex_burok.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/2_kovex_burok.png
rename to docs/notes/sem4/computer_graphics/img/chapter_2/2_kovex_burok.png
diff --git a/docs/notes/sem4/computer_graphics/img/2_kviz.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_kviz.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/2_kviz.png
rename to docs/notes/sem4/computer_graphics/img/chapter_2/2_kviz.png
diff --git a/docs/notes/sem4/computer_graphics/img/2_opengl_pipeline.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_opengl_pipeline.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/2_opengl_pipeline.png
rename to docs/notes/sem4/computer_graphics/img/chapter_2/2_opengl_pipeline.png
diff --git a/docs/notes/sem4/computer_graphics/img/2_viewport.png b/docs/notes/sem4/computer_graphics/img/chapter_2/2_viewport.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/2_viewport.png
rename to docs/notes/sem4/computer_graphics/img/chapter_2/2_viewport.png
diff --git a/docs/notes/sem4/computer_graphics/img/3_h8this.png b/docs/notes/sem4/computer_graphics/img/chapter_3/3_h8this.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/3_h8this.png
rename to docs/notes/sem4/computer_graphics/img/chapter_3/3_h8this.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_5/5_IEEE_float.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_IEEE_float.png
new file mode 100644
index 0000000..50bde74
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_5/5_IEEE_float.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_5/5_containment.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_containment.png
new file mode 100644
index 0000000..d06c0a6
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_5/5_containment.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/5_kviz_csillag.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_kviz_csillag.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/5_kviz_csillag.png
rename to docs/notes/sem4/computer_graphics/img/chapter_5/5_kviz_csillag.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_5/5_line_strip.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_line_strip.png
new file mode 100644
index 0000000..a4b36eb
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_5/5_line_strip.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_5/5_pipeline.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_pipeline.png
new file mode 100644
index 0000000..8ac4f55
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_5/5_pipeline.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/5_poligonvagas.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_poligonvagas.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/5_poligonvagas.png
rename to docs/notes/sem4/computer_graphics/img/chapter_5/5_poligonvagas.png
diff --git a/docs/notes/sem4/computer_graphics/img/5_vagasfa.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_vagasfa.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/5_vagasfa.png
rename to docs/notes/sem4/computer_graphics/img/chapter_5/5_vagasfa.png
diff --git a/docs/notes/sem4/computer_graphics/img/5_vptrans.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_vptrans.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/5_vptrans.png
rename to docs/notes/sem4/computer_graphics/img/chapter_5/5_vptrans.png
diff --git a/docs/notes/sem4/computer_graphics/img/5_vpvagas.png b/docs/notes/sem4/computer_graphics/img/chapter_5/5_vpvagas.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/5_vpvagas.png
rename to docs/notes/sem4/computer_graphics/img/chapter_5/5_vpvagas.png
diff --git a/docs/notes/sem4/computer_graphics/img/6_beware_of_the_pipeline.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_beware_of_the_pipeline.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/6_beware_of_the_pipeline.png
rename to docs/notes/sem4/computer_graphics/img/chapter_6/6_beware_of_the_pipeline.png
diff --git a/docs/notes/sem4/computer_graphics/img/6_bilinear_i.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_bilinear_i.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/6_bilinear_i.png
rename to docs/notes/sem4/computer_graphics/img/chapter_6/6_bilinear_i.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_6/6_bilinear_result.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_bilinear_result.png
new file mode 100644
index 0000000..54c07ef
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_6/6_bilinear_result.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_6/6_magnification.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_magnification.png
new file mode 100644
index 0000000..835f95b
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_6/6_magnification.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_6/6_minification.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_minification.png
new file mode 100644
index 0000000..88f3b41
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_6/6_minification.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_6/6_mipmap_result.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_mipmap_result.png
new file mode 100644
index 0000000..7b20ff7
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_6/6_mipmap_result.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/6_nearest_i.png b/docs/notes/sem4/computer_graphics/img/chapter_6/6_nearest_i.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/6_nearest_i.png
rename to docs/notes/sem4/computer_graphics/img/chapter_6/6_nearest_i.png
diff --git a/docs/notes/sem4/computer_graphics/img/7_fresnel.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_fresnel.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_fresnel.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_fresnel.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_7/7_gauss.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_gauss.png
new file mode 100644
index 0000000..3b53c48
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_7/7_gauss.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/7_light-surface.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_light-surface.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_light-surface.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_light-surface.png
diff --git a/docs/notes/sem4/computer_graphics/img/7_phong_example.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_phong_example.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_phong_example.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_phong_example.png
diff --git a/docs/notes/sem4/computer_graphics/img/7_phong_split.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_phong_split.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_phong_split.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_phong_split.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_7/7_pool.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_pool.png
new file mode 100644
index 0000000..0fcd60f
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_7/7_pool.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/7_radiancia.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_radiancia.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_radiancia.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_radiancia.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_7/7_reflect.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_reflect.png
new file mode 100644
index 0000000..e2c6e7d
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_7/7_reflect.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/7_refract.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_refract.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_refract.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_refract.png
diff --git "a/docs/notes/sem4/computer_graphics/img/chapter_7/7_r\303\274csi.png" "b/docs/notes/sem4/computer_graphics/img/chapter_7/7_r\303\274csi.png"
new file mode 100644
index 0000000..4d27cf4
Binary files /dev/null and "b/docs/notes/sem4/computer_graphics/img/chapter_7/7_r\303\274csi.png" differ
diff --git a/docs/notes/sem4/computer_graphics/img/7_swallow.png b/docs/notes/sem4/computer_graphics/img/chapter_7/7_swallow.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/7_swallow.png
rename to docs/notes/sem4/computer_graphics/img/chapter_7/7_swallow.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_8/8_class_diagram.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_class_diagram.png
new file mode 100644
index 0000000..f958cee
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_8/8_class_diagram.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/8_closest.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_closest.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_closest.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_closest.png
diff --git a/docs/notes/sem4/computer_graphics/img/8_getray.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_getray.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_getray.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_getray.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_8/8_no_epsilon.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_no_epsilon.png
new file mode 100644
index 0000000..92dd626
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_8/8_no_epsilon.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/8_raytrace.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_raytrace.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_raytrace.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_raytrace.png
diff --git a/docs/notes/sem4/computer_graphics/img/8_recurse.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_recurse.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_recurse.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_recurse.png
diff --git a/docs/notes/sem4/computer_graphics/img/8_sphere_intersect.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_sphere_intersect.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_sphere_intersect.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_sphere_intersect.png
diff --git a/docs/notes/sem4/computer_graphics/img/chapter_8/8_trace.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_trace.png
new file mode 100644
index 0000000..5eb34cd
Binary files /dev/null and b/docs/notes/sem4/computer_graphics/img/chapter_8/8_trace.png differ
diff --git a/docs/notes/sem4/computer_graphics/img/8_triangle.png b/docs/notes/sem4/computer_graphics/img/chapter_8/8_triangle.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/8_triangle.png
rename to docs/notes/sem4/computer_graphics/img/chapter_8/8_triangle.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_2d_texture.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_2d_texture.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_2d_texture.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_2d_texture.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_camera_model.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_camera_model.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_camera_model.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_camera_model.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_floatmoment.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_floatmoment.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_floatmoment.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_floatmoment.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_fov_norm.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_fov_norm.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_fov_norm.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_fov_norm.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_gouraud_issue.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_gouraud_issue.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_gouraud_issue.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_gouraud_issue.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_normal_interpolation.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_normal_interpolation.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_normal_interpolation.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_normal_interpolation.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_overcast.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_overcast.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_overcast.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_overcast.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_phong.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_phong.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_phong.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_phong.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_pipeline.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_pipeline.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_pipeline.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_pipeline.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_proj.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_proj.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_proj.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_proj.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_real_backface_culling.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_real_backface_culling.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_real_backface_culling.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_real_backface_culling.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_space.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_space.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_space.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_space.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_stripe_is_not_a_big_fan.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_stripe_is_not_a_big_fan.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_stripe_is_not_a_big_fan.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_stripe_is_not_a_big_fan.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_tesselation.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_tesselation.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_tesselation.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_tesselation.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_view_uwv.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_view_uwv.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_view_uwv.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_view_uwv.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_viewport_trans.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_viewport_trans.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_viewport_trans.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_viewport_trans.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_z_interpol.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_z_interpol.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_z_interpol.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_z_interpol.png
diff --git a/docs/notes/sem4/computer_graphics/img/9_zbuffer.png b/docs/notes/sem4/computer_graphics/img/chapter_9/9_zbuffer.png
similarity index 100%
rename from docs/notes/sem4/computer_graphics/img/9_zbuffer.png
rename to docs/notes/sem4/computer_graphics/img/chapter_9/9_zbuffer.png
diff --git a/docs/notes/sem4/computer_graphics/index.md b/docs/notes/sem4/computer_graphics/index.md
new file mode 100644
index 0000000..338afd3
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/index.md
@@ -0,0 +1,25 @@
+# Számítógépes grafika
+
+## Előszó
+
+Ez a jegyzet egy hallgatók által készített és karbantartott projekt, mely megpróbálja picit könnyebben emészthetővé tenni a Számítógépes grafika tárgyat. Természetesen nem helyettesíti az előadásra járást, de egy fokkal részletesebb, mint a hivatalos PPT-k.
+
+## Hasznos linkek
+
+- Egy [házifeladat sablon](https://github.com/levyry/grafika-hf-template) is készült a tárgyhoz, mellyel nem kell függőségek levadászásával, vagy a text editorod beállításaival foglalkoznod a házi írás helyett.
+- A tárgy [VIK Wiki oldalán](https://vik.wiki/Sz%C3%A1m%C3%ADt%C3%B3g%C3%A9pes_grafika) megtalálod a tárgy követelményeit, illetve további segédanyagokat, tippeket.
+- Szirmay tanár úr [YouTube csatornájára](https://www.youtube.com/@laszloszirmay-kalos5413) többször is hivatkozik a jegyzet. Mindenképpen ajánljuk az előadásvideók nézését, melyhez van egy [playlist](https://www.youtube.com/playlist?list=PLiH4g_VR3i0Pz0vAyjPzPCXDqLqHPfW2p).
+
+## Visszajelzések
+
+Ahogy telnek a félévek a tárgytematika megváltozhat, új segédanyagok és követelmények jelenhetnek meg. Ha valaki azt vélné felfedezni, hogy a jegyzet egy része elavult lenne, esetleg új kvíz kérdésekkel akarná bővíteni a jegyzetet, vagy csak éppen egy elírást talált valahol, az mindenképpen nyisson egy Issue-t a jegyzet [GitHub oldalán](https://github.com/VIK-CE-Notes/vik-ce-notes.github.io/issues/new), melyben megjelöli az egyik maintainert.
+
+## Függelékek
+
+### Matematikai kifejezések
+
+A jegyzetben sok matematikai kifejezéssel találkozhatunk, melyeknek egy részét a tárgy már feltételezi, hogy mindenki ismeri. Az [$A.$ függelékben](appendix/math_appendix.md) található a legtöbb ilyen kifejezés definíciója, illetve egy példa rá. Reméljük, hogy ez segít mindenkit ugyan arra a szintre hozni.
+
+## Maintainers
+
+Orbán "$\lambda$evy" Levente [orban.levente.laszlo AT gmail.com]
\ No newline at end of file
diff --git a/docs/notes/sem4/computer_graphics/lectures/1.md b/docs/notes/sem4/computer_graphics/lectures/1.md
new file mode 100644
index 0000000..97424e5
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/1.md
@@ -0,0 +1,693 @@
+# Geometriák és algebrák
+
+A geometriák különböző axiómákra épülnek. Az axiómákat eleinte _tapasztalatok_ határozták meg, és ezek olyan állítások, amikben _vallásosan hiszünk_. Tételek kiindulási pontjaként szolgálnak, és általában az alapfogalmakat impliciten ezekkel definiáljuk. Például az Euklideszi síkgeometriában az egyik legfontosabb, hogy egy egyenesre egy külső pontból legfeljebb egy olyan egyenes húzható, ami nem metszi (ez a [párhuzamossági posztulátum](https://hu.wikipedia.org/wiki/P%C3%A1rhuzamoss%C3%A1gi_axi%C3%B3ma)).
+
+??? example Bővebben Euklideszről...
+ Ha érdekel az Euklideszi síkgeometria, esetleg Euklidesz [Elemek](https://hu.wikipedia.org/wiki/Elemek) c. könyve, akkor a jegyzet írói ajánlják a [What was Euclid really doing? (3Blue1Brown)](https://www.youtube.com/watch?v=M-MgQC6z3VU) videót, melyben többek között szó esik a párhuzamossági posztulátumról és más geometriai rendszerekről is, melyek a tárgy tananyagát is képzik.
+
+Mi most absztrakt geometriai fogalmakhoz, mint például _pont_, _egyenes_, vagy _X metszi Y-t_ próbálunk számokat és függvényeket rendelni, hiszen ezekkel lehet programozni. Pontosabban bizonyos axiómák által alkotott _geometriához_ próbálunk egy _algebrát_ rendelni, amelyből már tudunk programokat írni. Viszont eközben sosem szabad a választott geometriánk axiómarendszerével ellentmondani.
+
+Az axiómáink megváltoztatása különböző eredményekhez vezethet, például ha olyan axiómarendszert alkotunk, ahol a háromszög belső szögeinek összege kevesebb mint $180\degree$, akkor _hiperbolikus geometriát_ kaptunk, mely egy gyakori model az asztrofizikában. Ha viszont több lenne, mint $180\degree$, akkor _gömbi geometriát_ kapnánk, mely a bolygónk modellezésében elengedhetetlen szerepet játszik.
+
+## Ambiens terek
+
+A különböző geometriákat _ambiens térrel_, más szóval beágyazó térrel, fogjuk ábrázolni.
+
+!!! info 1.1. Definíció (Ambiens tér, [ambient space](https://en.wikipedia.org/wiki/Ambient_space_(mathematics)))
+ Egy olyan tér, ami valamilyen objektumot (pl. sík, gömb) körbevesz.
+
+Picit absztraktnak hangzik ez a fogalom, próbáljuk meg értelmezni. Az euklideszi síkgeometria esetében például ez azt jelenti, hogy a szokásos két dimenziós ábrázolás helyett egy három dimenziós teret kell elképzelnünk, amelyben felveszünk egy síkot. Ez a sík az eredeti síkgeometria, viszont mivel három dimenzióban vagyunk, ezért nem limitálódunk le csak két dimenzióra.
+
+Például fel tudjuk használni ezt a harmadik koordinátát arra, hogy elkülönítsük a pontokat és a vektorokat. Alapból (ránézésre) nem tudnánk megmondani a $(2, 3)$ koordinátájú objektumról, hogy ez egy pontot ábrázol, vagy egy helyvektort, mely a $(2, 3)$ pontba mutat. Viszont most mondhatjuk azt, hogy az összes pont legyen $[x, y, 1]$ alakú, és az összes vektor pedig $[x, y, 0]$.
+
+Más geometriákat is beágyazhatunk ambiens terekbe, például ha nem a $(x, y, 1)$ síkon választanánk pontokat, hanem azt mondanánk, hogy minden pont $x, y$ és $w$ koordinátáinak az $x^2 + y^2 + w^2 = 1$ egyenletet kéne kielégítenie, akkor elliptikus geometriát ábrázolnánk, vagy a hiperbolikus geometria esetén a pontokat az $x^2 + y^2 - w^2 = -1$ egyenlet alapján választanánk. Az a fontos, hogy mindig ezeken az objektumokon (sík, félgömb, gömb, stb) választunk pontokat.
+
+## Metrika
+
+Korábban különböző metrikákkal (pl. hossz, szög) definiáltuk a különböző műveleteket (pl. skaláris szorzás). Most viszont fordítva fogjuk csinálni: tudjuk, hogy akarunk egy skaláris szorzás műveletet, ami rendelkezik a már megszokott tulajdonságaival (kommutatív, bilineáris).
+
+Nem a metrikáinkkal definiáljuk a műveletet, hanem a művelettel definiáljuk a metrikáinkat: egy vektor hosszát definiálhatjuk úgy, mint a saját magával vett skaláris szorzatának a négyzetgyöke. Ez az euklideszi geometriában pontosan megegyezik az általunk ismert hossz fogalmával, viszont így algebrailag is meg tudjuk fogalmazni, hogy mit értünk egy vektor "hosszán".
+
+## Euklideszi síkgeometria
+
+Két dimenzióról beszélünk ($x$,$y$ koordinátákkal), amihez felveszünk egy harmadik tulajdonságot ($w$-t).
+
+!!! info 1.2. Definíció (skaláris szorzás)
+ Vegyük az ambiens tér két elemét, legyenek ezek $a_1$ és $a_2$. Ekkor ezek _skaláris szorzata_ a következő:
+
+ $$
+ a_1 \cdot a_2 = x_1 x_2 + y_1 y_2 + w_1 w_2
+ $$
+
+Ez a művelet kommutatív, disztributív (bilineáris) és skálázható, viszont **nem** asszociatív.
+
+??? example Azt hittem, hogy már letudtam az Anal-t...
+ Ha pár matekos kifejezés pontos definíciójára esetleg nem emlékeznél, nézz rá az [$A.$ függelékre](../appendix/math_appendix.md), ahol példákon keresztül is segítünk megérteni egyes fogalmakat. A fenti fogalmak definícióit [itt](../appendix/math_appendix.md#műveleti-tulajdonságok) találod.
+
+Az ambiens terünk elemei a _pontok_ és a _vektorok_. Az ambiens vektorokat képesnek kell lennünk összeadni és skálázni, ebből következik, hogy $w=0$ a vektoroknál és $w=1$ a pontoknál (egyéb $w$-k se nem pontok, se nem vektorok). A pontok esetén $w=1$ azért áll fenn, hogy az eltolás lineáris leképezés maradjon. Továbbá így két pont különbsége pont egy vektor, hiszen a két $w$ tag különbsége $0$ lesz.
+
+### Vektorok tulajdonságai
+
+- Két pont különbsége egy vektor.
+- Az ambiens térnek elemei: $\underline{v} = [x,y,0]$
+- Hossza: $|v| = \sqrt{v \cdot v}$
+- Merőlegesség: $u \perp v$ ha $u \cdot v = 0$
+ - Minden vektorra végtelen sok merőleges vektor létezik $\lambda [y, -x, 0]$ alakban.
+- Párhuzamosság: $u \parallel v$ ha $u = \lambda v$
+ - Minden vektorra végtelen sok párhuzamos vektor létezik $\lambda [x, y, 0]$ alakban.
+- Egységvektor: $\displaystyle|v^0| = 1, v^0 \cdot v^0 = 1, v^0 = \frac{v}{|v|} = \frac{v}{\sqrt{v \cdot v}}$ (normalizálás)
+
+### Egyenes egyenletei
+
+!!! info 1.3. Definíció (Egyenes paraméteres egyenletei)
+ Egy $r$ egyenes parametrikus egyenlete a következő:
+
+ $$
+ r(t) = p + vt
+ $$
+
+ Koordináták használatával pedig:
+
+ $$
+ [x(t),y(t),w(t)] = [p_x,p_y,1] + [v_x,v_y,0] \cdot t
+ $$
+
+ Végezetül két pont ($p, q$) kombinációjaként:
+
+ $$
+ [x(t),y(t),w(t)] = [p_x,p_y,1] \cdot (1 - t) + [q_x,q_y,1] \cdot t
+ $$
+
+???+ example Fizikai értelmezés
+ Fizikai megközelítésből ez egy _állandó sebességű mozgásnak_ felel meg, hiszen az első idő szerinti deriváltja a sebesség, a második pedig a gyorsulás:
+
+ $$
+ \begin{align*}
+ \dot{r}(t) = v \\
+ \ddot{r}(t) = 0
+ \end{align*}
+ $$
+
+Azaz $p$ pontból $t$ ideje indultunk el $v$ vektorral. Ha végig gondoljuk ez valóban pontok gyűjteménye, hiszen $w=1$ végig. Fel lehet fogni továbbá az ambiens tér síkjának (melyet az origó, $p$ és $q$ pontok alkotnak) és a $w=1$ síknak a metszeteként.
+
+!!! info 1.5. Definíció (Egyenes implicit egyenlete)
+ Egy $r$ egyenes implicit egyenlete a következő:
+
+ $$
+ n\cdot (r - p) = 0
+ $$
+
+Ahol $r$ egyenest határozzuk meg $p$ pontja és $\underline{n}$ normálvektora segítségével:
+
+$$
+r(x,y) \Rightarrow [n_x, n_y, 0] \cdot [x - p_x, y - p_y, 0] = 0
+$$
+
+vagyis
+
+$$
+\boxed{n_x x + n_y y + d = 0}
+$$
+
+ahol $d = -n \cdot p$.
+
+Ha $r$ helyére behelyettesítünk, akkor könnyen eldönthetjük, hogy egy pont rajta van-e (egyébként pont ezért _implicit_ egyenlet, mert az $r$ egyenest nem fejezzük ki expliciten).
+
+## Euklideszi térgeometria
+
+A célunk az, hogy minden legyen ugyan olyan mint a síkgeometriánál, csak most már egyel magasabb dimenzióban: itt az ambiens tér négy dimenziós, az elemeit $[x, y, z, w]$ alakban adjuk meg.
+
+A korábban megbeszélt műveletek nem változnak, az egyenes egyenletek továbbra is megmaradnak.
+
+### Sík egyenletei
+
+!!! info 1.6. Definíció (Sík explicit egyenlete)
+ Egy $p$ pontot tartalmazó, $\underline{a}$ és $\underline{b}$ nem párhuzamos vektorok ($\underline{a} \not\perp \underline{b}$) által kifeszített sík explicit egyenlete a következő:
+
+ $$
+ r(u,v) = p + au + bv
+ $$
+
+ ahol $u,v$ valós paraméterek.
+
+!!! info 1.7. Definíció (Sík implicit egyenlete)
+ Egy sík implicit egyenlete a következő:
+
+ $$
+ n \cdot (r-p) = 0
+ $$
+
+Ahol $\underline{n}$ normálvektor merőleges $\underline{a}, \underline{b}$ vektorokra, vagyis: $n_x x + n_y y + n_z z + d = 0$
+
+Két $N_1, N_2$ sík akkor egyeznek meg, ha $N_1 = N_2 \lambda$ valamilyen $\lambda$ skalárra.
+
+## Görbület
+
+### Görbék görbülete
+
+Egy adott pontra az alábbi két definíció egyikét használhatjuk:
+
+!!! info 1.8. Definíció (Adott pontbeli görbület)
+ A $\kappa$ _görbület_ az "egysebességű" centripetális gyorsulás:
+
+ $$
+ a_{cp} = \frac{v^2}{R}
+ $$
+
+Ahol "egysebességű" alatt azt értjük, hogy a sebesség nagysága állandó.
+
+!!! info 1.9. Definíció (Adott pontbeli görbület)
+ A $K$ _görbület_ a simuló kör sugarának reciproka:
+
+ $$
+ K = \frac{1}{r} = \frac{v^2}{r}
+ $$
+
+{width=100%}
+
+### Gauss görbület
+
+Egy felület (mondjuk henger) görbületét szeretnénk meghatározni egy adott pontban. Feltehető, hogy ebben a pontban a felületnek van egy normálvektora, ami merőleges a felület síkjára. Ekkor az alakzatot felvághatjuk olyan síkokkal amik az adott pontot metszik és a normálvektorral párhuzamosak. Ezek a síkok bármerre állhatnak és a felületet ahogy metszik, úgy egy görbét határoznak meg.
+
+Az így kapott görbék közül van kettő, ahol az egyiknél minimális a görbület, a másiknál maximális. Ezeket a _principális_ vagy _főgörbületi_ irányoknak nevezzük, és merőlegesek egymásra.
+
+Az itt található görbületek szorzata az úgynevezett _Gauss-görbület_.
+
+{width=100%}
+
+??? example Részletek
+ [Ezen](https://youtu.be/0ZV4TjgI424?t=621) a linken elérhető a hivatalos grafika youtube videó ezzel kapcsolatban. A diasorokon voltak még további alakzatok, ezeken érdemes ezt végig gondolni. A legfontosabb, hogy a normállal mindig párhuzamosak ezek a metszések.
+
+## Gömbi geometria
+
+Itt a görbület állandóan pozitív, az egyenesek is görbék. További fontos változások:
+
+- Két pont nem mindig határoz meg egyértelműen egy egyenest.
+- Két egyenes mindig két pontban metszi egymást.
+- Nincsenek olyan egyenesek, amik ne metszenék egymást (még a párhuzamosok is metszik egymást).
+
+Ezeket a változtatásokat az új axiómák eredményezték.
+
+### Alap definíciók
+
+!!! info 1.10. Definíció (A gömb egyenlete)
+ Egy $k$ kör egyenlete a következő:
+
+ $$
+ k\colon x^2 + y^2 + z^2 = R^2 = \frac{1}{K}
+ $$
+
+Itt a $K$ görbület mindig pozitív.
+
+!!! info 1.11. Definíció (Főkör)
+ Két pont és a gömb közepe meghatároz egy síkot. A kört, ami a sík és gömb metszésével jön létre _főkörnek_ nevezzük.
+
+A főkör az egyenes analógja, hiszen ez lesz a legrövidebb út két pont között.
+
+Fontos kiemelni, hogy a főkört nem mindig lehet egyértelműen meghatározni, pl. Északi sark, Déli sark, Origó pontokkal végtelen sok sík van.
+
+A távolság analógja az _ívhossz_: $\displaystyle R \theta = \frac{\theta}{\sqrt{K}}$.
+
+!!! info 1.12. Definíció (Főkör egyenlete)
+ A főkör egyenlete a következő:
+
+ $$
+ r(t) = p \cos(t/R) + v^0 R \sin(t/R)
+ $$
+
+ ahol felhasználtuk, hogy egységsebességnél a távolság képlete $R \theta = t$.
+
+### Elliptikus geometria
+
+Ez a geometria nagyrészt analóg a gömbi geometriával, viszont egy fontos változtatás, hogy _az átellenes pontok egynek számítanak_.
+
+### Háromszögek gömbi geometriában
+
+Gömbi geometriában a háromszögek belső szögösszege nagyobb mint $180˚$, a területük pedig:
+
+$$
+T = (\alpha + \beta + \gamma - \pi)/K
+$$
+
+ahol $\alpha, \beta, \gamma$ a háromszög belső szögei radiánban. Derékszögű háromszögekre pedig az alábbi egyenlőtlenség teljesül:
+
+$$
+a^2 + b^2 > c^2
+$$
+
+ahol $a,b,c$ a háromszög oldalai.
+
+### Az ambiens tér elemei
+
+Az ambiens tér elemei a pontok és a vektorok egy adott pontban, ahol a $p$ pontokra teljesül, hogy
+
+$$
+\begin{align*}
+p \cdot p &= 1 \\
+p_x^2 + p_y^2 + p_w^2 &= 1
+\end{align*}
+$$
+
+ahol a skaláris szorzás definíciója változatlan az euklideszi síkgeometriához képest.
+
+A vektorokat csak adott $p$ pontokban definiáljuk; úgy, hogy egy $v$ vektorra teljesüljön, hogy
+
+$$
+p \cdot v = 0
+$$
+
+Fontos kiemelni, hogy a vektorok mások a tér különböző pontjaiban, és egy vektor a hozzá tartozó pont tangens terének az eleme.
+
+### Egyenesek
+
+Az egyenest továbbra is lehet egységsebességű mozgásként értelmezni, viszont itt már máshogy kell azt a mozgást leírni:
+
+!!! info 1.13. Definíció (Az egyenes parametrikus egyenlete gömbi geometriában)
+ Egy $r$ egyenes parametrikus egyenlete a következő:
+
+ $$
+ r(t) = p \cos(t) + v^0 \sin(t)
+ $$
+
+Továbbá is értelmezhető úgy, mint az ambiens tér síkjának és a geometriának a metszete.
+
+!!! info 1.14 Definíció (Gömbi kombináció, "slerp")
+ $$
+ \\[2.75ex] % weird spacing required so its centered. probably because there is no text in the admonition
+ r(td) = p \frac{\sin(1-t)d}{\sin(d)} + q \frac{\sin(td)}{\sin(d)}
+ $$
+
+Természetesen a pontok nem hagyják el a gömb felszínét, így $r(t) \cdot r(t) = 1$, és mivel egységsebességű mozgás, ezért $\dot{r}(t) \cdot \dot{r}(t) = 1$.
+
+A Gauss görbületet pedig a második idő szerinti deriváltból kaphatjuk meg:
+
+$$
+\ddot{r}(t) = -(r)t \Rightarrow K = \ddot{r}_{min} \cdot \ddot{r}_{max} = 1
+$$
+
+### Távolság
+
+
+Két pont távolsága az egységsebességű, egyenesvonalú mozgás ideje:
+
+$$
+d(p, q) = \arccos(q \cdot p)
+$$
+
+ebből meghatározható a kör implicit egyenlete:
+
+!!! info 1.15. Definíció (A kör implicit egyenlete gömbi geometriában)
+ $$
+ \\[2.75ex] % see comment at 1.14 definition
+ r \cdot c = \cos(R)
+ $$
+
+ahol felhasználtuk, hogy $R = d(r,c) = \arccos(r \cdot c)$.
+
+### Térképek
+
+Nézzünk egy valóvilág beli alkalmazást. A célunk az, hogy egy gömböt (például a Föld felszínét) levetítsünk egy síkra úgy, hogy minél jobban igazodjon a valós gömbhöz. Elvárjuk tőle, hogy euklideszi legyen, hogy könnyen ábrázolni tudjuk. Ezen felül két hasonlósági metrikáról beszélhetünk:
+
+#### Topológiai hasonlóság
+
+Ekkor egyértelmű folytonos leképezés van a valódi helyek és utak, illetve az ábrázolt helyek és utak között. Az orientáció is megmarad, azaz ami a térképen "balra van" az a való világban is "balra van".
+
+#### Geometriai hasonlóság
+
+Ami a való világban egy kör vagy egy egyenes, az a térképen is látszódjon annak. Szög-, távolság-, és területarány tartó; egyszóval a Gauss görbület egyezzen meg. Példa: Ha egy hajón utazunk, és el szeretnénk kanyarodni Afrika felé, és a (sík) térképen megmértük, hogy $45\degree$-ot kell ehhez balra kanyarodni, akkor a valóságban (gömb felszínén) is pont $45\degree$-ot kell forgatni a kormányon.
+
+Fontos, hogy távolságoknál és területeknél csak _arányokról_ beszélünk.
+
+??? question De miért nem lehet olyan térkép, ami mindent megtart?
+ Ha meg akarnánk tartani mind a szögeket, a távolságarányokat, és a területarányokat, akkor az azt jelentené, hogy nem változtathatunk a Gauss görbület értékén, hiszen $K$ attól függ, hogy a felületen hogyan mérünk szöget és távolságot, és független a felület térbeli alakjától ([Theorema Egregium](https://hu.wikipedia.org/wiki/Theorema_egregium)). Viszont a gömbi geometriában a görbület állandóan pozitív, azaz $K \gt 0$, viszont a síkoknál $K = 0$, szóval muszáj lesz változtatnunk $K$ értékén, azaz nem tudunk mindent megtartani.
+
+### Gömbök vetítése
+
+Három különböző vetítési módot tárgyalunk:
+
+#### Középpontos vetítés
+
+A vetítési középpontot összekötjük a gömb felületével, és megnézzük, hogy ez az egyenes hol metszi el a síkot amire vetítünk. Ez a metszéspont lesz a gömb felszínén lévő pontnak a vetített pontja. Ha ezt megcsináljuk a gömb minden pontjára, akkor levetítettük a gömböt a síkra. Viszont mivel a vetítési középpont és a gömb felszínének egy pontja által meghatározott egyenes két pontot metszik a gömb felszínén (ez egy átmérő lényegében, szóval két átellenes pontot határoz meg), ezért redundáns a vetítés, általában csak a _felső félgömböt_ vetítjük. Továbbá ez a vetítés _egyenestartó_ (a gömbi főkör pontjait vetítve egyenest kapunk a síkon), de **nem** kör-, szög- vagy távolságtartó.
+
+{width=100%}
+
+#### Sztereografikus vetítés
+
+Az elv teljesen analóg a középpontos vetítéssel, csak itt nem a gömb középpontja lesz a vetítési központ, hanem a gömb egy másik, tetszőleges pontja. Általában ez a gömb valamelyik pólusa szokott lenni, tipikusan a déli. Ekkor a _déli pólus kivételével mindent_ vetítünk, továbbá ez a vetítés _kör-_ és _szögtartó_, de **nem** egyenes- és távolságtartó. Bizonyos értelemben inverze a középpontos vetítésnek, hiszen a távolságon kívül pont ellentétes dolgokat tartanak meg.
+
+{width=100%}
+
+#### Mercator térkép
+
+Eddig a gömböket egyenesen síkokra vetítettünk, de most járjunk el másképp. Vegyük körbe a gömbünket egy hengerrel, és vetítsük a gömb felszínének a pontjait ennek a palástjára; ezt a palástot kitekerve ugyan úgy egy síkot kapunk. Az eljárás hasonló a középpontos vetítéshez, ugyan úgy a gömb középpontjából vetítünk pontokat, de mielőtt kitekerjük a henger palástját, meg kell nyújtanunk felfelé, hogy biztosítsuk a szögtartóságot. Ez az egyik legelterjedtebb térkép féle. Ez a vetítés _szögtartó_, de **nem** távolságtartó.
+
+{width=100%}
+
+???+ question Miért kell megnyújtani a hengert?
+ A képzeletbeli hengerünk végtelen magas, és mi csak a palástjára vetítünk. Ennek az a következménye, hogy az északi és déli pólusoknak nem lesz vetített pontja a paláston, hiszen a pólusok és a középpont által meghatározott egyenes párhuzamos a palásttal, nem fogja sehol metszeni. Viszont ha egy nagyon picit elmozdulunk a pólusoktól, akkor már metszeni fogja, csak nagyon nagyon messze a középponttól. Ilyenkor nagyon pici szögváltoztatással is a gömb méretéhez relatívan óriási változások lesznek a vetített pontok helyzetében.
+
+ Ezzel ellentétben ha az "egyenlítő" körüli pontokat vetítjük, itt kicsi változtatások a szögben nem eredményeznek olyan nagy változást a vetített pontok helyzetén. Így ahhoz, hogy szögtartó lehessen, muszáj lesz függőlegesen megnyújtani a hengert.
+
+
+## Hiperbolikus geometria
+
+Itt a görbület állandóan negatív. További fontos változás, hogy egy egyenesre egy külső pontból több nem metsző egyenes húzható.
+
+!!! info 1.16. Definíció (Hiperboloid egyenlete)
+ A $h$ hiperboloid egyenlete a következő:
+
+ $$
+ h\colon x^2 + y^2 - z^2 = -R^2 = \frac{1}{\kappa}
+ $$
+
+ Ez levezethető komplex számokkal is: $h\colon (iR)^2 = -R^2$
+
+### 1.7.1. Hiperbolikus terek vetítése egy diszkre
+
+{width=100%}
+
+??? info Emlékeztető (3. háziból 2 kör merőleges)
+ {width=100%}
+
+### 1.7.2. Minkowski tér
+
+A háromdimenziós teret kiterjesztjük egy negyedik dimenzióval, ami az _idő_. Itt nem pontok, hanem _események_ vannak jelen, hiszen ugyanaz a hely szerepelhet kétszer, de különböző időpontokban, más-más események közben.
+Ebben a rendszerben a távolságot úgy kell érteni, hogy az $x_1$ helyről $t$ idő alatt egy hatás elér-e egy $x_2$ helyre.
+
+## 1.8. Projektív geometria
+
+Ez az egyik legfontosabb geometriai rendszer amit tárgyalunk, mivel az emberi vizuális látás is így értelmezi a világot, szóval amikor grafikai programot csinálunk, akkor ehhez kell igazodni (a GPU mindegyik geometriát támogatja, de projektív geometriában gondolkodik). Az euklideszi geometria tapasztalati alapon készült, viszont a gyakorlatban tapasztaltakat nem írja le pontosan: ha sínekre állunk, akkor azt látjuk, hogy ezek a végtelenben "találkoznak", pedig párhuzamos egyenesek, szóval Euklidesz szerint nem lehet metszéspontjuk.
+
+Úgy fogjuk módosítani az euklideszi geometriát, hogy a gyakorlatban tapasztaltakat is pontosan le tudja írni. Mostantól bármilyen két egyenes - legyenek azok párhuzamosak vagy sem - pontosan egy pontban metszik egymást, így a "párhuzamos", mint fogalom értelmét veszti.
+
+Előnye ennek a geometriának - azon felül, hogy pontosabban ábrázolja a valóságban tapasztaltakat - az az, hogy lényegesen leegyszerüsíti a programozást: nem kell olyan edge-caseket vizsgálni, hogy két egyenes párhuzamos, hanem mindig létezik bármely két egyenes metszéspontja. Hátránya viszont az, hogy mivel most már két, euklideszi geometriában párhuzamos egyenes a "végtelenben" metszik egymást, így bekerül a "végtelen" is a geometriánkba, és így már nem lehet távolságot mérni. Nem lehet Descartes- vagy polárkoordinátákkal dolgozni, hiszen azok alkalmatlanok a "végtelen" távol lévő pont kezelésére.
+
+### 1.8.1. Ambiens tér elemei
+
+A sík, amit az ambiens tér körbe vesz az ugyan az mint az euklideszi geometriában, csak hozzáveszünk _ideális pontokat_. Ezek a pontok azok, ahol metszik egymást a "végtelenben" a párhuzamos egyenesek. Végtelen sok ilyen pont van, minden irányhoz tartozik egy.
+
+A beágyazás maga is máshogy történik, mivel az ideális pontokat valahogy reprezentálnunk kell. Ezt úgy érjük el, hogy az euklideszi pontokat kibővítjük egyenesekké. Kiválasztunk a projektív síkon egy pontot, és ezt összekötjük az origóval. Az így kapott egyenes reprezentálja a projektív pontot:
+
+$$
+\underbrace{(x,y)}_{\text{ Euklideszi pont}}
+\longrightarrow
+\underbrace{[x,y,1]}_{\substack{\text{Projektív síkra}\\
+ \text{kerül}}}
+\sim
+\underbrace{[x \cdot w, y \cdot w, w]}_{\substack{\text{Ennek a pontnak az} \\
+ \text{eltolása valami $\scriptsize w$} \\
+ \text{konstanssal, egy} \\
+ \text{egyenest adva.}}}
+= [X, Y, w]
+$$
+
+ahol $\displaystyle x = \frac{X}{w}, y = \frac{Y}{w}$ (ez az un. _homogén osztás_) és $w \neq 0$.
+
+Így ábrázolni tudunk minden euklideszi pontot mint egyenest. Az ideális pontok pedig $[X,Y,0]$ alakúak, azaz náluk $w$ lehet $0$. Még fontos kiemelni, hogy az egyenes "két végén" ugyan az az ideális pont van, tehát az mindegy, hogy melyik irányba indulunk el az eredeti ponttól ezen az egyenesen, a végén ugyan ahhoz a projektív ponthoz jutunk. Erre úgy is lehet gondolni, hogy ez az egyenes topológiailag egy kör.
+
+Ha már vannak projektív pontjaink, akkor tekintsünk _projektív egyeneseket_. Az egyenes továbbra is a legrövidebb távolság két pont között.
+
+!!! info 1.17. Definíció (A projektív egyenes explicit/parametrikus képlete)
+ Legyen két pontunk $P_1 = [X_1, Y_1, w_1]$ és $P_2 = [X_2, Y_2, w_2]$ alakban. Vegyünk fel egy $t$ futóváltozót. Ekkor a $P_1$ és $P_2$ által meghatározott egyenes parametrikus képlete:
+
+ $$
+ [X(t),Y(t),w(t)] = [X_1,Y_1,w_1] \cdot (1-t) + [X_2,Y_2,w_2] \cdot t
+ $$
+
+Itt a $t$ futóváltozót ahogy elkezdjük növelni $0$ és $1$ között, úgy nagyobb arányban számolja bele az egyik pont koordinátáit egy adott pontba mint a másikét. Ha vesszük az összes ilyen pontot $t$ minden értékére akkor megkapjuk az egyenest $P_1$ és $P_2$ pont között.
+
+Az implicit egyenletet is hasonlóan vissza tudjuk vezetni az euklideszi esetre. Egy euklideszi egyenest egy $\underline{n}$ normálvektorral és az eltolással írjuk le:
+
+$$
+n_x x + n_y y + d = 0
+$$
+
+Ha homogén koordinátákra váltunk ($x = \cfrac{X}{w}, y = \cfrac{Y}{w}$), akkor az alábbi alakot kapjuk:
+
+$$
+n_x X / w + n_y Y / w + d = 0 \qquad (w \neq 0)
+$$
+
+Ebből az egyenletből pedig megkapjuk a projektív egyenes implicit egyenletét:
+
+!!! info 1.18. Definíció (A projektív egyenes implicit egyenlete)
+ Adott egy $P$ projektív pont $[X, Y, w]$ alakban, és egy $\underline{n}$ normálvektor $\displaystyle \begin{bmatrix}
+ n_x \\
+ n_y \\
+ d\end{bmatrix}$ alakban. Ekkor a projektív egyenes implicit egyenlete a következő:
+
+ $$
+ n_x X + n_y Y + dw = 0 \qquad \bcancel{\cancel{(w \neq 0)}}
+ $$
+
+ azaz $P \cdot \underline{n} = 0$
+
+Fontos megjegyezni, hogy a pont egy sorvektor, az egyenes pedig egy oszlopvektor, és $w$ lehet $0$.
+
+A projektív tér esetében az euklideszi pontokra ugyan úgy $w=1$, csak most $[x,y,z,1]$ alakúak. Itt is beszorozhatunk $w$-vel, teljesen analóg a síkban lévő projektív pontokkal.
+
+## 1.8.2. Dualitás, metszés, illeszkedés
+
+Ha egy tétel pontokról és egyenesekről szól (mint például a projektív egyenes implicit egyenlete), akkor a pontok és egyenesek szerepe felcserélhető benne, és a tétel igaz marad.
+
+Így a 2D egyenes egyenlete az
+
+$$
+p \cdot l = 0
+$$
+
+azaz $\text{point} \cdot \text{line} = 0$ alakú. Ezt át lehet vezetni 2D-ből 3D-be, ahol kényelmesebb a metszés és illeszkedés példája erre:
+
+!!! info Tétel.
+ A $p_1$ és $p_2$ pontokra illeszkedő $l$ egyenes:
+
+ $$
+ \underbrace{p_1 \cdot l = 0}_{\displaystyle \hspace{6pt} l \perp p_1}, \quad \underbrace{p_2 \cdot l = 0}_{\displaystyle \hspace{6pt} l \perp p_2} \rightarrow l = p_1 \times p_2
+ $$
+
+Ennek az állításnak a duálisa:
+
+!!! info Tétel.
+ A $l_1$ és $l_2$ egyenesekre illeszkedő $p$ pont (metszéspont):
+
+ $$
+ \underbrace{l_1 \cdot p = 0}_{\displaystyle \hspace{2pt} p \perp l_1}, \quad \underbrace{l_2 \cdot p = 0}_{\displaystyle \hspace{2pt} p \perp l_2} \rightarrow p = l_1 \times l_2
+ $$
+
+Illetve még a metszésekhez kapcsolódó tétel:
+
+!!! info Tétel.
+ A $p$ ponton átmenő $L$ egyenesre merőleges $l$ egyenes:
+
+ $$
+ p \cdot l = 0, \quad l \cdot L^* = 0 \rightarrow l = p \times L^*
+ $$
+
+ ahol $L^*$: $L$-ből a $w$ törlése
+
+---
+
+# Kvíz
+
+!!! question 1\. Milyen messze van az $(-5, 4)$ pont a $3x + 4y + 5 = 0$ implicit egyenletű egyenestől
+
+??? tip Megoldás
+ 1\. Egyenesre normálvektort állítasz
+
+ $$
+ (3, 4) \implies (4, -3)
+ $$
+
+ 2\. Normálvektorral új egyenes, ami átmegy a ponton
+
+ $$
+ 4 \cdot (-5) + (-3) \cdot 4 + d = 0 \implies d = 32 \implies 4x -3y + 32 = 0
+ $$
+
+ 3\. Az egyenesek metszéspontjának megtalálása
+
+ $$
+ 4x -3y + 32 = 0 \text{ és } 3x + 4y + 5 = 0
+ $$
+
+ Mondjuk hozzáadom $3/4$-szer a másodikat az elsőhöz, de sok jó út van:
+
+ $$
+ \frac{25}{4} x + \frac{133}{4} = 0 \implies x = \frac{-143}{25}
+ $$
+
+ Ebből következik, hogy $y = \cfrac{76}{25}$
+
+ 4\. Metszés pont és eredeti pont távolságának kiszámítása
+
+ $$
+ d = \sqrt{\left((-5) - \left(\frac{-143}{25}\right)\right)^2 + \left(4 - \frac{76}{25}\right)^2} = 1.2
+ $$
+
+---
+
+!!! question 2\. Tekintsünk két várost $A$-t és $B$-t az északi szélesség (lattitude) $45$ fokán. Az $A$ város keleti hosszúsága $150\degree$, a $B$ város keleti hosszúsága $100\degree$. Mekkora az $A$ és $B$ város távolsága km-ben, ha a föld sugarát $6000$ km-nek vesszük?
+
+??? tip Megoldás
+ Távolságot (jelölje $x$) a főkörön mérjük, ott a legrövidebb.
+
+ 1\. 45\degree-nál mekkora egy kör kerülete:
+
+ $$
+ R' = R \cdot \sin(\theta) = 6000 \cdot \sin(45\degree) \approx 4242.64
+ $$
+
+ 2\. Ezen a körön már tudjuk, hogy a közrezárt szög $150\degree-100\degree = 50\degree$, azaz radiánban: $\theta' = 50 \cdot \frac{\pi}{180} = 0.8727$ radián.
+
+ $$
+ x = R' \cdot \theta' = 3702.5519 \dots
+ $$
+
+---
+
+!!! question 3\. A gömbi geometriánk Gauss görbülete $0.8$. Mekkora a $0.2$ sugarú kör kerülete ebben a geometriában?
+
+??? tip Megoldás
+ 1\. Gauss görbületből a gömb sugara
+
+ $$
+ K = 1/R^2 \implies R = 1 / \sqrt{K} = 1 / \sqrt{0.8} \approx 1.12
+ $$
+
+ 2\. A kör sugara most a gömbön található egyenesben mérve van megadva (a korábbi ábrán ez volt $r$)
+
+ $$
+ r = R * \theta \implies \theta = 0.2 / 1.12 \approx 0.18
+ $$
+
+ 3\. A kör kerülete pedig
+
+ $$
+ 2 \pi R \sin(\theta) = 2 \pi * 1.12 * \sin(0.18) = 1.2499
+ $$
+
+ Ha pontos értékekkel számolunk, ha kerekítve, akkor kb. $1.26$.
+
+---
+
+!!! question 4\. Egy pont koordinátái a $t$ idő alábbi függvényei: $x(t) = t*t, y(t) = \cfrac{1}{t}$ mekkora a mozgás sebességének a négyzete az első másodpercben?
+
+??? tip Megoldás
+ 1\. A sebesség a mozgás idő szerinti első deriváltja
+
+ $$
+ x'(t) = 2t \qquad y'(t) = -1 / t^2
+ $$
+
+ 2\. Ezt szeretnénk tudni az $1$ időpontban
+
+ $$
+ x'(1) = 2 \qquad y'(1) = -1 / 1
+ $$
+
+ 3\. Ebből a sebesség
+
+ $$
+ v = \sqrt{2^2 + (-1)^2} = \sqrt{5}
+ $$
+
+ 4\. Vagyis a sebesség négyzete
+
+ $$
+ (\sqrt{5})^{2} = 5
+ $$
+
+---
+
+!!! question 5\. Az alábbi műveletek közül melyek asszociatívak?
+ - Komplex számok szorzata
+ - Vektorok skaláris szorzata
+ - Vektorok elemenkénti szorzata
+ - Duális számok szorzata
+ - Vektorok elemenkénti szorzata
+ - Mátrixok szorzata
+
+??? tip Megoldás
+ - [x] Komplex számok szorzata
+ - [ ] Vektorok skaláris szorzata
+ - [x] Vektorok elemenkénti szorzata
+ - [x] Duális számok szorzata
+ - [ ] Vektorok elemenkénti szorzata
+ - [x] Mátrixok szorzata
+
+---
+
+!!! question 6\. Az alábbi műveletek közül melyek kommutatívak?
+ - Vektorok skaláris szorzata
+ - Vektorok elemenkénti szorzata
+ - Duális számok szorzata
+ - Komplex számok szorzata
+ - Vektorok vektoriális szorzata
+ - Mátrixok szorzata
+
+??? tip Megoldás
+ - [x] Vektorok skaláris szorzata
+ - [x] Vektorok elemenkénti szorzata
+ - [x] Duális számok szorzata
+ - [x] Komplex számok szorzata
+ - [ ] Vektorok vektoriális szorzata
+ - [ ] Mátrixok szorzata
+
+---
+
+!!! question 7\. Válassza ki az alábbiakból az igaz állításokat, euklideszi geometriát feltételezve.?
+ - $\sinh(3x + 4y + 5) = 0$ egy egyenes
+ - A $3x+4y+5=0$ egyenletű egyenes különbözik a $9x+12y+15=0$ egyenletű egyenestől.
+ - $3x + 4y + 5 = 0$ egyenesre merőleges a $4x -3y + 5 = 0$
+ - $3x + 4y + 5 = 0$ egyenes megegyezik a $-3x -4y - 5 = 0$-tel
+ - $3x + 4y + 5 = 0$ egyenes párhuzamos a $9x 3y + 5 = 0$-tel
+
+??? tip Megoldás
+ - [x] $\sinh(3x + 4y + 5) = 0$ egy egyenes
+ - Magyarázat: A $\sinh$ függvény pontosan akkor nulla, ha a bemenete is nulla, tehát csak azok a pontok teljesítik a $\sinh$ féle egyenletet, amik a bemenő egyenes egyenletét is.
+ - [ ] A $3x+4y+5=0$ egyenletű egyenes különbözik a $9x+12y+15=0$ egyenletű egyenestől.
+ - Magyarázat: Ha $e$ jelöli az első egyenest, akkor a második az $3 \cdot e$ alakú, és ez csak akkor nulla ha $e$ nulla, azaz csak azok a pontok teljesítik a $3 \cdot e = 0$ egyenletet amelyek az $e = 0$ egyenletet is.
+ - [x] $3x + 4y + 5 = 0$ egyenesre merőleges a $4x -3y + 5 = 0$
+ - Magyarázat: Az első irányvektora $(3,4)$, a másodiké $(4,-3)$, és ezek merőleges vektorok.
+ - [x] $3x + 4y + 5 = 0$ egyenes megegyezik a $-3x -4y - 5 = 0$-tel
+ - Magyarázat: Ugyan az a logika mint korábban, ha az első egyenes $e$, akkor a második egyenlet $-e = 0$, ami csak akkor igaz, ha $e=0$, azaz teljesül az első egyenlet.
+ - [x] $3x + 4y + 5 = 0$ egyenes párhuzamos a $9x + 12y + 5 = 0$-tel
+ - Magyarázat: Az első egyenes irányvektora $v = (3,4)$, a másodiké pedig $v' = (9, 12) = 3v$, és mivel $v = \lambda v'$, ezért $v \parallel v'$.
+
+---
+
+!!! question 8\. Válassza ki az alábbiakból az euklideszi geometria érvényes műveleteit, azaz azokat, amelyeknél az eredmény értelmezhető euklideszi geometriában, ha az operandusok értelmesek voltak.
+ - pont szorzása vektorral
+ - két vektor összege
+ - pont és vektor összege
+ - két pont összege
+ - két vektor kombinációja
+ - két pont kombinációja
+ - vektor szorzása számmal
+
+??? tip Megoldás
+ - [ ] pont szorzása vektorral
+ - [x] két vektor összege
+ - [x] pont és vektor összege
+ - [ ] két pont összege
+ - [x] két vektor kombinációja
+ - [x] két pont kombinációja
+ - [x] vektor szorzása számmal
+
+---
+
+!!! question 9\. Jelölje be az alábbi állítások közül azokat, amelyek igazak gömbi geometriában.
+ - Két különböző egyenes mindig egyetlen pontban metszi egymást
+ - Az egyenes két pont közötti legrövidebb út.
+ - A háromszög szögeinek összege $180$ fok
+ - A sík görbülete pozitív
+ - A Pitagorasz tétel igaz
+ - Két nem egybevágó háromszög lehet hasonló
+
+??? tip Megoldás
+ - [ ] Két különböző egyenes mindig egyetlen pontban metszi egymást
+ - [x] Az egyenes két pont közötti legrövidebb út.
+ - [ ] A háromszög szögeinek összege $180$ fok
+ - [x] A sík görbülete pozitív
+ - [ ] A Pitagorasz tétel igaz
+ - [ ] Két nem egybevágó háromszög lehet hasonló
diff --git a/docs/notes/sem4/computer_graphics/lectures/10.md b/docs/notes/sem4/computer_graphics/lectures/10.md
new file mode 100644
index 0000000..46fe39f
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/10.md
@@ -0,0 +1,646 @@
+
+
+# Játékfejlesztés
+
+## Virtuális valóság
+
+Az egyes játékokban a számítógépünk RAM-jában "élnek" a játékobjektumok, de mit is jelent az, hogy "élnek"? A mi esetünkben azt, hogy van állapotuk, és ezt az állapotot tudják változtatni a világ és a többi objektum állapota alapján. Ha minden objektum ezt csinálja, akkor a rendszerünk életre tud kelni. Viszont kell lennie egy kitüntetett objektumnak, ami az állapotát nem csak a többi objektum és a világ alapján változtatja, hanem a külvilág, a játszó ember alapján is. Ez az objektum reprezentál minket a virtuális világban, ez az _avatár_ képvisel minket. Ő a szemünk (az ő szemszögéből látjuk a virtuális világot) és őt vezéreljük, szemben a többi objektummal, akik magukról döntenek.
+
+## Feladatok
+
+- képszintézis az avatár nézőpontjából (a mi esetünkben csak egy darab szemből)
+- avatár vezérlése valamilyen beviteli eszközzel (akár többel, legtöbbször keyboard-al)
+- intelligens objektumok (AI/állapotgép)
+- a fizika világ szimulációja (legtöbbször Newtoni fizika, mert ez az ismerős)
+
+Ezek a feladatok annyira általánosak, hogy szinte minden játéknak a részei, ezért ezeket előre elkészíthetjük egy általános formában, azaz egy keretrendszer (ún. game engine) formájában. A game engine-nek hála nekünk elég csak a játék konkrétumait, működését és kinézetét megadni, leprogramozni.
+
+## Objektum orientáltság
+
+Létre kell hozni az objektumokat, amik a játékban lesznek (`Build()`), viszont ezután el kell dönteni, hogy melyik objektumnak milyen műveletek kellenek. Minden objektum frissíti a saját állapotát (`Control()`), és ténylegesen fel is veszi ezt az új állapotot (`Animate()`, viszont ez még nem jelenik meg grafikusan! Ez egy belső állapotfelvétel.).
+
+!!! question Miért választjuk szét az állapot frissítését, és felvevését?
+ A valós világ aszinkron, de a számítógépünk egy szekvenciális szimuláció (gondoljunk csak az órajelre), tehát minden állapotváltozást csak egymás után tud szimulálni. Ha lenne 100 objektumunk, és ebből az egyik változna, akkor ő neki kell tudnia az összes többi objektum állapotát, hogy el tudja dönteni, hogy ő milyet kell felvegyen. Itt még nincsen semmi baj, viszont ha ezt rögtön fel is veszi, és a második objektum is meg akar változni, akkor gondba ütközünk: amikor a második objektum körbenéz, akkor ő 98 darab "régi" állapotban lévő objektumot lát, és 1 olyat, ami már egy új állapotban van. A harmadik objektum már két darab "új" állapotú objektumot látna, és a végére amikor az utolsó objektum akarná frissíteni az állapotát, már minden más objektum valami teljesen más állapotot vett fel, mint amikor ő állapotot akart frissíteni. A való világ persze nem így működik, szóval először minden objektum meghatározza, hogy mi lesz a következő állapota, és mindenki egyszerre veszi ezeket fel, amikor már senki sem számolja a saját állapotát a többiek állapota alapján.
+
+Az új állapotot meg is kell grafikusan jeleníteni (`Draw()`). Az avatár egy speciális objektum, tehát az ő esetében kell egy módszer arra, hogy irányítani tudjuk (`ProcessInput()`), és arra, hogy megmutassuk a felhasználónak, hogy mi a világ jelenlegi állapota (`setCameraTransform()`)
+
+{width=100%}
+
+Tekintsünk kicsit mélyebben a `GameObject` osztály implementációjába:
+
+### GameObject
+
+```cpp
+struct GameObject {
+ vec3 position, velocity, acceleration; // fizikai animációhoz
+ bool alive = true; // él még
+ float boundingRadius = 0; // ütközésdetektáláshoz
+
+ virtual void Control(float tstart, float tend, Scene * scene) { }
+ bool Collide(GameObject * obj); // diszkrét ütközésdetektálás
+ bool Collide(GameObject * obj, float& tHit, vec3& wHit); // folytonos ütközés
+ virtual void Animate(float tstart, float tend) { // állapotváltás
+ float dt = tend - tstart;
+ position += velocity * dt; // Euler-integrálás
+ velocity += acceleration * dt;
+ }
+ virtual void Draw(RenderState state) { } // rajzolás
+ virtual void Kill() { alive = false; }
+};
+```
+
+```cpp
+struct MeshGameObject : GameObject {
+ static PhongShader* shader; // árnyalóprogram
+ Texture* texture = nullptr;
+ Material* material = nullptr;
+ Mesh* geometry = nullptr;
+public:
+ virtual void SetModelingTransformation(RenderState& state) {
+ state.M = translate(position); state.Minv = translate(-position);
+ }
+ virtual void Draw(RenderState state) {
+ SetModelingTransformation(state); // modellezési transzformáció
+ state.material = material; state.texture = texture;
+ shader->Bind(state); // transzformációk, anyag, textúra a GPU-ra
+ geometry->Draw(); // az objektum végigmegy a szerelőszalagon
+ }
+};
+```
+
+A játékunk érzékelhető része `GameObject`-ekből áll, majdnem minden amit megjelenítünk egy `GameObject` (vagy annak leszármazottja, lásd fentebb a `MeshGameObject`-et). Ezek tárolás egy fa struktúrát követ, a gyökere a `Scene`, az összes többi csúcsban `GameObject`ek vannak, és ők is tartalmazhatnak más `GameObject`eket (`children`).
+
+Egy `GameObject` tudja magáról a megjelenítéséhez szükséges tulajdonságait és alakját. A kirajzoláskor ezeket beállítja a `RenderState`-be, mielőtt meghívná a `geometry`-ájára a kirajzolást. Fontos megemlíteni hogy az `M` transzformációs mátrixot (és inverzét) nem felülírja, hanem megszorozza az eddigi állapotot. Ez azért van így, mert a `GameObject`ek `child`-jainak helyzetét a `parent`-hez relatívan értelmezzük.
+
+??? example Példa a helyzet relatív értelmezéséhez
+ A `Scene` objektum indul a $(0, 0, 0)$ origó középpontból, a karakterünket direktben tartalmazza, melynek koordinátája egyenlő lesz a világbeli koordinátáival, mondjuk $(1, 1, 1)$. A karakter egyik `child` objektuma a kalapja, ennek koordinátái a (0, 0, 2), relatíven értelmezzük, tehát a karakterünk origójától lesz ilyen távolságban. Ha az ezekhez tartozó mátrixokat egymás után összeszorozzuk, kapjuk meg a `child` `GameObject`-ek tényleges világbeli pozícióját, itt ez most $(1, 1, 3)$ lenne.
+
+### Szimulációs hurok (Game loop)
+
+```cpp
+void onTimeElapsed(float tstart, float tend) {
+ scene->Simulate(tstart, tend);
+ refreshScreen();
+ }
+```
+
+Amikor a programunk éppen nem renderel, megmérjük az előző `Simulate` óta eltelt időt, majd meghívjuk a szimuláló függvényt:
+
+```cpp
+void Scene::Simulate(float tstart, float tend) {
+ avatar->ProcessInput();
+ const float dt = 0.01f; // dt kicsi
+ for (float t = tstart; t < tend; t += dt) {
+ float Dt = fmin(dt, tend - t);
+ for (auto* obj : objects) obj->Control(t, t+Dt, this);
+ for (auto* obj : objects) obj->Animate(t, t+Dt);
+ }
+```
+
+Mi itt a `Dt`? Ez az ún. _delta time_, ami méri két kirajzolt képkocka (azaz két szimulációs "update tick") közti időt. Ha az eltelt idő (`te - ts`) nagyon nagy, az szimulációs anomáliákhoz (pl. hibás ütközés, lásd [Ütközések](10.md/#ütközések)) vezethet, ezért bevezetünk egy maximum delta time változót (`dt`). Ha `te - ts` túllépné ezt a maximumot, akkor ezt az időegységet a biztonság kedvéért kisebb szeletekre bontjuk, kis lépésekben szimuláljuk le.
+
+A szimulálás után pedig kirendereljük a jelenlegi állapotot:
+
+```cpp
+void onDisplay() {
+ glViewport(0, 0, winWidth, winHeight);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ scene->Render();
+ }
+```
+
+ahol a `Render()`:
+
+```cpp
+void Scene::Render() {
+ RenderState state;
+ state.wEye = avatar->position; state.light = light;
+ state.V = avatar->V(); state.P = avatar->P();
+ for (auto* obj : objects) obj->Draw(state);
+ VolumetricGameObject::Flush(state);
+}
+
+```
+
+Figyeljük meg, hogy új `RenderState`t hozunk létre, `M` és `Minv` az egységmátrix lesznek, azaz nem nyújtunk, nem forgatunk, nem méretezünk.
+
+## Volumetric shader
+
+{width=100%}
+
+Kiterjedt, de nem egyértelműen meghatározható geometriájú térfogatok ("fuzzy"). Ezeknél vagy nem definiálható egy éles határ, vagy túlságosan számításigényes lenne, minimális előnyökért. Ezek tipikusan valamilyen szinten átlátszóak, a sűrűségük változó lehet. Kicsi pamacsokból rakjuk ezeket össze, ahol a pamacsok méretét, sűrűségét és színét változtatva tudunk elérni egy kívánt összhatást. A pamacs/flötyi (igen, ez a szakszó rá) geometriailag bonyolultnak tűnik, szóval csalunk: feltöltünk egy átlátszó képet a megjeleníteni kívánt pamacsról, és rátextúrázzuk a pamacs objektumokra (`VolumetricGameObject`, lásd alább).
+
+```cpp
+struct VolumetricGameObject : GameObject {
+ static VolumetricShader* shader; // árnyalóprogram
+ static Volume* volume; // az összes pamacs
+ static Texture* splatTexture; // pamacstextúra
+ // az összegyűlt pamacsok lefényképezése
+ static void Flush(RenderState state) {
+ glEnable(GL_PROGRAM_POINT_SIZE);
+ glEnable(GL_BLEND); // kompozitálás engedélyezése
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ splatTexture->Bind();
+ shader->Bind(state);
+ volume->Sort(state.wEye);
+ volume->Draw();
+ glDisable(GL_BLEND); // kompozitálás tiltása
+ }
+};
+```
+
+Mivel a kép határai átlátszóak, ezért nem lesz pontos határa. Viszont ha egy másik irányból is megnézzük a pamacsot, akkor lebukunk, hiszen a pamacsunk csak szemből néz ki úgy, ahogy akarjuk, hiszen egy képről beszélünk, végtelenül vékony. Viszont ha még egyet csalunk, akkor tudjuk orvosolni a problémát: ha folyton a néző felé forgatjuk a képet, akkor mindig pontosan azt látjuk, amit szeretnénk. Ezzel csak az a probléma, hogy feltűnő lehet, ha csak egy képet használunk, szóval a harmadik csalásunk az, hogy egy kép helyett mondjuk csinálunk 4-8 képet a pamacsunkról, mind különböző szögekben, aztán ezeket elforgatva rárakjuk az objektumunkra. Ha jól csináltuk, akkor már egy egész realisztikus képet kapunk a pamacsunkról.
+
+```glsl title="Vertex shader"
+uniform mat4 VP;
+uniform int viewportHeight;
+
+layout(location = 0) in vec3 wPos;
+layout(location = 1) in vec4 color;
+layout(location = 2) in float size;
+
+out vec4 modulated;
+
+void main() {
+ gl_Position = VP * vec4(wPos, 1.0f);
+ gl_PointSize = size * viewportHeight / gl_Position.w;
+ modulated = color;
+}
+```
+
+```glsl title="Fragment shader"
+uniform sampler2D textMap;
+
+in vec4 modulated;
+
+out vec4 outColor;
+
+void main() {
+ outColor = texture(textMap, gl_PointCoord.xy) * modulated;
+}
+```
+
+Ahhoz, hogy az átlátszóság működjön, kicsit kell állítgatni az OpenGL-t is CPU oldalról:
+
+```cpp
+glEnable(GL_PROGRAM_POINT_SIZE);
+glEnable(GL_BLEND);
+glBlendFunc(GL_SRC_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA);
+
+// VBO feltöltés a világkoord-ban
+// Draw
+glDisable(GL_BLEND);
+```
+
+{width=100%}
+
+### Billboard
+
+Mindig a kamera felé néző téglalap. Régen egy teljes téglalapra tették rá, de az OpenGL-be pontosan a pamacsok miatt behozták azt, hogy egy `Point`-ra is lehet textúrázni, így nem kell négy pontot eltárolin egy pamacsra, hanem elég csak egyet.
+
+```cpp
+vec3 w = wEye - pos; // szem felé mutat
+vec3 r = cross(up, w); // billboard vízszintes (jobb)
+vec3 u = cross(r, w); // billboard függőleges (fel)
+r = normalize(r) * size; // normalizáljuk és beállítjuk a méretet
+u = normalize(u) * size;
+```
+
+Tehát a transzformációs mátrixa:
+
+$$ \bold{T} =
+\begin{bmatrix}
+r_x & r_y & r_z & 0 \newline
+u_x & u_y & u_z & 0 \newline
+0 & 0 & 1 & 0 \newline
+pos_x & pos_y & pos_z & 1
+\end{bmatrix}
+$$
+
+## Avatar
+
+```cpp
+struct Avatar : public GameObject {
+ vec3 wVup;
+ float fov = M_PI / 2.0f, fp = 0.01f, bp = 100.0f;
+ float asp = (float)winWidth / winHeight;
+
+ virtual void ProcessInput() = 0;
+ mat4 V() { return lookAt(position, position + velocity, wVup); }
+ mat4 P() { return perspective(fov, asp, fp, bp); }
+};
+```
+
+A `wVup` lehet egyszerűen `[0, 1, 0]` vagy a pillanatnyi gyorsulásból és a korábbi `wVup` átlagából kaphatjuk meg.
+
+## Keyboard polling
+
+```cpp
+bool keys[256]; // is pressed?
+void onKeyboard(unsigned char key, int pX, int pY)
+{
+ keys[key] = true;
+}
+void onKeyboardUp(unsigned char key, int pX, int pY)
+{
+ keys[key] = false;
+}
+```
+
+Egy tömbben tároljuk, hogy éppen mi a billentyűk állása, a fenti két eseményben állítjuk. `Simulate` közben ebből a tömbből polloljuk az állását.
+
+## Euler karakterisztika
+
+Olyan objektumokat szeretnénk felrajzolni, amik a valóságban is létezhetnek (pl. nincsen végtelenül keskeny dolog a valóságban). Ezt úgy érjük el, hogy kiindulunk egy olyan alakzatból, amiről tudjuk, hogy a valóságban is létezhet (például egy kocka, vagy egy téglatest), ezután pedig olyan transzformációkat hajtunk végre rajta, amik "nem rontják el". Az ilyen féle transzformációkra azt mondjuk, hogy az Euler karakterisztika _invariáns_ alattuk. Az Euler karakterisztika az alábbi kifejezés:
+
+$$
+\text{csúcs} - \text{él} + \text{lap} = \chi
+$$
+
+ahol $\chi$ a felület topológiájától függ. Poliéderek esetén $\chi = 2$.
+
+## Frenet keret
+
+Egy transzformációval érjük el, hogy a nézőpont/geometria kijelölt "feje" a sebesség irányába nézzen.
+
+{width=100%}
+
+
+
+$$
+M =
+\begin{bmatrix}
+i' & j' & k' & r \\
+0 & 0 & 0 & 1 \\
+\end{bmatrix}
+$$
+
+### Levezetés
+
+Először kiszámoljuk a __nem ortonormált__ (ortonormált = vektorok merőlegesek egymásra és egység hosszúak) formájában:
+
+$$
+\begin{align*}
+j' &= v \\
+k^* &= k'(1-\alpha) + a \cdot \alpha \\
+i' &= j' \times k^*
+\end{align*}
+$$
+
+ahol $k'$ az előző tickben/állapotan lett meghatározva (kiindulásként lehet például $k' = a$), $\alpha$ pedig egy súlyozási tényező, lehetővé teszi hogy az új és az előző $k'$ előző között egy sima átmenetet biztosítsunk, és véd az $a = 0$ eset ellen is.
+
+Majd __ortogonalizáljuk__ (Gram-Schmidt ortogonalizáció):
+
+$$
+\begin{align*}
+j' &= v/|v| \qquad \text{(normalizáljuk)} \\
+i' &= \cfrac{j' \times k^* }{|j' \times k^*|} \qquad \text{(ezt is)} \\
+k' &= i' \times j' \qquad \text{(ezt már nem kell)}
+\end{align*}
+$$
+
+Esélyes hogy $a$ és $v$ nincs megadva. $r$ első deriváltja $v$, második deriváltja $a$.
+
+Ez kicsit leegyszerűsítve, $\alpha = 1$ esetben a következő:
+
+$$
+\begin{align*}
+j' &= \^v \\
+i' &= \^v \times \^a \\
+k' &= \^v \times \^a \times \^v
+\end{align*}
+$$
+
+## Ütközések
+
+Ütközés szempontjából mindent gömbként kezelünk (vagy belerakjuk az objektumot egy gömbbe, és azok a gömbök ütköznek), és a távolságuk alapján döntjük el, hogy összeérnek-e.
+
+```cpp
+bool GameObject::Collide(GameObject * obj) {
+ float dist = length(position - obj->position); // távolság
+ return (boundingRadius + obj->boundingRadius < dist);
+}
+```
+
+Probléma: ha az objektum gyors, és/vagy a delta time nagy, akkor átmehetünk az objektumokon anélkül, hogy ütköznénk vele (diszkrét eset).
+
+{width=100%}
+
+Megoldás: Folytonos ütközésdetektálás. Egy sugarat bocsátunk ki a mozgatás irányában, megnézzük hogy beleütközik-e valamibe.
+
+{width=100%}
+
+A koordinátákat a vizsgált objektumhoz rögzítjük.
+
+```cpp
+rel_pos = position - pos2
+rel_velocity = velocity - vel2
+Ray: rel_pos + rel_velocity * t
+
+if (ray intersects bounding sphere first && tintersect < dt)
+ //collision
+```
+
+Bár még mindig nem tökéletes, mivel a mozgatott objektumnak nem vesszük figyelembe a kiterjedését.
+
+## Részecskerendszer (particle system)
+
+
+
+Példának vegyünk porszemcséket, amit a szél fúj. Ezt a szelet tekintsük egy erőtérnek.
+
+```text
+pos: pos += velocity * dt
+velocity: velocity += acceleration * dt
+acceleration: acceleration = force / weight
+lifetime: random kezdeti érték
+age: age += dt; if (age > lifetime) Kill();
+size, dsize: size += dsize * dt;
+weight, dweight: weight += dweight * dt
+color, dcolor: color += dcolor * dt
+```
+
+---
+
+# Kvíz
+
+!!! quote ""
+ A 2024/2025/II félévben nem voltak ebben a témában kvízek.
+
+!!! question 1\. A virtuális világban egy pontszerű test és egy gömb mozog. A pontszerű test a szimulációs időlépés kezdetén a $(1,2,5)$ pontban van (mértékegység parsec) és $(3,5,2)$ parsec/sec sebességgel halad. A gömb középpontja a szimulációs időlépés kezdetén a $(2,3,7)$ pontban van és $(9,6,2)$ parsec/sec sebességgel halad. Mekkora az a minimális gömbsugár, amely felett a két objektum a dt=100 msec időlépésben az intervallum elején tesztelő diszkrét ütközésdetektálási algoritmus szerint ütközik?
+
+??? tip Megoldás
+ Váltsuk át a pontszerű test koordinátáit a gömbhöz relatíven.
+
+ $$
+ \begin{align*}
+ p_r &= p_p - p_g = (1, 2, 5) - (2, 3, 7) = (-1, -1 -2) \\
+ v_r &= v_p - v_g = (3, 5, 2) - (9, 6, 2) = (-6, -1, 0)
+ \end{align*}
+ $$
+
+ Vegyük észre, hogy a pont egyre csak még inkább távolodni fog a gömbtől, ha ütközést szeretnénk detektálni azt mihamarabb.
+
+ Időlépés intervallum **elején** tesztelő, **diszkrét**
+
+ Magyarán az első teszt $t = 0 \cdot dt$ időben fut le. Ekkor a távolságuk $|p_r| = \sqrt{6} \approx 2.45$
+
+---
+
+!!! question 2\. Egy test $3$ darab különálló poliéder részből áll, és egyik rész sem tartalmaz lyukat. A testen összesen $10$ csúcsot és $18$ lapot számoltunk meg. Hány éle van?
+
+??? tip Megoldás
+
+ Euler karakterisztika invariánst felhasználva:
+
+ $$
+ \text{csúcs} - \text{él} + \text{lap} = \chi
+ $$
+
+ Egy egyszeresen összefüggő (lyuk nélküli) poliéderre az Euler-karakterisztika $2$. Mivel itt $3$ különálló testről van szó, a teljes karakterisztika $6$.
+
+ Behelyettesítve ez
+
+ $$
+ 6 = 10 - \text{él} + 18 \implies \text{él} = 22
+ $$
+
+---
+
+!!! question 3\. Egy billboard (plakát) referencia helyzetében az origóban van és az $x, y$ síkra fekszik. Adjuk meg a modellezési transzformáció elemeit egy értékes jegyre, ha a
+ - a billboard mérete nem változik a transzformáció során
+ - a szem a világ $(4,2,7)$ pontjában van
+ - a billboard által reprezentált objektum a $(1,2,3)$ pontban van
+ - a billboard preferált függőleges iránya a $(0,1,0)$
+
+??? tip Megoldás
+ ```cpp
+ vec3 w = wEye - pos; // szem felé mutat
+ vec3 r = cross(w, up); // billboard vízszintes (jobb)
+ vec3 u = cross(r, w); // billboard függőleges (fel)
+ r = normalize(r) * size; // normalizáljuk és beállítjuk a méretet
+ u = normalize(u) * size;
+ ```
+
+ Kiszámoljuk $w, r, u$ értékeket:
+
+ $$
+ \begin{align*}
+ w &= \text{eye} - \text{pos} = (3, 0, 4) \\
+ r &= \text{up} \times w = (4, 0, -3) \rightarrow \^{r} = (-0.8, 0, 0.6) \\
+ u &= r \times w = (0, 25, 0) \rightarrow \^{u} = (0, 1, 0)
+ \end{align*}
+ $$
+
+ Behelyettesítünk:
+
+ $$
+ \begin{bmatrix}
+ r_x & r_y & r_z & 0 \\
+ u_x & u_y & u_z & 0 \\
+ 0 & 0 & 1 & 0 \\
+ pos_x & pos_y & pos_z & 1
+ \end{bmatrix} =
+ \begin{bmatrix}
+ 0.8 & 0 & -0.6 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 1 & 2 & 3 & 1
+ \end{bmatrix}
+ $$
+
+---
+
+!!! question 4\. Egy FPS játékban az avatár pillanatnyi pozíciója $(0, 0, 0)$, sebessége $(6, 8, 0)$, gyorsulása $(12, -9, 0)$. A kamera orientációt a Frenet kerettel állítjuk be. Mi lesz a kamera View transzformációja?
+
+
+??? tip Megoldás
+ Nincs mese, ki kell számolni.
+
+ $$
+ \begin{align*}
+ r &= (0, 0, 0) \\
+ j' &= \^v = (0.6, 0.8, 0) \\
+ i' &= \^v \times \^a = (0.6, 0.8, 0) \times (0.8, -0.6, 0) = (0, 0, -1) \\
+ k' &= i' \times j' = (0.8, -0.6, 0)
+ \end{align*}
+ $$
+
+ Ez egy transzformációs mátrix, nem a kamera View transzformációja. Tehát a mátrix:
+
+ $$
+ \bold{T}_V =
+ \begin{bmatrix}
+ 1 & 0 & 0 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ -e_x & -e_y & -e_z & 1 \\
+ \end{bmatrix}
+ \begin{bmatrix}
+ u_x & u_y & u_z & 0 \\
+ v_x & v_y & v_z & 0 \\
+ w_x & w_y & w_z & 0 \\
+ 0 & 0 & 0 & 1 \\
+ \end{bmatrix}^{-1}
+ $$
+
+ Ahol:
+
+ $$
+ \begin{align*}
+ e &= r \\
+ u &= i \\
+ v &= k \\
+ w &= -j
+ \end{align*}
+ $$
+
+ (ugye nem felejtettük el, hogy a view $-z$ irányba néz, és azt szeretnénk, hogy a irányába nézzünk)
+
+ A megfeleltetés után, és annak tudatában, hogy a második mátrix ortonormált (tehát inverze önmaga transzponáltja)
+
+ $$
+ \begin{bmatrix}
+ 1 & 0 & 0 & 0 \\
+ 0 & 1 & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{bmatrix}
+ \begin{bmatrix}
+ 0 & 0 & -1 & 0 \\
+ 0.8 & -0.6 & 0 & 0 \\
+ -0.6 & -0.8 & 0 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{bmatrix}^{-1}=
+ \begin{bmatrix}
+ 0 & 0.8 & -0.6 & 0 \\
+ 0 & -0.6 & -0.8 & 0 \\
+ -1 & 0 & 0 & 0 \\
+ 0 & 0 & 0 & 1
+ \end{bmatrix}
+ $$
+
+---
+
+!!! question 5\. Egy játékobjektum orr iránya referencia helyzetben az $y$ tengely, függőleges iránya pedig a $z$ tengely. Az objektum pályája $r(t)=(\cos(t), \sin(t), t)$.
+ Adjuk meg a modellezési transzformáció elemeit egy értékes jegyre a $t=\pi/4$-re, ha az objektumot Frenet keret módszerrel animáljuk.
+
+
+
+??? tip Megoldás
+ Tudjuk, hogy:
+
+ $$
+ \begin{align*}
+ r(t) &= (\cos(t), \sin(t), t) \\
+ v(t) &= \dot{r}(t)=(-\sin(t), \cos(t), 1) \\
+ a(t) &= \"r(t)=(-\cos(t), -\sin(t), 0)
+ \end{align*}
+ $$
+
+ Ezek a $t=\cfrac\pi 4$ helyen:
+
+
+ $$
+ \begin{align*}
+ r(\frac\pi 4) &= \left(\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, \frac\pi 4\right) \\
+ v(\frac\pi 4) &= \left(-\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, 1\right) \\
+ a(\frac\pi 4) &= \left(-\frac{\sqrt{2}} 2, -\frac{\sqrt{2}} 2, 0\right)
+ \end{align*}
+ $$
+
+ És akkor számolunk...
+
+ $$
+ \begin{align*}
+ r &= \left(\frac{\sqrt{2}} 2, \frac{\sqrt{2}} 2, \frac\pi 4\right) \\
+ j' &= \^v = \left(-\frac 1 2, \frac 1 2, \frac{\sqrt{2}} 2\right) \\
+ i' &= \^v \times \^a = \left(\frac 1 2, -\frac 1 2, \frac{\sqrt{2}} 2\right) \\
+ k' &= i' \times j' = \left(-\frac{\sqrt{2}} 2, -\frac{\sqrt{2}} 2, 0\right)
+ \end{align*}
+ $$
+
+ Tehát a mátrixunk nem más, mint
+
+ $$
+ M =
+ \begin{bmatrix}
+ i' & 0 \\
+ j' & 0 \\
+ k' & 0 \\
+ r & 1 \\
+ \end{bmatrix}
+ =
+ \begin{bmatrix}
+ \frac1 2 & -\frac 1 2 & \frac{\sqrt{2}} 2 & 0 \\
+ -\frac1 2 & \frac 1 2 & \frac{\sqrt{2}} 2 & 0 \\
+ -\frac{\sqrt{2}} 2 & -\frac{\sqrt{2}} 2 & 0 & 0 \\
+ \frac{\sqrt{2}} 2 & \frac{\sqrt{2}} 2 & \frac\pi 4 & 1
+ \end{bmatrix}
+ =
+ \begin{bmatrix}
+ 0.5 & -0.5 & 0.7 & 0 \\
+ -0.5 & 0.5 & 0.7 & 0 \\
+ -0.7 & -0.7 & 0 & 0 \\
+ 0.7 & 0.7 & 0.8 & 1
+ \end{bmatrix}
+ $$
+
+---
+
+!!! question 6\. Az alábbi programsorok egy szimulációs hurkot (game loop) valósítanak meg, de nem jól működik. Válassza ki a hibás sorokat:
+ ``` cpp linenums="1"
+ void onIdle ( ) { // idle call back
+ float tend = 0;
+ float tstart = tend;
+ tend = glutGet(GLUT_ELAPSED_TIME)/1000;
+ avatar->ProcessInput( );
+ for(float t = tstart; t < tend; t += dt) {
+ float Dt = min(dt, tend - t);
+ for (GameObject * obj : objects) obj->Control(dt);
+ for (GameObject * obj : objects) obj->Animate(dt);
+ }
+ onDisplay();
+ }
+ ```
+
+??? tip Megoldás
+ ```cpp hl_lines="2 4 9 11" linenums="1"
+ void onIdle ( ) { // idle call back
+ float tend = 0;
+ float tstart = tend;
+ tend = glutGet(GLUT_ELAPSED_TIME)/1000;
+ avatar->ProcessInput( );
+ for(float t = tstart; t < tend; t += dt) {
+ float Dt = min(dt, tend - t);
+ for (GameObject * obj : objects) obj->Control(dt);
+ for (GameObject * obj : objects) obj->Animate(dt);
+ }
+ onDisplay();
+ }
+ ```
+
+ - Hibás sorok
+ - 2: `tend` vagy `static`, vagy a függvényen kívül kell léteznie, nem nullázhatjuk mindig
+ - 4: nem kell leosztanunk milliszekundumra
+ - 9, 11: először animálunk, utána irányítunk
+
+---
+
+!!! question 7\. Mely problémák megoldásánál használnak Gram-Schmidt ortogonalizációt?
+
+??? tip Megoldás
+ - [x] Billboard (plakát)
+ - [x] Frenet keret
+ - [x] 3D kamera transzformáció
+ - [ ] Fizikai animáció
+ - [ ] 2D kamera transzformáció
+
+---
+
+!!! question 8\. Egy kockát két szinten Catmull-Clark algoritmussal felosztunk. Hány háromszög keletkezik?
+
+??? tip Megoldás
+ Catmull-Clark algoritmusnál $1$ négyszögből csinálunk $4$-et. $\newline$
+ Ezt kétszer is megcsináljuk: $6 \cdot 4 \cdot 4 = 96$ négyszög, ami kétszer ennyi háromszög, azaz $192$.
diff --git a/docs/notes/sem4/computer_graphics/lectures/11.md b/docs/notes/sem4/computer_graphics/lectures/11.md
new file mode 100644
index 0000000..013fbb3
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/11.md
@@ -0,0 +1,1113 @@
+
+
+# Vektorháború
+
+## Vektoralgebra alapjai
+
+Mi a vektor fogalmat jelenleg úgy fogjuk értelmezni, hogy egy hossz és egy távolság. Két pont viszonyát jellemzi; megmondja, hogy az egyik távol van a másiktól, és milyen irányban van. Úgy is fel lehet fogni, mint egy _eltolás_, hiszen megmondja, hogy egy pontot milyen módon kéne eltolni, hogy egy másik pontba kerüljünk. Koordinátákkal számolható, de szerkeszthető is (tenzor).
+
+??? example "Tenzor? Azt eszik vagy isszák?"
+ A tenzor egy eléggé nehezen felfogható fogalom tud lenni és bár ebben a tárgyban nem igazán fog felmerülni, ha valakit mégis mélyebben érdekelne a téma, akkor ajánljuk az [I never intuitively understood Tensors...until now! (FloatHeadPhysics)](https://www.youtube.com/watch?v=k2FP-T6S1x0) videót, melyben egész érthetően, pár példán keresztül elmagyarázzák a fogalmat.
+
+ TL;DR: a "skalár" és "vektor" kifejezések általánosítása
+
+Szeretnénk műveleteket is értelmezni ezeken a vektorokon, kezdjük például az összeadással. Általánosságban a matematikai tanulmányunk során pár dolgot már megszoktunk az összeadással kapcsolatban ([gyűrű axiómák](../appendix/math_appendix.md#gyűrűk-testek-csoportok-stb)). Egy ilyen tulajdonság például, hogy legyen _zárt_: két szám összege egy szám, két mátrix összege egy mátrix. Hasonlóan, két vektor összegét is szeretnénk, ha egy vektor lenne. Ezen felül még nem bánjuk, ha a műveletünk kommutatív, és asszociatív. Ha a vektorokra úgy gondolunk, mint eltolások, akkor ez a művelet magától értetődő lesz: két eltolás összege az szimplán az, ha elvégezzük a két eltolást egymás után.
+
+Mivel figyeltünk arra, hogy egy "szép" műveletet válasszunk, ezért kipottyant az is, hogy ez az összeadás _invertálható_. Az eltolás inverze a "vissza tolás", tehát egy olyan vektor, mely ugyanolyan hosszú, de ellentétes irányú, mint az eredeti vektorunk.
+
+Általánosságban a vektorokat nem csak eltolni lehet, hanem forgatni, skálázni is. Ezeket összefoglalóan az alábbi alakban lehet felírni:
+
+$$
+[x', y', 1] = [x, y, 1]
+\begin{bmatrix}
+a & e & 0\\
+b & f & 0\\
+c & d & 1\\
+\end{bmatrix}
+$$
+
+Na már haladunk, van összeadásunk. Szeretnénk tudni szorozni is, viszont itt problémákba ütközünk. Vizsgáljuk meg az egyes "szorzásokat", amikről eddig hallhattunk a vektorok vonatkoztatásában:
+
+### Skaláris szorzás (dot product)
+
+Vegyünk két $v, a$ vektort. Jelölje ezek skaláris szorzatát $b \in \R$. Ekkor ha $\cdot$ jelöli a skaláris szorzást:
+
+$$
+v \cdot a = b \stackrel{\text{def}}{\iff} |v||a|\cos(\alpha) = b
+$$
+
+Ezzel több problémánk is van. Először is nem zárt, hiszen az eredmény egy skalár ($v$-nek $a$-ra vett vetületének hossza), és ezáltal nem is lehet asszociatív, hiszen $x \cdot y \cdot z$ esetén ha az elsőt végezzük el előbb, akkor egy $z$-vel párhuzamos vektort kapunk, ha a másodikat, akkor pedig egy $x$-el párhuzamosat.
+
+Nem is invertálható, mert ha megpróbálnánk, akkor nem teljesülne az _egyértelműség_ feltétele (ugyan annak a műveletnek ugyan azokkal az értékekkel nem lehet két különböző eredménye). Nézzük, hogy miért:
+
+$$
+v \cdot a = b
+$$
+
+inverze az lenne, ha ismerve a $b \in \R$ és $a$ vektort, meg akarnánk állapítani a $v$ vektort:
+
+$$
+v = \frac{b}{a}
+$$
+
+alakban. Ezzel viszont az a baj, hogy túl sok ismeretlenünk van. Ismerjük a $b$ skalárt és az $a$ vektort méretét és hosszát, viszont ez eredmény vektor hosszát és irányát egyáltalán nem tudjuk. A definíciót tudjuk csak felhasználni, azaz csak egy egyenletünk van ($|v||a|\cos(\alpha)$), de ebből se $|v|$-t, se $\alpha$-t nem ismerjük. Ez geometriailag azt jelenti, hogy több különböző olyan vektor is létezik, amelynek $a$ a merőleges vetülete. Egy műveletnek több eredménye még sem lehet, szóval ez nem igazán egy "rendes" szorzás.
+
+### Vektoriális szorzás (cross product)
+
+Ez a művelet eleve csak háromdimenziós vektorokra van értelmezve, szóval eleve kizárt, hogy általános vektor szorzás lehessen, de azért vizsgáljuk meg. A jele $\times$. Két $a, b$ vektor vektoriális (más szóval kereszt) szorzata azon $c$ vektor, melyre igazak az alábbiak:
+
+- $|c| = |a||b|\sin(\alpha)$,
+- $c$ merőleges az $a$ és $b$ által kifeszített síkra,
+- $c$ irányát a jobbkéz-szabály alapján határozzuk meg.
+
+Ez a művelet zárt, nem asszociatív, és antikommutatív ($a \times b = - b \times a$). Ez a művelet sem nem invertálható, hasonló okokból mint a skaláris szorzás.
+
+#### Tipp a kiszámítására
+
+Ha feladatokban meg kell határozni két vektor kereszt szorzatát, akkor van egy trükk hozzá, ami bár matematikailag nem igazán precíz, de annál hasznosabb:
+
+$$
+a \times b =
+\begin{vmatrix}
+ \underline{i} & \underline{j} & \underline{k} \\
+ a_x & a_y & a_z \\
+ b_x & b_y & b_z
+\end{vmatrix}
+$$
+
+azaz egy olyan mátrix determinánsa, aminek az alsó két sora az $a$ és $b$ vektorok koordinátái, a felső sora pedig $\R^3$ bázisvektorai. Vegyesen kezelni számokat és vektorokat egy mátrixban, és determinánst számolni erre a mátrixra kicsit vadul hangzik, viszont ha mégis kiszámoljuk a determinánst (például a [Sarrus-szabály](https://en.wikipedia.org/wiki/Rule_of_Sarrus) felhasználásával), utána pedig $\underline{i}, \underline{j}$ és $\underline{k}$ szerint csoportosítjuk a tagokat, akkor az eredmény vektor első koordinátája az $\underline{i}$ bázisvektor együtthatója lesz, a második a $\underline{j}$, a harmadik pedig a $\underline{k}$:
+
+$$
+a \times b = [\overbrace{a_y b_z - b_y a_z}^{\displaystyle c_x}, \overbrace{a_z b_x - b_z a_x}^{\displaystyle c_y}, \overbrace{a_x b_y - b_x a_y}^{\displaystyle c_z}]
+$$
+
+### Külső szorzat (wedge product)
+
+A skaláris szorzat két vektorhoz egy alacsonyabb dimenziójú struktúrát rendelt, egy számot. A kereszt szorzat egy ugyan olyan dimenziójú objektumot rendel két vektorhoz. Tudnánk olyan műveletet értelmezni, ami két vektorhoz egy magasabb szintű objektumot rendel hozzá? A válasz az, hogy igen, ez pedig a külső szorzat lesz. A jele $\wedge$.
+
+Ha $\R^2$ beli vektorokat nézünk, akkor $v_1 \wedge v_2$ egy _irányított terület_ lesz. Mit értünk azon, hogy irányított terület? Az eredmény mérete, azaz $|v_1 \wedge v_2|$ megegyezik a $v_1, v_2$ által kifeszített paralelogramma területével, azaz visszaköszön a vektoriális szorzatnál megismert képlet: $|v_1 \wedge v_2| = |v_1||v_2|\sin(\alpha)$. Az, hogy ez a terület "irányított" annyit jelent, hogy számít a körbejárásának sorrendje: $v_1 \wedge v_2 = - v_2 \wedge v_1$. Természetesen $\R^3$ beli vektorok esetén egy irányított térfogatot kapnánk, és ez magasabb dimenziókra is kiterjeszthető.
+
+Az ilyen irányított területeket más szóval _bivektoroknak_ nevezzük. Fontos még kiemelni, hogy a terület alakja egyáltalán nem érdekes, csak a nagysága, és a körüljárás iránya. Asszociatív, antikommutatív és disztributív.
+
+### Szorzás összefoglalás
+
+Láttuk, hogy se a skaláris, se a vektoriális szorzat nem igazán felel meg "igazi szorzásnak" az algebránkban. Az lesz a megoldás, hogy nem a sima vektorokat fogjuk az alap objektumainknak tekinteni, hanem az úgynevezett _multivektorokat_. Ehhez viszont előbb meg kell ismerkednünk a multivektorok algebrájával, a Clifford algebrával.
+
+## Geometriai (Clifford) algebra
+
+Mielőtt rátérünk a konkrét a geometriai algebrára, illetve az itt definiált "igazi szorzásra", előtte kell tartanunk egy kicsi szemléletformáló kitérőt.
+
+### Szemléletformáló kitérő
+
+Az összeadásra és a skálázásra jól működtek a vektoraink, de ha belegondolunk, akkor ez nem meglepő, hiszen szinte bármilyen "nem szám" objektumra ez a két művelet könnyen értelmezhető. Például ha vannak narancsaink meg citromjaink, akkor ezeket is össze tudjuk adni: ha Aladárnak van két narancsa és egy citroma, Bélának meg egy narancsa és két citroma, akkor ha összeülnek, hogy vacsorázzanak, akkor három-három narancsuk és citromjuk lesz összesen. Annak a kijelentésnek is van értelme, hogy "megduplázom a citromjaid számát". Összegezve, ha az algebrai kifejezéseinkben csak összeadni, és skalárral szorozni szeretnénk, akkor egy cseppet sem zavar minket, ha "nem szám" objektumok is vannak a kifejezésben.
+
+Viszont a szorzás már egy picit szigorúbb művelet: hogyan tudnánk összeszorozni Aladár és Béla uzsonnáit? Az eredményben milyen objektumok lehetnek egyáltalán? Számok, narancsok, citromok, citrancsok, ezek mind teljesen valid gondolatok. Ahhoz, hogy ezt pontosan meg tudjuk mondani, valami kapcsolatot kell teremtenünk az objektumaink és a valós számok között. A vektorok esetén ez a koordinátás alak:
+
+$$
+\underline{v} = x \underline{e}_1 + y \underline{e}_2
+$$
+
+ahol $x,y \in \R$ számok, $\underline{e}_1$ és $\underline{e}_2$ pedig $R^2$ bázisvektorai. Ez egyféle kapcsolat a valós számok és az objektumaink között. Ezzel a kapcsolattal az volt a baj, hogy nem tudtunk rá elegáns szorzás műveletet definiálni. Próbáljunk meg kiindulni egy másik kapcsolatból, illetve azokból a tulajdonságokból, amiket tudjuk, hogy a műveletünknek birtokolnia kell, és próbáljunk meg ezekből levezetni egy szorzást.
+
+### Geometriai szorzás
+
+Ez a művelet (jelölje $\ast$) legyen asszociatív, disztributív és invertálható is. Induljunk ki abból a kapcsolatból, hogy bármely $v$ vektorra: $v * v \in \R$, azaz az eredmény legyen egy valós szám. Ebből a kapcsolatból elindulva:
+
+$$
+v * v = (x e_1 + y e_2) * (x e_1 + y e_2) = x^2 e_1 * e_1 + y^2 e_2 * e_2 + xy(e_1 * e_2 + e_2 * e_1)
+$$
+
+Mivel az $e_1, e_2$ bázisvektorok is vektorok, ezért ő rájuk is igaz, hogy $e_1 * e_1$ és $e_2 * e_2$ valós számok. Viszont mivel ezek bázisvektorok, ezért ennél egyszerűbb alakra már nem igazán hozhatóak, szóval itt muszáj döntést hoznunk: melyik valós számmal legyen egyenlő $e_1 * e_1$ és $e_2 * e_2$? Nem igazán a szám értéke a fontos, hanem inkább az előjele. A lehetséges választásaink az $1, 0, -1$. Mi most $e_1 * e_1 = e_2 * e_2 = 1$-et fogunk választani a geometriai algebránkban, viszont a többi választásra is kitérünk majd. Elöljáróban annyit, hogy a duális számok esetén -- mellyekkel deriválni fogjuk megtanítani a CPU-t -- az $e_1 * e_1 = e_2 * e_2 = 0$-át fogjuk választani, és komplex számok esetén pedig $e_1 * e_1 = 1$ és $e_2 * e_2 = -1$ (ez abból is látszik, hogy a komplex síkon az $x$-tengely menti bázisvektor az $1$, és $1 * 1 = 1$, az $y$-tengely menti bázisvektor pedig az $i$, és $i * i = -1$).
+
+Ha már kikötöttük, hogy $e_1 * e_1 = e_2 * e_2 = 1$, akkor az első két tag az összegünkben valós, már csak a harmadik taggal kell kezdeni valamit. Itt megjelenik a bázisvektorok vegyes szorzata, $e_1 * e_2$. Ha kikötnénk, hogy ezek is legyenek valós számok, akkor lényegében azt mondanánk, hogy bármely két vektor geometriai szorzata valós szám lenne, de ez a művelet már létezik, ez a skaláris szorzás.
+
+Mivel nem igazán tudunk mit kezdeni a vegyes szorzatok eredményével, ezért máshogy oldjuk meg a problémát: nekünk igazából elég lenne az, ha az utolsó tag ($xy(e_1 * e_2 + e_2 * e_1)$) valahogy eltűnne. Ezt elérhetjük úgy, hogy azt mondjuk, hogy $xy(e_1 * e_2 + e_2 * e_1) = 0$. Ekkor a fenti $v * v$ képletben az eredmény tényleg valós lesz, és elkerültük a problémánkat.
+
+Viszont ha azt mondjuk, hogy $xy(e_1 * e_2 + e_2 * e_1) = 0$, akkor az csak akkor lehet igaz, ha $e_1 * e_2 = - e_2 * e_1$, azaz a műveletünk antikommutatív.
+
+Az $e_1 * e_2$ művelet eredményét valahogy muszáj jelölnünk, szóval próbáljuk meg a legáltalánosabb módon, a legkevesebb dolgot feltételezve: $e_1 * e_2$ eredménye legyen $e_{12}$ bivektor, ez a területeket hivatott leírni. Ezek alapján próbáljuk meg meghatározni két tetszőleges vektor szorzatát:
+
+$$
+\begin{align*}
+v_1 * v_2 &= (x_1 e_1 + y_1 e_2) * (x_2 e_1 + y_2 e_2) \\
+&= x_1 x_2 + y_1 y_2 + (x_1 y_2 - x_2 y_1)e_1 * e_2
+\end{align*}
+$$
+
+Azt látjuk, hogy két vektor geometriai szorzata egy valós részből ($x_1 x_2 + y_1 y_2$) illetve egy bivektor részből ($(x_1 y_2 - x_2 y_1)e_1 * e_2$) áll, ahol a bivektor pontosan a $v_1$ és $v_2$ által kifeszített paralelogramma területével van megszorozva. Viszont ezek a műveletek ismerősek lehetnek, hiszen a valós rész az pont $v_1 \cdot v_2$, a bivektoros rész pedig pont $v_1 \wedge v_2$, tehát összegezve:
+
+$$
+\boxed{
+ v_1 * v_2 = v_1 \cdot v_2 + v_1 \wedge v_2
+}
+$$
+
+### Invertálás
+
+Most, hogy van egy "jól viselkedő" szorzás műveletünk, nézzük meg, hogy ezt hogyan tudjuk invertálni. A gyűrű axiómákhoz visszanyúlva, a szorzás invertálhatósága alatt azt értjük, hogy minden $v$ vektornak létezik egy $v^{-1}$ _inverze_, melyre igaz, hogy $v * v^{-1} = 1$. Mivel ebben a kifejezésben nincsen bivektoros tag, ezért gyanús, hogy valami olyasmi irányba kell elindulnunk, amely során a bivektoros tag nulla.
+
+Vizsgáljuk meg újra a $v * v$ kifejezést. A főképletbe behelyettesítve azt kapjuk, hogy:
+
+$$
+v * v = v \cdot v + v \wedge v
+$$
+
+viszont $v \wedge v$-ről tudjuk, hogy egy olyan irányított terület, aminek a nagysága a két operandusa által kifeszített paralelogramma területe. Viszont ha a két vektorunk egybevágó, akkor nem feszítenek ki egy paralelogrammát, vagy ha nagyon rá akarjuk erőltetni, akkor egy $0$ területű paralelogrammát feszítenek ki. Ez nekünk pont megfelelő, hiszen ebben a kifejezésben sincsen bivektoros tag.
+
+Láttuk, hogy $v * v = v \cdot v = |v|^2$. Ha azt akarjuk, hogy $v * v^{-1} = 1$ teljesüljön, akkor a $v^{-1} = \frac{v}{v*v}$ választással elértük a célunkat:
+
+$$
+v * v^{-1} = v * \frac{v}{v*v} = v * v * \frac{1}{|v|^2} = \frac{|v|^2}{|v|^2} = 1
+$$
+
+### Belső szorzás
+
+A $\underline{v}$ vektor és $\bm{I}$ bivektor belső szorzatának eredménye egy olyan vektor, amely az $\bm{I}$ bivektor síkjában fekszik, és merőleges a $\underline{v}$ vektor $\bm{I}$ síkjára eső vetületére.
+
+Ez a művelet rendkívül hasznos, mert egyetlen, koordináta-rendszertől független operációban valósítja meg a vetítés és a síkbeli forgatás kombinációját. Hagyományos vektoralgebrában, ugyanehhez több lépésre és mátrixműveletre lenne szükség.
+
+{width=100%}
+
+#### 1\. Vetítés a síkra
+
+A kiindulási vektorunk a kék vektor, nevezzük $v$-nek (a piros és a zöld vektor a bivektort alkotó vektorok). Ez a vektor általános esetben nem fekszik a bivektor által meghatározott síkban. A belső szorzat szempontjából a vektornak csak a bivektor síkjára eső része, vagyis a vetülete számít. A fekete vektor a $v$ merőleges vetülete a síkon. Ezt a vektorkomponenst $v_{\parallel}$-nek nevezzük.
+
+A $v$ vektornak van egy síkra merőleges komponense is ($v_{\perp}$), de a belső szorzat ezt a komponenst "figyelmen kívül hagyja". Matematikailag ez azért van, mert a merőleges komponens és a bivektor szorzata egy magasabb fokú objektumot, egy trivektort hozna létre, amit a belső szorzat (ami egy fokszám-csökkentő művelet) definíció szerint nulláz.
+
+#### 2\. Forgatás a síkban
+
+Miután megvan a $v$ vektornak a bivektor síkjában fekvő $v_{\parallel}$ vetülete, a belső szorzat ezen a vetületen egy $90\degree$-os forgatást hajt végre a bivektor síkján belül. Ezt a... másik fekete vektor jelöli... yeah...
+
+A forgatás iránya a bivektor orientációjától (elvégre egy irányított terület) függ.
+
+### 2D geometriai algebra
+
+Nézzük meg a Clifford algebra egy konkrét alkalmazását, arra az esetre, ha két dimenzióval dolgozunk. Láttuk, hogy két vektor geometriai szorzata egy valós számot és egy bivektort eredményez, de ha erre az eredményre tovább ismételgetjük a szorzást, akkor a végén vegyesen lesznek számaink, vektoraink, és bivektoraink. Az ezeket összefogó algebrai objektum, amivel dolgozunk, az a _multivektor_:
+
+$$
+\mathbf{V} = s + xe_1 + ye_2 + Be_{12}
+$$
+
+ahol $s$ egy szám, $e_1, e_2$ a bázisvektoraink, $e_{12}$ pedig a bivektorunk, azaz egy irányított terület. Az összeadásuk, és a skálázásuk a szokásos módon történik, pont ugyan úgy, mint ahogy a sima vektorok koordinátáival járunk el: összeadni skalárt a skalárral, vektort a vektorral, bivektort a bivektorral, stb...
+
+Nézzük meg, hogy a szorzásra hogyan viselkednek a multivektorok:
+
+- skalár szorzása skalárra, vektorral, illetve bivektorral: ez a szokásos módon történik
+- két bivektor szorzata:
+
+$$
+e_{12} * e_{12} = e_{1} * e_{2} * e_{1} * e_{2}
+$$
+
+a középső két tagot felcserélhetjük, de az antikommutativitás miatt bejön egy $-1$-es szorzó:
+
+$$
+e_{1} * e_{2} * e_{1} * e_{2} = -1 * e_{1} * e_{1} * e_{2} * e_{2} = -1 * (1) * (1) = -1
+$$
+
+Azt láttuk tehát, hogy ha úgy választjuk meg a multivektorainkat, hogy $\underline{v} = \underline{0}$, akkor a komplex számokat kapjuk meg. Emiatt ezentúl a $e_{12} = \bm{I}$ jelölést fogjuk alkalmazni.
+
+- bivektor és vektorok szorzata (jobbról és balról eltérő):
+
+$$
+\underline{v} * \bm{I} = (x e_1 + y e_2) * e_{12} = x * e_1 * e_1 * e_2 + y * e_2 * e_1 * e_2 = e_2 x - e_1 y
+$$
+
+azaz elforgattuk a vektorunkat $\pm 90 \degree$-al.
+
+Összegezve, az alábbi szorzótáblát állapítottuk meg:
+
+$$
+\mathbf{V} = s + xe_1 + y e_2 + B \bm{I}
+$$
+
+esetén:
+
+$$
+\def\arraystretch{1.5}
+\begin{array}{|c||c|c|c|c|}
+\hline
+& 1 & e_1 & e_2 & \bm{I} \\[-0.1ex] \hline \hline
+1 & 1 & e_1 & e_2 & \bm{I} \\ \hline
+e_1 & e_1 & 1 & \bm{I} & e_2 \\ \hline
+e_2 & e_2 & -\bm{I} & 1 & -e_1 \\ \hline
+\bm{I} & \bm{I} & -e_2 & e_1 & -1 \\ \hline
+\end{array}
+$$
+
+### Projection és rejection
+
+Hogyan tudjuk ezzel az eszköztárral például egy vektornak egy másik vektorral merőleges, és párhuzamos komponenseit meghatározni?
+
+Vegyük $a$ és $v$ nem egyirányú vektorokat. Keressük $v_{\perp}$ és $v_{\parallel}$ vektorokat, melyek rendre merőlegesek, és párhuzamosak $a$-val, és $v_{\perp} + v_{\parallel} = v$.
+
+Egy kis maszatolás után megkapjuk, hogy:
+
+$$
+\begin{align*}
+v_{\perp} &= (v \wedge a) * a^{-1} \\
+v_{\parallel} &= (v \cdot a) * a^{-1}
+\end{align*}
+$$
+
+Továbbá mivel vektorok esetén $v * a = v \cdot a + v \wedge a$, ezért ezt átrendezve azt kapjuk, hogy:
+
+$$
+\begin{align*}
+v \cdot a &= \frac{(v*a + a*v)}{2} \\
+v \wedge a &= \frac{(v*a - a*v)}{2}
+\end{align*}
+$$
+
+De mire is megyünk ezzel? Sok bonyolultabb vektorműveletet, melyekhez eddig mátrixokhoz kellett nyúlnunk, szépen ki tudunk fejezni geometriai szorzatokkal. Nézzünk is pár ilyet:
+
+### Tükrözés
+
+Ha egy $v$ vektort egy másik $a$ vektorra akarunk tükrözni, akkor geometriailag elég lenne $v$-nek az $a$-ra merőleges komponensét negálni. Ezt úgy is elérhetjük, hogy a párhuzamos komponensből kivonjuk a merőleges komponenst. Ezeket a komponenseket most már könnyen ki tudjuk fejezni, tehát ha $v'$-vel jelöljük $v$ tükörképét, akkor:
+
+$$
+\begin{align*}
+v' &= v_{\parallel} - v_{\perp} = (v \cdot a) * a^{-1} - (v \wedge a) * a^{-1} \\
+&= (v \cdot a - v \wedge a) * a^{-1} = (a \cdot v + a \wedge v) * a^{-1} \\
+\implies &\boxed{v' = a * v * a^{-1}}
+\end{align*}
+$$
+
+### Forgatás
+
+A tükrözést felhasználva fogunk forgatni. Tegyük fel, hogy van két $a_1, a_2$ vektorunk, melyek $\varphi$ szöget zárnak be egymással. Ekkor bármely másik $v$ vektort el tudjuk forgatni $2 \varphi$ szöggel, ha először tükrözzük $a_1$-re, utána pedig a keletkező $v'$ vektort tükrözzük $a_2$-re.
+
+??? failure "Ennek az állításnak a levezetése (:warning:KEEP OUT:warning:)"
+ Na sziasztok, $\lambda$evy vagyok, és ez itt egy forgatás levezetős bekezdés, mert ugye ti küldtétek, én végigjátszom!
+
+ {width=100%}
+
+ Itt azt a feltételt, hogy $a_1$ és $a_2$ (melyekről feltesszük, hogy egységvektorok, annak ellenére, hogy az ábrán egyértelműen nem ugyan olyan hosszúak) bezárt szöge $\varphi$, azt úgy tudjuk értelmezni, hogy visszavezetjük a geometriai szorzatot a skalár szorzatos és külső szorzatos definíciójához:
+
+ $$
+ \begin{align*}
+ R &\coloneqq a_2 * a_1 = a_2 \cdot a_1 + a_2 \wedge a_1 = \cos(\varphi) - \bm{I}*\sin(\varphi) \\
+ R^{-1} &\coloneqq a_1 * a_2 = a_1 \cdot a_2 + a_1 \wedge a_2 = \cos(\varphi) + \bm{I}*\sin(\varphi)
+ \end{align*}
+ $$
+
+ ahol $R$ egy _rotor_. Itt tényleg igaz, hogy $R^{-1}$ az $R$ inverze, hiszen feltettük, hogy $a_1$ és $a_2$ egységvektorok, és egységvektorok esetén $a^{-1} = a$, tehát $(a_2 * a_1)^{-1} = a_1^{-1} * a_2^{-1} = a_1 * a_2$.
+
+ Írjuk fel $v''$-őt, és próbáljuk meg valahogy becsempészni a rotorunkat:
+
+ $$
+ \begin{align*}
+ v'' &= a_2*v'*a_2^{-1} = a_2*a_1*v*a_1^{-1}*a_2^{-1} \\
+ &= (a_2*a_1)*v*(a_1^{-1}*a_2^{-1}) = R * v * R^{-1} \\
+ &= (\cos(\varphi) - \bm{I}*\sin(\varphi)) * v * (\cos(\varphi) + \bm{I}*\sin(\varphi))
+ \end{align*}
+ $$
+
+ Ezután felbontjuk a baloldali zárójelet, kihasználjuk az antikommutativitást, utána pedig minden zárójelet felbontunk, végezetül pedig kihasználjuk, hogy $\bm{I}^2 = -1$:
+
+ $$
+ \begin{align*}
+ v'' &= (\cos(\varphi) - \bm{I}*\sin(\varphi)) * v * (\cos(\varphi) + \bm{I}*\sin(\varphi)) \\
+ &= (v*\cos(\varphi) - (\bm{I}*v)*\sin(\varphi)) * (\cos(\varphi) + \bm{I}*\sin(\varphi)) \\
+ &= (v*\cos(\varphi) - (-v*\bm{I})*\sin(\varphi)) * (\cos(\varphi) + \bm{I}*\sin(\varphi)) \\
+ &= (v*\cos(\varphi) + (v*\bm{I})*\sin(\varphi)) * (\cos(\varphi) + \bm{I}*\sin(\varphi)) \\
+ &= v*\cos^2(\varphi) + 2*v*\bm{I}*\sin(\varphi) * \cos(\varphi) + v*\bm{I}^2 \sin^2(\varphi) \\
+ &= v*\cos^2(\varphi) + 2*v*\bm{I}*\sin(\varphi) * \cos(\varphi) - v*\sin^2(\varphi) \\
+ \end{align*}
+ $$
+
+ Felidézzük, hogy $\cos(2\varphi) = \cos^2{\varphi} - \sin^2{\varphi}$ és $\sin(2\varphi) = 2\sin(\varphi)\cos(\varphi)$:
+
+ $$
+ \begin{align*}
+ v'' &= v*\cos^2(\varphi) + 2*v*\bm{I}*\sin(\varphi)*\cos(\varphi) - v*\sin^2(\varphi) \\
+ &= v*\cos^2(\varphi) - v * \sin^2(\varphi) + 2*v*\bm{I}*\sin(\varphi)*\cos(\varphi) \\
+ &= v*[\cos^2(\varphi) - \sin^2(\varphi)] + v*\bm{I}*[2*\sin(\varphi)*\cos(\varphi)] \\
+ &= v* \cos(2\varphi) + v * \bm{I}*\sin(2\varphi) \\
+ &= v * (\cos(2\varphi) + \bm{I}*\sin(2\varphi))
+ \end{align*}
+ $$
+
+
+
+ azaz $\displaystyle v'' = v * e^{\bm{I}2\varphi}$, tehát $v$-nek a $2\varphi$-vel elforgatott képe. $\blacksquare$
+
+## Komplex számok algebrája
+
+A kétdimenziós geometriát az előzőekben vektorokkal, és pontokkal alapoztuk meg: ezekből és az ezeken végrehajtott műveletekből állt az algebránk. Más utat is járhatunk, komplex számokkal is ki tudjuk fejezni a kétdimenziós geometriát.
+
+Emlékezzünk vissza a Clifford algebránkhoz, amikor azt akartuk eldönteni, hogy mi legyen $e_1 * e_1$ és $e_2 * e_2$ eredménye. Akkor mind a kettőt $1$-nek választottuk, de ha $e_2 * e_2$-t $-1$-nek választottuk volna, az is egy valid algebrát eredményez: a komplex számok algebráját.
+
+### Pontok és műveletek
+
+A geometriánkban egy pontnak egy komplex szám felel meg:
+
+$$
+z_p = x_p + y_p \bm{i} = R \cdot e^{\bm{i}\varphi} = R \cdot \cos(\varphi) + \bm{i} \cdot R \cdot \sin(\varphi)
+$$
+
+ahol $x_p, y_p$ valós számok, $R$ a pont origótól mért távolsága, $\varphi$ pedig a pontot és az origót összekötő félegyenesnek a $x$-tengellyel bezárt szöge.
+
+Korábban vektorokkal modelleztük az eltolásokat, forgatásokat, stb. Ezeket viszont komplex számokkal is tudjuk: az eltolás komplex számok összeadása, és az, hogy mennyivel toljuk el a pontot, szintén egy komplex szám:
+
+$$
+z_p' = z_p + z_t
+$$
+
+ahol $z_t$ egy tetszőleges komplex szám. Néha célszerű a komplex számokra nem mint pontokra, hanem mint _helyvektorokra_ gondolni, azaz az origóból a pontba mutató vektorra. Ebben az értelmezésben egy pontot egy másik pont helyvektorával toljuk el, amikor összeadjuk őket.
+
+A skálázás műveletét is tudjuk ábrázolni, pontosabban az úgynevezett izotrop (irányfüggetlen) skálázást:
+
+$$
+z_p' = z_p \cdot z_s
+$$
+
+ahol $z_s$ egy olyan komplex szám, aminek a képzetes része nulla. Ez a skálázás ugyanolyan mértékben skálázza az $x$- és az $y$-tengelyt is.
+
+Ha a szorzásban választott komplex számunknak nemnulla képzetes része van, akkor a _forgatva nyújtás_ műveletét kapjuk. Ehhez szemléletesebb, ha az $R \cdot e^{\bm{i}\varphi}$ trigonometrikus alakját használjuk a komplex számoknak. Vegyük $z_r = x_r + y_r \bm{i} = s \cdot e^{\bm{i} \alpha}$ tetszőleges komplex számunkat. Ekkor ha a $z_p$ pontunkat ezzel megszorozzuk, egy $s$-el megnyújtott, $\alpha$-val elforgatott pontot kapunk:
+
+$$
+z_p' = z_p \cdot z_r = (s R) \cdot e^{\bm{i} \cdot (\alpha + \varphi)}
+$$
+
+Ha csak forgatni szeretnénk, akkor elég $s = 1$ választás, azaz $|z_r| = 1$.
+
+Ezekből a szép geometriai tulajdonságokból adódóan a fraktáloknál, illetve a kétdimenziós forgatások modellezésénél gyakran komplex számokat használunk.
+
+### Implementáció (komplex számok)
+
+```cpp
+struct Complex {
+ float x, y;
+
+ Complex(float x0, float y0) { x = x0, y = y0; }
+
+ Complex operator+(Complex r) {
+ return Complex(x + r.x, y + r.y);
+ }
+
+ Complex operator-(Complex r) {
+ return Complex(x - r.x, y - r.y);
+ }
+
+ Complex operator*(Complex r) {
+ return Complex(x * r.x - y * r.y, x * r.y + y * r.x);
+ }
+
+ Complex operator/(Complex r) {
+ float l = r.x * r.x + r.y * r.y;
+ return (*this) * Complex(r.x / l, -r.y / l); // konjugálttal bővítjük
+ }
+};
+
+// Második konstruktor, polárkoordinátákból
+Complex Polar(float r, float phi) {
+ return Complex(r * cosf(phi), r * sinf(phi));
+}
+```
+
+### Példa
+
+Ha kétdimenziós transzformációkat kell modelleznünk, akkor a komplex számoknál nem igazán találunk jobbat. Az alábbi példa is szemléleti ezt: a specifikációt lényegében szóról szóra kóddá tudjuk fordítani, nagyobb nehézségek nélkül.
+
+
+> A $p$ pontot a $\textcolor{red}{\text{\((1,-1)\) pivot pont}}$ körül $\textcolor{SpringGreen}{\text{nyújtsuk \(2\)-szeresére és forgassuk el \(t\)-vel}}$, $\textcolor{cyan}{\text{majd toljuk el a \((2, 3)\) vektorral}}$ és végül $\textcolor{Violet}{\text{nyújtsuk az origó körül \(0.8\)-szorosára} \\ \text{és forgassuk \(–t/2\)-radiánnal}}$.
+
+A fenti transzformációt megvalósító kódrészlet:
+
+
+
+## Geometria 3D-ben
+
+Tudunk esetleg találni valami hasonló algebrát a komplex számokhoz, csak három dimenzióban? Nagyon kényelmes lenne, ha 3D-s alakzatok forgatását, eltolását, stb. ugyan úgy tudnánk szorzásokkal és összeadásokkal megvalósítani.
+
+Ha vissza emlékezünk a [szemléletformáló kitérőnkre](#szemléletformáló-kitérő), akkor tudhatjuk, hogy általánosságban az összeadás, és a skalárral szorzás nem igazán törődnek azzal, hogy milyen objektumokon hajtjuk őket végre. Pont ezért, az eltolás (összeadás) és a skálázás (skalárral szorzás) műveleteket tetszőleges dimenziókba általánosíthatjuk, így három dimenzióba is.
+
+A gondot megint a szorzás (forgatás) jelenti. Szeretnénk megtartani azokat a jó tulajdonságokat, amiket elvárunk egy szorzástól, viszont ezért a Clifford algebrában és eléggé sokat küzdtünk. Sőt, mivel most a háromdimenziós forgatást szeretnénk modellezni, ezért a szorzásunknak annak a tulajdonságaival kel, hogy bírjon.
+
+{width=100%}
+
+Például ahogy a fenti képen is láthatjuk, a forgatás nem kommutatív.
+
+### Naiv megközelítés
+
+!!! quote "Idézet"
+ $\text{Hát ha 2D-ben elég volt az, hogy } z = x + y \bm{i} \text{, akkor 3D-ben} \\
+ \text{legyen } h = x + y \bm{i} + z \bm{j}\text{, és annyi.} \\[-7ex]$
+ $\hspace{26em} \text{- Naiv kolléga}$
+
+Ötletnek nem rossz, viszont ha ezen az úton indulnánk el, akkor a végén oda jutunk, hogy nem tudunk egy olyan szorzást definiálni, amivel rendesen lehet forgatni.
+
+De akkor mégis hogyan forgassunk három dimenzióban?
+
+### Mátrixok
+
+Mivel a forgatás egy lineáris művelet, ezért kell legyen egy $r' = \bm{R(r)}$ lineáris transzformációhoz tartozó mátrix.
+
+$$
+x'\bm{i} + y'\bm{j} + z'\bm{k} = R(x + y + z) = xR(\bm{i}) + yR(\bm{j}) + zR(\bm{k})
+$$
+
+$$
+[x', y', z'] = [x, y, z]
+\begin{bmatrix}
+\bm{R(i)}_x & \bm{R(i)}_y & \bm{R(i)}_z \\
+\bm{R(j)}_x & \bm{R(j)}_y & \bm{R(j)}_z \\
+\bm{R(k)}_x & \bm{R(k)}_y & \bm{R(k)}_z
+\end{bmatrix}
+$$
+
+Ezzel lehetne forgatni, viszont mátrixokkal dolgozni nem éppen a legkényelmesebb, szóval kutakodjunk tovább.
+
+### Rodriguez formula
+
+Próbáljuk meg a lineáris algebra ismereteinket felhasználva kimaszatolni:
+
+Origón átmenő $d$ tengely körüli forgatás.
+{width=100%}
+
+Magyarázat:
+
+- $d$ (zöld): forgatási tengely
+- $r$ (piros): forgatni kívánt vektor
+- $r_\parallel = r'_\parallel = d(r \cdot d)$ (barna): $d$-vel párhuzamos komponense $r$ és $r'$-nek (egyenlők)
+- $r_\perp = r - d(r \cdot d)$ (sötétkék): $r-r_\parallel$, azaz $r$-ből kivonjuk a párhuzamos komponenst, ami marad az már biztosan merőleges
+- $r_{\perp\perp} = d \times r_\perp = d \times r$ (világoskék): $d$-re és $r_{(\perp)}$-re merőleges
+
+- $r' = r'_\parallel + r'_\perp$ (lila): $r$ elforgatva, a párhuzamos és merőleges komponensek összege
+
+A merőleges komponenst pedig $r_\perp$, $r_{\perp\perp}$ és szögfüggvények segítségével az alábbi módon kaphatjuk meg:
+
+- $r'_\perp = r_\perp \cos\varphi + r_{\perp\perp} \sin\varphi$
+
+Tehát összegezve:
+
+$$
+\boxed{
+\begin{align*}
+r' &= \overbrace{d(r \cdot d)}^{\displaystyle r'_{\parallel}} + \overbrace{(r - d(r \cdot d))\cos(\varphi)}^{\displaystyle r_{\perp}} + \overbrace{d \times r \sin(\varphi)}^{\displaystyle r_{\perp\perp}} \\
+&= r \cos(\varphi) + d(r \cdot d)(1 - \cos(\varphi)) + d \times r \sin(\varphi)
+\end{align*}
+}
+$$
+
+A végső képlettel már egy fokkal kényelmesebb dolgozni, mint egy mátrixszal, viszont még mindig nem az igazi. A megoldást az fogja jelenti, hogy egy dimenzióval feljebb lépünk.
+
+### Kvaternió
+
+Egy kvaternió egy négydimenziós komplex szám, ami azt jelenti, hogy a valós része mellett van három képzetes része. Több alakban is szokás ábrázolni:
+
+- mint egy négyes vektort: $q = [s, x, y, z]$
+- mint egy valós szám és egy háromdimenziós képzetes vektor párt: $q = [s, \bm{d}]$
+- algebrai alak: $q = s + x \bm{i} + y \bm{j} + z \bm{k}$
+
+A kvaterniókon végzett műveletek logikája ugyan az, mint a komplex számokon végzett műveleteké, csak most több képzetes rész van. Ez a gyakorlatban annyit jelent, hogy míg a komplex számoknál elég volt azt az egy "szabályt" megjegyezni, hogy $i^2 = -1$, addig a kvaternióknál több ilyen "szabály" lesz, amit észben kell tartani.
+
+Ezáltal sok műveletet ugyan úgy végzünk el, mint a komplex számok esetén:
+
+- $q_1 + q_2 = [s_1 + s_2, x_1 + x_2, y_1 + y_2, z_1 + z_2]$
+- $a \cdot q = q \cdot a = [as, ax, ay, az]$ ahol $a \in \R$
+- $|q| = \sqrt{s^2 + x^2 + y^2 + z^2}$
+
+Az a nagy kérdés, hogy a szorzást hogyan definiáljuk, hogy 3D-s forgatást lehessen vele modellezni. Korábban ez nem ment, de itt már lehetséges:
+
+
+
+
+
+$$
+i^2 = j^2 = k^2 = ijk = -1
+$$
+
+
+
+Ez a szorzás asszociatív, de _nem kommutatív_, összeadásra pedig disztributív. A fenti egyenlet átrendezésével megkapható az összes többi eset (pl. $ij = k$, $ki = j$, stb...)
+
+Invertálhatóságot is akarunk, de ahhoz először kell egy (multiplikatív) egység elem: $[1,0,0,0]$. Ha már ez megvan, felírhatjuk egy $q$ kvaternió inverzét, a következő képpen:
+
+$$
+q^{-1} = \frac{[s, -d]}{|q|^2}
+$$
+
+Ez az inverz baloldali és jobboldali inverz is (nem feledkezünk meg arról, hogy a szorzás nem kommutatív), tehát $q^{-1} \cdot q = q \cdot q^{-1} = [1, 0, 0, 0]$.
+
+#### Szorzás geometriai értelmezése
+
+Ha nagyon sokáig bámulnánk a szorzási szabályokat, akkor észrevehetnénk, hogy azok megegyeznek a vektoriális szorzásban ismert összefüggésekkel. Ha a kvaterniókra $q = [s, \bm{d}]$ alakban gondolunk, akkor:
+
+$$
+[s_1, \bm{d}_1] * [s_2, \bm{d}_2] = [\overbrace{s_1 s_2 - \bm{d}_1 \cdot \bm{d}_2}^{\text{valós}}, \overbrace{s_1 \bm{d}_2 + s_2 \bm{d}_1 + \bm{d}_1 \times \bm{d}_2}^{\text{képzetes}}]
+$$
+
+#### Forgatás kvaterniókkal
+
+A motivációnk az volt, hogy tudjunk 3D-ben könnyen forgást modellezni. Nézzük meg, hogy kvaterniókkal hogyan lehet.
+
+Egy $\bm{d} \in \R^3$ (egységhosszú) vektorral megadott tengely körüli $\alpha$ szöggel való forgatást az alábbi kvaternió írja le:
+
+$$
+q = [\cos(\alpha/2), \bm{d} \cdot \sin(\alpha/2)]
+$$
+
+Viszont felmerülhet bennünk a gondolat, hogy hát ez egy négydimenziós vektor, és mi háromdimenziós vektorokat szeretnénk forgatni, de ezeket nem lehet összeszorozni. A forgatandó $\bm{u} \in \R^3$ vektorunkat be kell ágyaznunk egy kvaternióba, még pedig a következő képpen: $p = [0, \bm{u}]$, azaz egy nulla valós részű kvaterniót csinálunk belőle. Ezután pedig már forgathatjuk:
+
+$$
+q * p * q^{-1} = q * [0, \bm{u}] * q^{-1} = [0, \bm{v}]
+$$
+
+ahol a $\bm{v}$ háromdimenziós vektor az $\bm{u}$ elforgatottja $\bm{d}$ körül $\alpha$-val. Az inverzet jelenleg könnyű előállítani, mivel $q$-t pont úgy állítottuk elő, hogy egységhosszú legyen, és egységhosszú kvaterniók inverze megegyezik a konjugáltukkal:
+
+$$
+q^{-1} = [\cos(\alpha/2), - \bm{d} \cdot \sin(\alpha/2)]
+$$
+
+!!! info 11.1 Tétel (kvaternió forgatás)
+ Egy $\bm{d} \in \R^3$ egységhosszú vektorral megadott tengely körüli $\alpha$ szöggel való forgatást az alábbi kvaternió írja le:
+
+ $$
+ q = [\cos(\alpha/2), \bm{d} \cdot \sin(\alpha/2)]
+ $$
+
+ mellyel egy $\bm{u} \in \R^3$ vektort az alábbi módon lehet elforgatni:
+
+ $$
+ q * p * q^{-1} = q * [0, \bm{u}] * q^{-1} = [0, \bm{v}]
+ $$
+
+??? abstract Bizonyítás
+ A bizonyítás a kvaternió-szorzás algebrai definíciójának és a trigonometrikus azonosságoknak direkt alkalmazásán alapul.
+
+ Ha be tudjuk látni, hogy a $q * p * q^{-1}$ kifejezés ekvivalens a Rodriguez formulával, akkor készen is vagyunk, hiszen az a formula ugyan azt csinálja, mint amit mi most szeretnénk.
+
+ A Rodriguez formula ezt mondja ki:
+
+ $$
+ v = u \cos(\alpha) + d(u \cdot d)(1 - \cos(\alpha)) + d \times u \sin(\alpha)
+ $$
+
+ Itt az $u$ vektort szeretnénk forgatni, de mivel a forgatás (és a kvaternió szorzás is) disztributív az összeadásra, csinálhatjuk azt, hogy felbontjuk $u$-t egy $d$-re merőleges, és egy $d$-vel párhuzamos komponensre. Ezután ezeket külön-külön elforgatva, a végén pedig összeadva a keletkező két vektort ugyan azt kapjuk, mintha az eredeti $u$-t forgattuk volna el. (Ha ez nem világos, hogy miért igaz, akkor próbáld meg 2D-ben végig gondolni, ott is működik ugyan ez feltéve, hogy egységhosszú vektorokkal dolgozunk.)
+
+ Most pedig külön-külön bebizonyítjuk, hogy $d$-re merőleges, illetve vele párhuzamos vektorok esetén a kvaterniós szorzás ekvivalens a Rodriguez formulával.
+
+ ??? abstract Első eset: $d$ merőleges $u$-ra
+ Mivel $d \perp u$, ezért $u \cdot d = 0$, tehát picit egyszerűsödik a Rodriguez formulánk:
+
+ $$
+ v = \bm{u} \cos(\alpha) + \bm{d} \times \bm{u} \sin(\alpha)
+ $$
+
+ Bontsuk szét a $q * [0, \bm{u}] * q^{-1}$ kifejezést, kezdve a $q * [0, \bm{u}]$ szorzattal:
+
+ $$
+ \begin{align*}
+ q * [0, \bm{u}] &= [\cos(\alpha/2), \bm{d} \sin(\alpha/2)] * [0, \bm{u}] \\
+ &= [0, \bm{u} \cos(\alpha/2) + \bm{d} \times \bm{u} \sin(\alpha/2)] \\
+ &= [0, \bm{u}^{*}]
+ \end{align*}
+ $$
+
+ !!! note Szorzás emlékeztető
+ $$
+ [s_1, \bm{d}_1] * [s_2, \bm{d}_2] = [\overbrace{s_1 s_2 - \bm{d}_1 \cdot \bm{d}_2}^{\text{valós}}, \overbrace{s_1 \bm{d}_2 + s_2 \bm{d}_1 + \bm{d}_1 \times \bm{d}_2}^{\text{képzetes}}]
+ $$
+
+ Itt kihasználtuk azt, hogy mivel (a fenti szorzás emlékeztető jelöléseivel) esetünkben $s_2 = 0$, és $\bm{d}_1 \cdot \bm{d}_2$ is nulla (hiszen $d \perp u$), ezért az eredmény valós része biztosan $0$ lesz. A képzetes tagnál csak annyit tapasztaltunk, hogy mivel $s_2$ nulla, ezért kiesett a $s_2 \bm{d}_1$ tag.
+
+ Vizsgáljuk meg picit az $\bm{u}^{*}$ tagot, és a Rodriguez formulát:
+
+ $$
+ \begin{align*}
+ \text{Rodriguez:} \quad &v = \bm{u} \cos(\alpha) + \bm{d} \times \bm{u} \sin(\alpha) \\
+ \text{Kvaternió:} \quad &\bm{u}^{*} = \bm{u} \cos(\alpha/2) + \bm{d} \times \bm{u} \sin(\alpha/2)
+ \end{align*}
+ $$
+
+ A kettő pontosan megegyezik, azzal a különbséggel, hogy csak $\alpha / 2$ szöggel forgattunk!
+
+ Nézzük a második szorzást. Hasonlóan érvelve mint a $q * [0, \bm{u}]$ esetben, itt is pár tag kiesik:
+
+ $$
+ \begin{align*}
+ [0, \bm{u}^{*}] * q^{-1} &= [0, \bm{u}^{*}] * [\cos(\alpha/2), - \bm{d} \sin(\alpha/2)] \\
+ &= [0, \bm{u}^{*} \cos(\alpha/2) - \bm{u}^{*} \times \bm{d} \sin(\alpha/2)] \\
+ &= [0, \bm{u}^{**}]
+ \end{align*}
+ $$
+
+ Vizsgáljuk meg itt is az eredmény képzetes részét:
+
+ $$
+ \begin{align*}
+ \text{Rodriguez:} \quad &v = \bm{u} \cos(\alpha) + \bm{d} \times \bm{u} \sin(\alpha) \\
+ \text{Első kvaternió:} \quad &\bm{u}^{*} = \bm{u} \cos(\alpha/2) + \bm{d} \times \bm{u} \sin(\alpha/2) \\
+ \text{Második kvaternió:} \quad &\bm{u}^{**} = \bm{u}^{*} \cos(\alpha/2) - \bm{u}^{*} \times \bm{d} \sin(\alpha/2)
+ \end{align*}
+ $$
+
+ Jelen esetben az a különbség, hogy míg a Rodriguez formulában $ + \bm{d} \times \bm{u}$ van, nekünk most $- \bm{u}^{*} \times \bm{d}$. Viszont mivel a keresztszorzat egy antikommutatív művelet, ezért $- \bm{u}^{*} \times \bm{d} = \bm{d} \times \bm{u}^{*}$!
+
+ Ezt a tulajdonságot kihasználva, már $\bm{u}^{**}$ is a Rodriguez formulával ekvivalens alakba került, tehát ez is egy $\alpha/2$-vel való forgatás.
+
+ Mivel a $q$-val való balról szorzás, és a $q^{-1}$-el való jobbról szorzás is külön-külön egy $\alpha/2$-vel való forgatást eredményezett, így ha ezeket egymás után elvégezzük, akkor tényleg egy $\alpha$-val való forgatást hajtunk végre, tehát $\bm{u}^{**} = v$. $\blacksquare$
+
+ ??? abstract Második eset: $d$ párhuzamos $u$-val
+ Mivel $d \parallel u$, és mind a kettő egységvektor (hiszen $u$-t mi választjuk, $d$-ről pedig a tétel kiköti, hogy egységvektor), ezért $d = u$. Ezentúl $d \times u = 0$ és $d \cdot u = |d| |u| = 1$ is igazak, tehát egyszerűsödik a Rodriguez formulánk:
+
+ $$
+ \begin{align*}
+ v &= \bm{u} \cos(\alpha) + \bm{d}(\bm{u} \cdot \bm{d})(1 - \cos(\alpha)) \\
+ &= \bm{u} \cos(\alpha) + \bm{d}(1 - \cos(\alpha)) \\
+ &= \bm{u} \cos(\alpha) + \bm{d} - \bm{d} \cos(\alpha) \\
+ &= \cos(\alpha)(\bm{u}-\bm{d}) + \bm{d} \\
+ &= \cos(\alpha)(0) + \bm{d} \\
+ &= \bm{d} = \bm{u}
+ \end{align*}
+ $$
+
+ Ebből nekünk a legfontosabb rész az az, hogy $v = u$. Ezzel lényegében azt mondjuk, hogy a kiinduló $u$ vektor a forgatás után ($v$) változatlan marad. Tehát ha be tudjuk látni, hogy a kvaterniókkal való szorzás sem változtat az eredeti vektoron, akkor készen vagyunk.
+
+ Nézzük a baloldali szorzatot:
+
+ $$
+ \begin{align*}
+ q * [0, \bm{u}] &= [\cos(\alpha/2), \bm{d} \sin(\alpha/2)] * [0, \bm{u}] \\
+ &= [- \bm{u} \cdot \bm{d} \sin(\alpha/2), \bm{u} \cos(\alpha/2)] \\
+ &= [- \sin(\alpha/2), \bm{u} \cos(\alpha/2)]
+ \end{align*}
+ $$
+
+ Folytassuk a jobboldali szorzattal:
+
+ $$
+ \begin{align*}
+ [- \sin&(\alpha/2), \bm{u} \cos(\alpha/2)] * q^{-1} = \\
+ &= [- \sin(\alpha/2), \bm{u} \cos(\alpha/2)] * [\cos(\alpha/2), - \bm{d} \sin(\alpha/2)] \\
+ &= [- \sin(\alpha/2)\cos(\alpha/2) + \sin(\alpha/2)\cos(\alpha/2), \bm{d} \sin^2(\alpha/2) + \bm{u} \cos^2(\alpha/2)] \\
+ &= [0, \bm{d} (\sin^2(\alpha/2) + \cos^2(\alpha/2))] \\
+ &= [0, \bm{d}] = \boxed{[0, \bm{u}]}
+ \end{align*}
+ $$
+
+ Tehát a két kvaterniós szorzat után visszakaptuk $[0, u]$-t, tehát ebből is az következik, hogy $v = u$, szóval megfelelünk a Rodriguez formulának. $\blacksquare$
+
+
+ Beláttuk, hogy $d$-re merőleges, és azzal párhuzamos vektorokra igaz az állítás. Ezt követően tetszőleges $u$ vektort el tudunk forgatni, ha felbontjuk a $d$-re merőleges és párhuzamos komponenseire, azokat külön elforgatjuk, és az eredményt összeadjuk. $\blacksquare$
+
+Természetesen ha tetszőleges 3D-s tengely körül tudunk forgatni, akkor bármilyen 3D-s forgatást tudunk modellezni.
+
+Ha valaki inkább vizuális típus, akkor nagyon tudom ajánlani [ezt](https://eater.net/quaternions/video/intro) az angol nyelvű interaktív videót/szimulációt.
+
+#### Kvaternió implementáció
+
+Nézzük meg, hogy kódban hogyan implementáljuk mindezt.
+
+```cpp
+struct vec4 {
+ // Itt a `w` jelöli a valós részt, tehát
+ // q = w + xi + yj + zk
+ float x, y, z, w;
+
+ // további műveletek...
+};
+
+// Kvaternió szorzás a geometriai interpretációt felhasználva
+vec4 qmul(vec4 q1, vec4 q2) {
+ vec3 d1(q1.x, q1.y, q1.z), d2(q2.x, q2.y, q2.z);
+ return vec4(d2 * q1.w + d1 * q2.w + cross(d1, d2), q1.w * q2.w - dot(d1, d2));
+}
+
+// Konstruálás egy szögből és egy tengelyből, azaz egy
+// 3D-s forgatást leíró mennyiségekből.
+vec4 quaternion(float ang, vec3 axis) {
+ // `d` egységvektor, kell a `normalize`
+ vec3 d = normalize(axis) * sinf(ang / 2);
+
+ return vec4(d.x, d.y, d.z, cosf(ang / 2));
+}
+
+// Egy `u` vektor elforgatása. Ha akarnánk, akkor
+// paraméterként a szöget és a tengelyt is átadhatnánk.
+vec3 Rotate(vec3 u, vec4 q) {
+ vec4 qinv(-q.x, -q.y, -q.z, q.w); // q konjugált
+ vec4 qr = qmul(qmul(q, vec4(u.x, u.y, u.z, 0)), qinv);
+ return vec3(qr.x, qr.y, qr.z);
+}
+```
+
+#### GPU shader programozás
+
+Ha a vertex shaderben szeretnénk kvaterniókat használni, ahhoz az alábbi kódrészlet nyújt példát:
+
+```glsl
+uniform vec4 q; // quaternion as uniform variable
+in vec3 u; // Varying input: vertex
+
+vec4 qmul(vec4 q1, vec4 q2) {
+ vec3 d1 = q1.xyz, d2 = q2.xyz;
+ return vec4(d2 * q1.w + d1 * q2.w + cross(d1, d2), q1.w * q2.w - dot(d1, d2));
+}
+
+void main() {
+ vec4 qinv = vec4(-q.xyz, q.w); // conjugate
+ vec3 v = qmul(qmul(q, vec4(u, 0)), qinv).xyz;
+ gl_Position = vec4(v, 1);
+}
+```
+
+## Automatikus deriválás
+
+A való világban sokkal többször kell egy mérnöknek deriválnia, mint az gondolnánk. A fizikusok a világ működését differenciálegyenletekkel írják le, tehát elkerülhetetlen, hogy egy mérnök deriváljon, ha a való világot szeretné modellezni (gondoljunk csak háromdimenziós grafikai szimulációkban a felületek normálvektoraira). Ahogy fejlődött a technológia, úgy egyre több számítást delegálunk a számítógépeknek, hiszen nagyságrendekkel gyorsabbak, mint mi emberek. Pontosan ezért felmerülhet az igény, hogy akkor tanítsuk meg a számítógépet is deriválni.
+
+### Inverz feladatok
+
+A deriválás akkor is előjöhet, ha egy úgynevezett _inverz feladatot_ szeretnénk megoldani. Vegyük példának egy tórusz kirajzolását. Ha ismerjük az egyenletét, akkor a képszintézis feladatot elvégezve könnyen meg tudunk jeleníteni egy tóruszt. Viszont ennek a feladatnak az inverzét - egy kirajzolt kép alapján eldönteni, hogy az ott lévő alakzatnak mi az egyenlete - nagyságrendekkel nehezebb elvégezni. A tóruszos példában a gépi látás eszközeihez nyúlhatunk, de általánosságban az az igaz, hogy gyakran csak találgatni tudunk, és a tippjeinket leellenőrizni, ha meg akarjuk oldani az inverz feladatot.
+
+Amikor leellenőrizzük a tippünket, akkor valamekkora _hibát_ állapítunk meg, azaz egy számot, ami leírja, hogy mennyire térünk el az eredeti feladat megoldásától. Ha az összes tippünkhöz hozzárendeljük, hogy mekkora annak a hibája, akkor egy úgynevezett _hiba függvényt_ kapunk. Ennek a függvénynek mi nekünk a globális minimuma kéne, hiszen ott a legalacsonyabb a hiba. Viszont nem csak vaktában akarunk tippelgetni, szeretnénk azt is tudni, hogy milyen irányban és milyen mértékben változtassuk a tippünket, hogy csökkenjen a hiba. Ehhez a hiba függvény deriváltját kell vennünk. Ha ez az érték közel $0$ (és a második derivált is pozitív), akkor tudjuk, hogy közel járunk a minimumhoz, tehát kisebbeket éri meg változtatni, ha viszont nem $0$ közeli, akkor tudjuk, hogy nagyobbakat változtathatunk, hiszen még messze járunk a minimumtól.
+
+### Naiv módszer
+
+Ha egy matematikust kérnénk meg, hogy implementálja a deriválást valamilyen programozási nyelven, akkor valószínűleg ehhez a képlethez nyúlna (numerikus differenciálás):
+
+$$
+f'(x) \approx \cfrac{f(x + \Delta) - f(x)}{\Delta}
+$$
+
+és ezt alakítaná kóddá, valahogy így:
+
+```cpp
+const float Delta = 0.001;
+
+float foo(float x) { // ... }
+
+float foo_Derivative(float x) {
+ return (foo(x + Delta) - foo(x)) / Delta;
+}
+```
+
+Ezzel viszont egy használhatatlan eredményt kapnánk. Nézzük meg, hogy miért:
+
+- ha túl nagy $\Delta$-t választanánk, akkor pontatlan becslést kapunk
+- ha túl kicsi $\Delta$-t választanánk, akkor pedig zajos becslést kapunk
+
+Ennek az az oka, hogy a számítógép véges számábrázolást használ, tehát egy bizonyos tizedesérték után már pontatlanok a számaink. Viszont amikor két nagyon közeli értékű számot kivonunk, akkor pont azokat a tizedesértékeket veszítjük el, amiket még pontosan tudunk ábrázolni, hiszen a $\Delta$-ánk kicsi, azokon nem változtat. Tehát a végén lényegében kapunk egy nagyon pici számot, ami tele van random számjegyek különbségeivel: lényegében használhatatlan zaj.
+
+Ahhoz, hogy egy használható $\Delta$-t válasszunk, ahhoz már kéne tudni a derivált függvényt, szóval ez a megközelítés nem vezet eredményre. Viszont akkor mégis mit tudunk tenni? A 2D-s és 3D-s forgatás esetében segített, ha visszanyúltunk a Clifford algebra eszközeihez, próbáljuk meg ezt most is.
+
+### Duális számok
+
+Emlékezzünk ismét vissza a Clifford algebránkhoz, amikor azt akartuk eldönteni, hogy mi legyen $e_1 * e_1$ és $e_2 * e_2$ eredménye. Akkor mind a kettőt $1$-nek választottuk, a komplex számok esetén pedig $e_2 * e_2$-t $-1$-nek, viszont mi történne, ha $e_2 * e_2$-t $0$-nek választjuk? Az így kapott algebrát a duális számok algebrájának hívjuk.
+
+Egy duális szám $z = x + y \bm{i}$ alakú, ahol $x, y \in \R$ illetve $i^2 = 0$, viszont $i$ nem feltétlenül egyenlő $0$-val. Nézzük meg az ezeken a számokon végzett aritmetikát:
+
+$$
+\begin{align*}
+\text{Összeadás:} \quad &(x_1 + y_1 \bm{i}) \pm (x_2+y_2 \bm{i}) = (x_1 \pm x_2) + (y_1 \pm y_2) \bm{i} \\
+\text{Szorzás:} \quad &(x_1+y_1 \bm{i}) \cdot (x_2+y_2 \bm{i}) = (x_1x_2) + (x_1y_2+y_1x_2) \bm{i} + \cancel{(y_1y_2) \bm{i}^2} \\
+\text{Osztás:} \quad &\frac{x_1 + y_1 \bm{i}}{x_2 + y_2 \bm{i}} = \frac{(x_1 + y_1 \bm{i})(x_2 - y_2 \bm{i})}{(x_2 + y_2 \bm{i})(x_2 - y_2 \bm{i})}= \frac{x_1x_2 + (y_1x_2x_1y_2) \bm{i} - \cancel{(y_1y_2) \bm{i}^2}}{x^2_2 - \cancel{y^2_2 \bm{i}^2}} = \\
+&= \frac{x_1}{x_2} + \frac{y_1x_2-x_1y_2}{x_2^2} \bm{i}
+\end{align*}
+$$
+
+Hasonlítsuk össze a kapott összefüggéseket a függvények deriválási szabályaival:
+
+$$
+\def\arraystretch{1.5}
+\begin{array}{|c|c|c|}
+\hline
+& \text{Duális számok képzetes része} & \text{Deriválási szabályok} \\ \hline
+\text{Összeadás} & (y_1 \pm y_2) \bm{i} & (f \pm g)' = f' \pm g' \\ \hline
+\text{Szorzás} & (x_1y_2+y_1x_2) \bm{i} & (f \cdot g)' = (f \cdot g' + f' \cdot g) \\ \hline
+\text{Osztás} & \cfrac{y_1x_2-x_1y_2}{x_2^2} \bm{i} & \cfrac{f' \cdot g - f \cdot g'}{(g')^2} \\[1.75ex] \hline
+\end{array}
+$$
+
+Pontosan megegyeznek! Tehát ha egy $z = x + y \bm{i}$ duális számba egy $f$ függvény $f(x)$ értékét eltároljuk $x$-ben, utána pedig ezzel a $z$ számmal összeadunk, szorzunk vagy osztunk, akkor az $y$ pontosan meg fog felelni $f'(x)$-el, az összeadások, szorzások és osztások után, tehát $z = f(x) + f'(x) \bm{i}$.
+
+#### Alap implementáció
+
+Nagyon hasonlít egy komplex szám osztályhoz, csak most $i^2 = 0$.
+
+```cpp
+struct Dnum {
+ float f, d; // function and derivative values
+
+ // Default konstruktorban a deriváltat nullának vesszük.
+ // Erre még később visszatérünk.
+ Dnum(float f0, float d0 = 0) { // constant derivative = 0
+ f = f0, d = d0;
+ }
+
+ Dnum operator+(Dnum r) { return Dnum(f + r.f, d + r.d); }
+ Dnum operator-(Dnum r) { return Dnum(f - r.f, d - r.d); }
+ Dnum operator*(Dnum r) { return Dnum(f * r.f, f * r.d + d * r.f); }
+ Dnum operator/(Dnum r) {
+ return Dnum(f / r.f, (d * r.f – f * r.d) / r.f / r.f);
+ }
+};
+```
+
+Az így definiált Duális szám osztállyal már egyszerűbb függvényeket tudunk deriválni. Nézzük erre egy példát.
+
+Vegyük az $f(x) = \cfrac{a \cdot x}{x^2 + b}$ függvényt, valamilyen szabadon választott $a, b$ valós számokra.
+
+Ha valami konkrét $x$ értékre vagyunk kíváncsiak, akkor kódban ez így nézne ki:
+
+```cpp
+float t = value;
+float F = t * a / (t * t + b);
+```
+
+Ha ezt naiv módon átírjuk, hogy duális számokat használjon, akkor az alábbi alakot kapjuk:
+
+```cpp
+Dnum F = Dnum(t,1) * Dnum(a,0) / (Dnum(t,1) * Dnum(t,1) + Dnum(b,0));
+```
+
+Ez már tökéletesen működik, mégis van egy szépséghibája a dolognak: a számítógép nem tudja, hogy mi `t`, `a` vagy `b` szerint akarunk deriválni, tehát a konstruktorban külön meg kell adni, hogy `t` deriváltja $1$, a többié meg nulla. Így pontosan olyan, mintha `t` szerint deriválnánk. Viszont ki tudjuk használni a default konstruktort: a `Dnum(float f0, float d0 = 0)` konstruktor második paramétere alapértelmezetten legyen nulla. Ez azért kényelmes, mert a konstansok deriváltja nulla, így amikor egy kifejezésben konstansokat (`Dnum(a), Dnum(b)`) használunk, az osztály helyesen kezeli őket a deriválási szabályokban.
+
+Az így kapott kódrészletben már hozzá sem kell nyúlni az eredeti kifejezéshez, kihasználhatjuk a default konstruktort:
+
+```cpp
+Dnum t(value, 1); // Eszerint deriválunk
+Dnum F = t * a / (t * t + b);
+```
+
+Viszont ez a deriválás jelenleg csak a négy alapműveletre működik, nekünk viszont vannak egyéb deriválandó függvényeink, például $\sin$, $\cos$, $\log$, $\exp$, stb... Ezeknek is felvehetnénk a deriválási szabályaikat külön függvényekbe:
+
+```cpp
+Dnum Sin(float t) { return Dnum(sinf(t), cosf(t)); }
+Dnum Cos(float t) { return Dnum(cosf(t), -sinf(t)); }
+// ...
+```
+
+és ezeket utána alkalmazhatnánk kifejezésekben:
+
+```cpp
+Dnum t(value, 1);
+Dnum F = 3 * t + a * Sin(t);
+```
+
+viszont egy dolgot eddig a szőnyeg alá söpörtünk, ami ezt a megközelítést lehetetlenné teszi: az összetett függvények deriváltjait.
+
+#### Teljes implementáció
+
+Az alap `Dnum` osztály nem változik, hiszen az már követi a láncszabályt, viszont az elemi függvényeink így fognak kinézni:
+
+```cpp
+Dnum Sin(Dnum g) { return Dnum(sinf(g.f), cosf(g.f) * g.d); }
+Dnum Cos(Dnum g) { return Dnum(cosf(g.f), -sinf(g.f) * g.d); }
+Dnum Tan(Dnum g) { return Sin(g)/Cos(g); }
+Dnum Log(Dnum g) { return Dnum(logf(g.f), 1/g.f * g.d); }
+Dnum Exp(Dnum g) { return Dnum(expf(g.f), expf(g.f) * g.d); }
+Dnum Pow(Dnum g, float n) {
+ return Dnum(powf(g.f, n), n * powf(g.f, n - 1) * g.d);
+}
+```
+
+Látható, hogy ezeknek a függvényeknek szintén duális számokat kell átadni, mert el kell érniük a `g.d` változót, azaz a belső függvény deriváltját.
+
+#### Többváltozós függvények
+
+Ha felületi gradienst szeretnénk számolni, akkor ahhoz többváltozós függvényeket is kell tudnunk deriválni. Ehhez azt fogjuk csinálni, hogy a duális szám osztályban a deriváltakhoz nem egy értéket tárolunk, hanem változónként egyet, azaz egy tömböt.
+
+```cpp
+template
+struct Dnum {
+ float f; // function value
+ T d; // derivatives
+
+ Dnum(float f0, T d0 = T(0)) { f = f0, d = d0; }
+ Dnum operator+(Dnum r) { return Dnum(f+r.f, d+r.d); }
+ Dnum operator*(Dnum r) { return Dnum(f*r.f, f*r.d + d*r.f); }
+ Dnum operator/(Dnum r) { return Dnum(f/r.f, (d*r.f–f*r.d)/r.f/r.f); }
+};
+
+template
+Dnum Exp(Dnum g) {
+ return Dnum(expf(g.f), expf(g.f) * g.d);
+}
+```
+
+Nézzük egy példát ennek a többváltozós `Dnum` osztály használatára: az $F(x,y,z)$ skalármező gradiensének kiszámítását.
+
+```cpp
+float x, y, z;
+Dnum X(x, vec3(1, 0, 0)), Y(y, vec3(0, 1, 0)), Z(z, vec3(0, 0, 1));
+Dnum F = X*X/a + Y*Y/b + Z*Z/c – 1;
+vec3 grad = F.d;
+```
+
+a `Dnum X(x, vec3(1, 0, 0))` azt jelenti, hogy konstruálunk egy olyan `Dnum` típusú `X` változót, aminek a kezdeti értéke `x`, és ő az első deriválási változó. Hasonlóan `y` és `z` esetén is, csak ők a második illetve harmadik deriválási változók (hiszen például amikor `y` szerint deriválunk, akkor `x` és `z` $0$, tehát a `vec3` második paraméterei `y`-nál $1$, a többi változónál pedig $0$).
+
+#### Összetettebb példa
+
+Egy kétdimenziós pályán haladunk, és azt szeretnénk, hogy mindig a sebesség irányába nézzünk.
+
+A pálya egyenlete:
+
+$$
+\begin{align*}
+x(t) &= \frac{\sin(t)(\sin(t)+3)4}{\tan(\cos(t)+2)} \\[2ex]
+y(t) &= \frac{(\cos(\sin(t))8+1)12+2}{(sin(t)sin(t))^3+2}
+\end{align*}
+$$
+
+A sebességvektor, azaz hogy merre nézünk:
+
+$$
+v(t) = (\dot x(t), \dot y(t))
+$$
+
+Ha kézzel akarnánk kiszámolni és legépelni $\dot x$-t és $\dot y$-t, akkor eléggé keserves feladat elé néznénk:
+
+$$
+\begin{align*}
+\dot x(t) = &\frac{48 \sin^2 (t) \sin^2 (\cos(t) + 2)}{(\cos(2 (\cos(t) + 2)) - 1)^2} + \frac{16 \sin^3 (t) \sin^2 (\cos(t) + 2)}{(\cos(2 (\cos(t) + 2)) - 1)^2} \\[2.5ex]
+&- \frac{8 \sin(t) \cos(t) \sin(2 (\cos(t) + 2))}{\cos(2 (\cos(t) + 2)) - 1} - \frac{12 \cos(t) \sin(2 (\cos(t) + 2))}{\cos(2 (\cos(t) + 2)) - 1}
+\end{align*}
+$$
+
+és ez még csak $\dot x$...
+
+Ezt spóroljuk meg, ha automatikus deriválást használunk. Nézzük ugyan ezt duális számokkal:
+
+```cpp
+void Animate(float tt) {
+ // Idő szerint deriválunk
+ Dnum t(tt, 1);
+
+ // Pályafüggvények
+ Dnum x = Sin(t)*(Sin(t)+3)*4 / (Tan(Cos(t))+2);
+ Dnum y = (Cos(Sin(t)*8+1)*12+2)/(Pow(Sin(t)*Sin(t),3)+2);
+
+ vec2 position(x.f, y.f), velocity(x.d, y.d);
+
+ vec2 heading = normalize(velocity);
+
+ Draw(position, heading);
+}
+```
+
+---
+
+# Kvíz
+
+!!! quote ""
+ A 2024/2025/II félévben nem voltak ebben a témában kvízek.
+
+!!! question 1\. Mi lesz a $q * u * q^{-1}$ kvaternió szorzás eredményének első képzetes része, azaz az $i$ szorzója, ha $u=[0, 10, 0, 0]$, és $q=[\sqrt{2}/2, (0, 0, \sqrt{2}/2)]$ ?
+
+??? tip Megoldás
+ Számítsuk ki $q^{-1}$-et:
+
+ $$
+ q^{-1} = [s, -d]/|q|^2 = [\sqrt{2}/2, (0, 0, -\sqrt{2}/2)]
+ $$
+
+ Emlékezzünk vissza az alábbi képletekre:
+
+ $$
+ [s_1, \bm{d}_1] * [s_2, \bm{d}_2] = [\overbrace{s_1 s_2 - \bm{d}_1 \cdot \bm{d}_2}^{\text{valós}}, \overbrace{s_1 \bm{d}_2 + s_2 \bm{d}_1 + \bm{d}_1 \times \bm{d}_2}^{\text{képzetes}}]
+ $$
+
+ Végezzük el a baloldali szorzást:
+
+ $$
+ \begin{align*}
+ q * u &= [\sqrt{2}/2, (0, 0, \sqrt{2}/2)] * [0, (10, 0, 0)] = \\
+ &= [0, \sqrt{2}/2 (10, 0, 0) + (0, 0, 0) + (0, 5\sqrt2, 0)] = \\
+ &= [0, (5\sqrt2, 5\sqrt2, 0)]
+ \end{align*}
+ $$
+
+ Utána pedig a jobboldalit:
+
+ $$
+ \begin{align*}
+ [0, (5\sqrt2, 5\sqrt2, 0)] * q^{-1} &= [0, (5\sqrt2, 5\sqrt2, 0)] * [\sqrt{2}/2, (0, 0, -\sqrt{2}/2)] \\
+ &= [0, (5, 5, 0) + (-5, 5, 0)] = \\
+ &= [0, (0, 10, 0)]
+ \end{align*}
+ $$
+
+ Azaz $i = 0$.
+
+---
+
+!!! question 2\. Mi lesz a $q * u * q^{-1}$ kvaternió szorzás eredményének második képzetes része, azaz a $j$ szorzója, ha $q=[\sqrt{2}/2, 0, 0, \sqrt{2}/2]$ és $u=[0, 6, 0, 0]$?
+
+??? tip Megoldás
+ Az előzővel teljesen analóg módon. Végeredmény: $j = 6$.
+
+---
+
+!!! question 3\. Adott két kvaternió, $q_1$ és $q_2$. Mi lesz a $q_1 * q_2$ első imaginárius része, azaz az $i$ szorzója?
+ $$
+ \begin{align*}
+ q_1 &= 1+2i +2j + 3k \\
+ q_2 &= 1+0i +2j + 2k
+ \end{align*}
+ $$
+
+??? tip Megoldás
+ Átírhatók $[s, d(i , j, k)]$ alakba:
+
+ $$
+ \begin{align*}
+ q_1 &= 1+2i +2j + 3k = [1, (2,2,3)] \\
+ q_2 &= 1+0i +2j + 2k = [1, (0,2,2)]
+ \end{align*}
+ $$
+
+ Innentől pedig teljesen analóg az előző kettővel.
+
+ Végeredmény: $i = 0$.
+
+---
+
+!!! question 4\. Adott két kvaternió, $q_1$ és $q_2$. Mi lesz a $q_1 * q_2$ valós része?
+ $$
+ \begin{align*}
+ q_1=1+5i +3j + 1k \\
+ q_2=4+4i +0j + 2k
+ \end{align*}
+ $$
+
+??? tip Megoldás
+ Az előzővel teljesen analóg módon. Végeredmény: $s = -18$.
+
+---
+
+!!! question 5\. A 3D forgatás művelet mely tulajdonságokkal rendelkezik az alábbiak közül?
+ - Van egységelem, azaz olyan forgatás, amely nem változtatja meg az alakzatot.
+ - Invertálható
+ - Az összeadással disztributív
+ - Asszociatív
+ - Kommutatív
+
+??? tip Megoldás
+ - [x] Van egységelem, azaz olyan forgatás, amely nem változtatja meg az alakzatot.
+ - Magyarázat: $[1,0,0,0]$
+ - [x] Invertálható
+ - Magyarázat: $q^{-1} = [s, -d]/|q|^2$
+ - [x] Az összeadással disztributív
+ - Magyarázat: Lásd [fentebb](#kvaternió)
+ - [x] Asszociatív
+ - Magyarázat: Lásd [fentebb](#kvaternió)
+ - [ ] Kommutatív
+ - Magyarázat: Nem az, szemléltetésnek a [fenti](#geometria-3d-ben) dobókockás kép.
diff --git a/docs/notes/sem4/computer_graphics/lectures/12.md b/docs/notes/sem4/computer_graphics/lectures/12.md
new file mode 100644
index 0000000..e2ae418
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/12.md
@@ -0,0 +1,1002 @@
+# Fraktálok és káosz
+
+Idáig mindig azzal a feltételezéssel éltünk, hogy a virtuális világunk definiálható metrikus geometriával (tipikusan Euklideszivel), másrészt pedig hogy szimulálható. Nézzük meg, hogy pontosan mit is jelentenek ezek a feltételezések.
+
+## Szimulálható
+
+A virtuális világunk objektumainak állapota és viselkedése van. A viselkedés azt jelenti, hogy a saját és a többi objektum állapota alapján a saját állapotát meg tudja változtatni. Az objektumok állapotának összessége a _rendszer állapota_. Ekkor a rendszer szimulálását elképzelhetjük úgy, mint egy olyan $F$ függvény, ami a rendszer jelenlegi állapotához hozzárendeli a rendszer következő állapotát.
+
+Számítástechnikában _diszkrét időszimulációt_ alkalmazunk, ami azt jelenti, hogy nem folytonosan, hanem $\Delta t$ időlépésenként frissítjük a virtuális világ állapotát. Reményeink szerint ennek ellenére a valósághoz hasonlóan fog működni a rendszerünk.
+
+Az $F$ függvényt és a kezdeti állapotot teljes pontossággal nem ismerjük, viszont abban reménykedünk, hogy a szimulált és valóságos világok állapotai közötti hiba nullához tart. Sajnos nem ez a helyzet. Vannak olyan rendszerek, ahol megpróbálhatjuk bármennyire is pontosítani az $F$ függvényt, bármennyire is pontosabb kezdeti állapotot megadni, ennek ellenére a hiba nem tart nullához. Az ilyen rendszereket nevezzük __kaotikus dinamikus rendszereknek__.
+
+??? example Példák egyszerű kaotikus rendszerekre
+ Nem kell nagyon absztrakt dolgokra gondolni ahhoz, hogy kaotikus rendszereket kapjunk. Nézzünk meg (röviden) két kaotikus rendszert, melyeket még egy Corvinusos óvodás is meg tudna érteni.
+
+ ## Háromtest-probléma
+
+ Vegyünk egy sík terepet, melyen elhelyezünk három golyót. A golyóknak van tömegük, és a gravitáció törvényei is jelen vannak a rendszerünkben. Hogyan fog egymásra hatni a három golyó?
+
+ Ez a rendszer kaotikus, hiszen még a mai napig sincs általános megoldása. Más szóval ha adok neked egy kezdeti állapotot, és megkérdezem tőled, hogy "Ezer időegység múlva milyen állapotban lesz a rendszer?" akkor ahhoz, hogy megválaszold muszáj lesz numerikus becslésekkel leszimulálnod a rendszert (és még ekkor is lenne hiba benne, ha a valóságban is leszimulálnánk).
+
+ Az emberiség történelme során egyik legtöbbet kutatott háromtest-probléma a Nap, Föld és Hold mozgása.
+
+ ## Kettős inga
+
+ Talán az egyik leghíresebb kaotikus rendszer a kettős inga. Képzeljük el két, egymáshoz csatolt ingát, az alábbi konfigurációban:
+
+ {width=100%}
+
+ Fogjuk meg az alsó (vagy felső) golyót, és vigyük el valamilyen tetszőleges kezdeti állapotba, utána pedig engedjük el. A gravitáció hatására a két golyó elkezdenek mozogni, és gyorsan egymás mozgására is hatással lesznek.
+
+ Ez a rendszer szintén kaotikus, lehetetlen teljesen pontosan megmondani, hogy egy kezdeti állapotból később milyen állapotok lesznek. Más szóval, ha egy későbbi állapotot látunk, a kaotikus rendszerek kezdeti feltételekre való extrém érzékenysége miatt gyakorlatilag lehetetlen belőle pontosan visszakövetkeztetni az eredeti kezdeti állapotra.
+
+ Ebben a rendszerben megfigyelhető a butterfly effect, azaz a kezdeti állapot _erős hatást gyakorol_ a rendszerre. Ez azt jelenti, hogy ha fogunk két kezdeti állapotot, amikben csak egy nagyon pici eltérés van (például az egyikben $\theta_2 =19.125\degree$, a másikban pedig $\theta_2 =19.126\degree$), akkor bizonyos idő elteltével már [teljesen más állapotban lesz a két rendszer](https://www.youtube.com/watch?v=d0Z8wLLPNE0).
+
+ Fontos kiemelni, hogy ez nem azt jelenti, hogy a kaotikus rendszerek véletlenszerűek lennének. Teljesen determinisztikusak, egyik lépésben sem kell valamilyen random eseményhez nyúlni, mint például radioaktív bomlás. Ennek ellenére a gyakorlatban nem lehet megjósolni tetszőleges rendszerek jövőbeli állapotát.
+
+ A fejezet későbbi felében mélyebben tárgyaljuk a káoszelméletet.
+
+## Metrikusan definiálható
+
+### Virtuális világ
+
+Eddig feltettük, hogy a világot le lehet írni Euklideszi geometriával. Az Euklideszi geometria az axiómáiból épül fel, melyek pontokra, egyenesekre és egyenesekra vonatkoznak, viszont a valóságban ilyenek nincsenek, tehát nem magától értetődő, hogy tényleg alkalmazhatjuk-e a való világra.
+
+Ha ember alkotta objektumokat nézünk, akkor míg távolról lehet, hogy valamilyen komplex alakjuk van, ha elég közel megyünk, akkor közelítőleg csak síkokból, és egyenesekből állnak. Ezt _skálafüggőségnek_ nevezzük, ami tehát az a gondolat, hogy "kicsiben mindenki lineáris".
+
+Mivel az Euklideszi geometria metrikus, itt van értelme a méret fogalmának: 1D-ben a hossz, 2D-ben a felület, 3D-ben a térfogat. Kapcsolatot láthatunk egy alakzat metrikája és a dimenziója között: úgy kell "megmérni" egy objektumot, ahogy azt a dimenziója megszabja (egy kockának nincsen "hossza", hanem az oldalának van).
+
+### Természet
+
+A természet viszont skálafüggetlen, bármennyire is közelíthetünk, akkor is ugyan olyan lesz közelről, mint messziről. Ez azt is jelenti, hogy nem differenciálható, hiszen ez a skálafüggőségből adódik.
+
+Ennek egy másik következménye az, hogy a valóságban egy egység szakasszal, egység négyzettel vagy egység kockával nem tudunk rendesen hosszat, felületet vagy térfogatot mérni. Viszont intuitívan érezzük, hogy hát a természetbeli objektumoknak kell lenni hosszának, felületének és térfogatának, hiszen ha kimegyek az erdőbe, és fogok egy levelet, annak simán megmérhetem a hosszát, vagy egy kavics térfogatát.
+
+Nézzünk egy példát egy természetben előforduló folyamatra, hogy megértsük, mégis mi zajlik itt.
+
+## Koch görbe
+
+Próbáljunk meg hókristályok kialakulását szimulálni. Vizsgáljuk csak az egyik oldalát először a hópihének, a többi szimmetrikusan ugyan úgy fog fejlődni.
+
+{width=100%}
+
+A kezdeti állapotban van egy szakaszunk. Ezután ennek a középső harmada kicserélődik egy egyenlő oldalú háromszög másik két oldalára. Eleinte harmadoltuk a szakaszunkat, és az egyik harmad helyére bejött két ugyan olyan hosszú szakasz, tehát $3$ egységnyi szakaszból lett $4$. Ez azt jelenti, hogy a szakaszunk hossza is $4/3$-addal nőtt.
+
+Ha tovább ismételjük ezt a folyamatot az újonnan kapott $4$ kicsi szakaszra, akkor tovább tudjuk növelni a szakaszaink számát. Ha a végtelenségig ismételnénk a lépéseket, akkor kapnánk meg a _Koch görbét_. Ez tényleg hasonlít egy hópihére, és mivel tudjuk pontosan, hogy hogyan konstruáltuk, vizsgáljuk meg pár tulajdonságát, mint például, hogy hány dimenziós ez az alakzat?
+
+### Tulajdonságok
+
+Mivel minden lépésben $4/3$-addal növeltük a görbe hosszát, és végtelen lépésünk van, ezért a görbe hosszát az alábbi határérték adja meg:
+
+$$
+\lim_{n \to \infty} l_0 \left( \frac{4}{3} \right)^{n}
+$$
+
+ahol $l_0$ a kezdeti szakasz hossza. Ez a határérték [divergens](https://cdn.discordapp.com/emojis/1394642603701571605.webp?size=240), szóval az alakzatunknak a dimenziója biztos, hogy nagyobb mint $1$, hiszen "végtelen hossza" van.
+
+Ugyanakkor a görbénk végig egyenesekből áll, szóval a területének nullának kell hogy legyen, tehát nem lehet kétdimenziós. Ez azt jelenti, hogy a Koch görbe dimenziójának valahol $0$ és $1$ között kell lennie.
+
+Bár az alakzatunk folytonos (a konstrukcióból adódóan), de sehol sem differenciálható, hiszen "tüskés". Ez abból látszik, hogy bár egy szakasz a belső pontjaiban differenciálható, a két végpontjában nem. A konstrukciónk pedig olyan, hogyan a szakaszok hossza a nullába tart, azaz a határértékben sehol sem lesz differenciálható.
+
+A rendszer _önhasonló_, azaz ha vesszük egy bizonyos részhalmazát, az teljesen egyenértékű az eredeti rendszerrel (olyasmi mint egy rekurzív alakzat).
+
+## Hausdorff dimenzió önhasonló objektumokra
+
+Nézzük meg, hogyan tudjuk általánosítani a dimenzió fogalmát, hogy a Koch görbének is tudjunk dimenziót adni.
+
+Vegyünk egy kiindulási alakzatot. Kicsinyítsük $r$-szeresére, így a mérete $1/r$-szeres lesz. Ezután fedjük le az eredeti tartományt ezzel a kicsinyített alakzattal, jelölje az ehhez szükséges kicsi alakzatok számát $N$. Ha ezt végtelenszer megismételjük, akkor kapunk egy alakzatot, melynek a $D$ dimenziója:
+
+$$
+D = \frac{\log{N}}{\log(1/r)}
+$$
+
+Ez abból következik, hogy:
+
+$$
+N = 1/r^D
+$$
+
+Így például a fenti Koch görbe esetén mivel $1/3$ méretűre kicsinyítettük a kiindulási szakaszt, és $4$-szer fedtük le vele a tartományt, ezért $r = 1/3$, $N = 4$, így $D = \frac{\log 4}{\log 3} \approx 1.26$.
+
+
+
+??? example Nem önhasonló objektumok
+ ## Nem önhasonló objektumok: vonalzó dimenzió
+
+
+ Önhasonló objektumokra:
+
+ {width=100%}
+
+ $$
+ D = \frac{\log(\text{Hossz}(l))}{\log(l)} + 1
+ $$
+
+ Tippre $l$ a vonalzó egység hossza, $\text{Hossz}(l)$ a teljes hossz azaz $l \cdot db$.
+
+ Alkalmazása: természetes objektumok elkülönítése és kategorizálása.
+
+ {width=100%}
+
+## Lindenmayer rendszerek
+
+A Koch görbe mintájára sok más hasonló alakzatot tudunk kreálni. A Koch görbe a Lindenmayer rendszerekbe tartozik, nézzük, hogy ezek hogyan épülnek fel.
+
+A Lindenmayer rendszerekben úgy adjuk meg az alakzatunkat, lényegében megadjuk azt, hogy egy egyenes szakasszal mit csinál (gondoljunk vissza a Koch görbe első lépésére). Ezt úgy adjuk meg, hogy elképzelünk egy teknőst ([igen, kötelezően teknőst](https://en.wikipedia.org/wiki/Turtle_graphics)) a szakasz egyik végpontjában. Ez a teknős csak két dolgot tud csinálni: előre menni, és tetszőleges szöggel forogni ([Comlogo](https://hu.wikipedia.org/wiki/Comenius_Logo) programozók előnyben). Ezeknek a műveleteknek az egymás után végrehajtásával nagyon sok önhasonló objektum leírható, vegyük példának a már ismert Koch görbét.
+
+### Koch görbe :turtle:
+
+Először nézzük meg a hozzárendelést, azaz az utasítások sorozatát, amit a teknősünk végre fog hajtani:
+
+$$
+\text{F} \mapsto \text{F} + 60 \text{F} - 120 \text{F} + 60 \text{F}
+$$
+
+Ez azt jelenti, hogy egy előremenetelt ($\text{F}$) helyettesíts azzal, hogy:
+
+- $\text{F}$: előre mész (természetesen kisebb egységet)
+- $+ 60$: elfordulsz hatvan fokkal balra
+- $\text{F}$ előre mész
+- $- 120$: elfordulsz százhúsz fokot jobbra
+- $\text{F}$: előre mész
+- $+ 60$: elfordulsz hatvan fokot balra
+- $\text{F}$: előre mész
+
+Ha összevetjük a fenti ábra első két ábrájával, akkor látjuk, hogy ez pont azt az alakzatot írja le, amit úgy kapunk, ha az egyenes középső harmadát kicseréljük egy egyenlő oldalú háromszög két másik oldalára.
+
+??? example További példák
+ A diasoron további példákat lehet találni:
+
+ 
+
+A Lindenmayer rendszerek egy magyar biológusról lettek elnevezve, hiszen arra használta őket, hogy különböző növények növekedését leírja. A módszer tényleg alkalmaz növényszerű önhasonló alakzatok leírására:
+
+{width=100%}
+
+??? example Zajos rendszerek
+ ## Fraktális zaj
+
+ 
+
+ - perturbációk generálása véletlenszerűen
+ - ezek szórását a finomabb szintek felé csökkentsük
+ - gyorsan csökken akkor sima görbe
+ - lassan csökken akkor rücskösebb görbe
+
+ ## Perlin zaj
+
+ Felhők, hegyek, minecraft világ generálásához.
+
+ 
+
+ - több skálán állítjuk elő a jelet
+ - egyre kisebb szinteken egyre kisebb értékkészletből, de egyre több mintapontot generálunk
+ - ezeket összeadva kapunk egy zajos tartományt
+
+ - ÉK gyorsan csökken akkor sima
+ - ÉK lassan csökken akkor rücskös
+
+## Káoszelmélet
+
+A kaotikus viselkedés tipikusan fraktálokat generál, tehát érdemes megvizsgálnunk a káosz fogalmát a fraktálok megértése érdekében.
+
+### Nyulak szigete
+
+Kezdjük a káoszelmélet egyik eredetproblémájával. Biológusok egy szigeten figyelték a nyúl populáció változását. Azt vették észre, hogy látszólag semmilyen rendszert nem követ, ezért felkértek egy matematikust, hogy alkosson meg egy rendszert, amiben már követhetőbb, hogy mi történik.
+
+Vegyünk fel egy koordináta-rendszert, ahol az $x$ tengely a jelenlegi évi nyulak számát ($x_n$) jelöli, az $y$ tengely pedig a következő évit ($x_{n+1}$). Ha kevés nyúl van a szigeten, akkor ha az összes szaporodik is, olyan nagyon nagy ugrást nem várhatunk a következő évben, tehát:
+
+- kevés nyúl $\mapsto$ picivel több nyúl
+
+Ez a növekedés eleinte lineáris, viszont elérkezik egy pont, amikor elkezd csökkenni. Hiszen a szigetnek véges erőforrásai vannak, nem tud végtelen sok nyulat eltartani, tehát ha már nagyon sok nyúl van, akkor kevés fog tudni szaporodni, és a következő évben megint kevés nyúl lesz:
+
+- sok nyúl $\mapsto$ kevés nyúl
+
+Ezt a viselkedést, hogy eleinte közel lineárisan növünk, utána pedig egy inflexiós pontot meghaladva közel lineárisan csökkenünk egy parabolával jól lehet jellemezni. A matematikus által megalkotott egyenlet a következő:
+
+$$
+x_{n+1}=C \cdot x_n \cdot (x_{\text{max}} - x_n)
+$$
+
+ahol $C \in \R$ és $x_{\text{max}}$ a maximális populáció száma. Ha pontosan ennyi nyúl lenne a szigeten, akkor a nyulak kihalnának.
+
+Vizsgáljuk meg a különböző lehetőségeket $C$ értékére.
+
+#### Kicsi erősítési tényező
+
+Ha $C$ kicsi, akkor a parabolánk az $y = x$ egyenes alatt fut:
+
+{width=100%}
+
+Válasszunk egy populációt az $x$ tengelyen (jelölje ezt a sárga pont) és kövessük végig, hogy mi történik.
+
+Először is behelyettesítjük a pontunkat a parabolikus függvényünkbe, amit úgy is szemléltethetünk, hogy a sárga ponttól függőlegesen felfele megyünk, ameddig el nem metsszük a parabolát. Ezután a parabola jelenlegi értéke a következő évi nyúl populáció, azaz $x_{n+1}$. Mi kíváncsiak vagyunk viszont $x_{n+2}$-re is, tehát ezt az értéket újra be kell helyettesíteni a parabolikus függvényünkbe. Ezt a behelyettesítést grafikusan úgy is szemléltethetjük, hogy elmetsszük vízszintesen az $y = x$ egyenest a parabolánk pontjából, utána pedig újra függőlegesen mozgunk ameddig nem metsszük el újra a parabolát.
+
+Ezt a folyamatot ismételve azt látjuk, hogy "konvergálunk" az origó felé, azaz a populáció évről évre csökken, végül pedig kihal.
+
+Észrevehetjük, hogy az origóban ez a folyamat ugyan azt a pontot eredményezi, mint amiből kiindultunk (azaz az origóhoz az origót rendeli). Az olyan pontokat, melyekre
+
+$$
+x^{\ast} = F(x^{\ast})
+$$
+
+teljesül egy függvény _fixpontjának_ nevezzük. Ha $C$ kicsi, akkor csak az origó a fixpont.
+
+#### Közepes erősítési tényező
+
+Ha $C$ közepes, akkor a parabolánk egy része az $y = x$ egyenes fölött fog futni. Ez azt is jelenti, hogy a parabola és az egyenes már két pontban fogják metszeni egymást:
+
+{width=100%}
+
+Abból a szempontból lesz "közepes" a $C$ erősítési tényező, hogy a második metszéspontban a parabola meredeksége abszolút értékben kisebb, mint egy. Ez azt jelenti, hogy bár csökken a parabola, de még "nem nagyon", éppen hogy csak picit negatív a meredeksége.
+
+Ha megint eljátsszuk a grafikus iterációt mint az előző esetben, akkor azt vesszük észre, hogy bárhonnan is indítjuk el a szimulációt, mindig ugyan abba a pontba jutunk: a második metszéspontba. Ez a metszéspont is egy fixpont, tehát logikus, hogy ide konvergálunk.
+
+#### Nagy erősítési tényező
+
+Ha a második metszéspontban a meredekség már abszolút értékben nagyobb mint egy, az azt jelenti, hogy a parabolánk szinte mindenhol nagyon meredek. Az iterációt ismét eljátszva, és követve $x_n$ értékét ezt kapjuk:
+
+{width=100%}
+
+Ekkor azt tapasztaljuk, hogy a nyulak száma évről évre látszólag teljesen véletlenszerűen ugrál, pont úgy, mint ahogy a biológusok ezt tapasztalták. Itt a legtöbb pont nem konvergál egy konkrét értékhez, hanem össze vissza változik.
+
+Fontos, hogy itt a véletlenszerűség tényleg csak látszólagos, hiszen a nyulak számát abszolút pontosan meghatározza a képletünk, melyet bevezettünk.
+
+Ez is egy kaotikus rendszer, hiszen nagyon érzékeny a kezdeti feltételekre: ha csak egy pár nyúl egyeddel is megváltozik a kezdeti $x_0$ feltételünk, amiből kiindulunk, akkor az $n$-edik lépésben megfelelően nagy $n$-re már teljesen más $(x_1)_n$ és $(x_2)_n$ értékeket kapunk.
+
+### Formális vizsgálat
+
+Vizsgáljuk meg a káosz jelenségét kicsit formálisabban, eltekintve a nyulak szigetétől. Azt láttuk, a következő állapot a jelenleginek valamilyen függvénye:
+
+$$
+x_{n+1} = F(x_n)
+$$
+
+és ennek a függvénynek a többszörös alkalmazásával későbbi állapotokat is megkaphatunk:
+
+$$
+\begin{align*}
+x_1 &= F(x_0) \\
+x_2 &= F(x_1) = F(F(x_0)) \\
+x_3 &= F(x_2) = F(F(F(x_0))) \\
+&\vdots
+\end{align*}
+$$
+
+Az a kérdés, hogy ez az állapotsorozat, vagy trajektória hogyan viselkedik hosszútávon. Konvergál-e valamilyen $x^{\ast}$ állapotba, vagy a végtelenségig oszcillál látszólag random állapotok között?
+
+A kérdés megválaszolásához a rendszer fixpontjait kell vizsgálnunk. Ha a trajektóriánk konvergens, akkor muszáj, hogy létezzen egy $x^{\ast}$ fixpont, melyre:
+
+$$
+x^{\ast} = F(x^{\ast})
+$$
+
+viszont ez önmagában nem elég, hiszen láttuk a nyúlsziget esetén is, hogy nagy $C$ esetén nem konvergált a sorozat sehova, de mégis volt két fixpontunk. Vezessünk be egy új fogalmat, mely le tudja írni egy $x^{\ast}$ fixpontról, hogy képes-e oda konvergálni a sorozat.
+
+### Fixpontok stabilitása
+
+Képzeljünk el egy golyót egy dombon, illetve egy völgyben:
+
+{width=100%}
+
+Ekkor a domb tetején, és a völgy alján lévő golyó is "stabil", azaz ha nem éri erőhatás, akkor nem fog elmozdulni. Mégis érezzük a különbséget: ha a domb tetején lévő golyót meglökjük, akkor az egyre csak távolodni fog a rendszer fixpontjától, míg a völgy alján lévő golyót ha meglökjük akkor egy idő után visszatér az eredeti helyzetébe.
+
+A fixpontjainkat is hasonlóan osztályozhatjuk. A stabil fixpontok azok olyan fixpontok, melyeket több kezdőállapotból is el lehet érni, a rendszer oda konvergál. A labilis fixpontok azok olyan fixpontok, melyeket csak egy darab kezdőállapotból lehet elérni, magából a labilis pontból, és a legkisebb zavar esetén is már nem konvergens a rendszer.
+
+Osztályozzuk gyakorlás képpen a nyúlszigetes példánk fixpontjait:
+
+- kicsi $C$ esetén csak egy fixpont volt, az origó, és minden ide konvergált, tehát ez egy stabil fixpont
+- közepes $C$ esetén már két fixpontunk volt: az origó, amitől minden távolodott (labilis), és a másik metszéspont, amibe minden konvergált (stabil)
+- nagy $C$ esetén két metszéspontunk volt, de az egész rendszer oszcillált, tehát mindkét fixpont labilis volt
+
+Hogyan tudjuk általánosságban (parabola felrajzolása nélkül) eldönteni egy fixpontról, hogy stabil, vagy labilis-e? Ugyan úgy, mint ahogy a mechanikai példánkban eldöntenénk: lökjük meg picit a labdát, és nézzük meg, hogy merre gurul. Mi is ezt tesszük: egy pici $\Delta x_n$ zavarást adunk hozzá a fixponthoz és nézzük meg, hogy idővel ez a zavarás nullához tart-e, vagy sem:
+
+$$
+x^{\ast} + \Delta x_{n+1} = F(x^{\ast} + \Delta x_n)
+$$
+
+Ha a $\Delta x_{n+1}$ sorozat a nullához tart, akkor előbb utóbb vissza érünk az $x^{\ast}$ fixpontba, tehát $x^{\ast}$ stabil, ellenkező esetben pedig labilis.
+
+A fenti egyenletet közelítve, és átalakítva azt kapjuk, hogy a stabilitás feltétele:
+
+$$
+\begin{align*}
+\text{Stabil: } &|F'(x^{\ast})| \lt 1 \\
+\text{Labilis: } &|F'(x^{\ast})| \gt 1
+\end{align*}
+$$
+
+A levezetésben feltettük, hogy $F$ egy egyszerű egyváltozós függvény, $x$ pedig egy skalár, ami bár a nyulak szigetén igaz volt, általánosságban nem feltétlenül, hiszen ha például $x$ egy virtuális világ állapota, akkor nagy eséllyel valamilyen vektor.
+
+## Szimulálható...?
+
+Térjünk vissza a téma eleji kérdéshez: szimulálható-e a természet egy virtuális világban? Tételezzük fel, hogy a valódi $\tilde{x}_0$ állapotot csak valamilyen közelítéssel ismerjük, azaz van valamilyen $\Delta x_0$ hibatényező (pl. mérési hiba). Ugyanez feltehető az $F$ függvényről, azaz:
+
+$$
+x_0 = \tilde{x}_0 + \Delta x_0 \\
+F(x) = \tilde{F}(x) + \Delta F(x)
+$$
+
+Ekkor a korábbi képletünket alkalmazva azt kapjuk, hogy:
+
+$$
+\overbrace{F(x)}^{\ast_0} \approx \underbrace{\tilde{F}(\tilde{x})}_{\ast_1} + \overbrace{\tilde{F}'(\tilde{x}) \Delta x}^{\ast_2} + \underbrace{\Delta F(\tilde{x})}_{\ast_3}
+$$
+
+ahol:
+
+$$
+\begin{align*}
+\ast_0 \colon& \text{általunk számított állapot} \\
+\ast_1 \colon& \text{valóságos állapot} \\
+\ast_2 \colon& \text{tökéletlen bemeneti állapot miatti hiba} \\
+\ast_3 \colon& \text{jelenlegi számítás hibája}
+\end{align*}
+$$
+
+Nézzük meg, hogyan viselkedik az állapotsorozatunk:
+
+
+
+$$
+\begin{align*}
+x_1 &= F(x_0) = \tilde{F}(\tilde{x}_0) + \tilde{F}'(\tilde{x}_0)\Delta x_0 + \Delta F(\tilde{x}_0) \\
+x_2 &= F(x_1) = \tilde{F}(\tilde{x}_0) + \tilde{F}'(\tilde{x}_1)\tilde{F}'(\tilde{x}_0)\Delta x_0 + \tilde{F}'(\tilde{x}_1)\Delta F(\tilde{x}_0) + \Delta F(\tilde{x}_1) \\
+&\vdots \\
+x_n &= F(x_{n-1}) = \tilde{F}(\tilde{F}(\ldots)) \\[-2.9em]
+ & \hspace{10.65em} + \overbrace{\tilde{F}'(\tilde{x}_{n-1}) \dots \tilde{F}'(\tilde{x}_1)\tilde{F}'(\tilde{x}_0)\Delta x_0}^{\text{akkumulált hiba}} \\
+ & \hspace{10.65em} + \tilde{F}'(\tilde{x}_{n-1}) \dots \tilde{F}'(\tilde{x}_0)\Delta F(\tilde{x}_0) \\
+ & \hspace{10.65em} + \tilde{F}'(\tilde{x}_{n-1}) \dots \Delta F(\tilde{x}_1) \\
+ & \hspace{10.65em} + \dots \\
+ & \hspace{10.65em} + \Delta F(\tilde{x}_{n-1})
+\end{align*}
+$$
+
+Ha $|F'| \gt 1$, akkor az összes hibatag exponenciálisan nő, tehát még akkor is, ha $\Delta x_0$ és $\Delta F$ tart a nullához, a hiba végtelenbe divergál. Ekkor már a rendszer állapotát sokkal inkább az akkumulált hiba tag határozza meg, mint a valódi állapot: ezt nevezzük káosznak.
+
+Ezáltal kaotikus rendszereket nem tudunk pontosan szimulálni, hiszen ha csak egy pár ezred milliméter mérési hibát is összeszedünk, akkor a szimulációnk teljesen más lesz, mint a valóság.
+
+## Pszeudó véletlenszám generátor
+
+A kaotikus rendszerek bár determinisztikusak, mégis véletlenszerűnek tűnnek. Ha belegondolunk, ugyan így működnek a kódunkban a pszeudó véletlenszám generátorok: adunk egy kezdeti feltételt (`seed`), és a rendszer (látszólag) véletlenszerű értékeket vesz fel, de ha valaki ismeri a kezdeti feltételünket, akkor le tudja szimulálni a rendszer működését, és abban az esetben már egyáltalán nem tűnik véletlenszerűnek.
+
+Nézzünk egy egyszerűsített példát a C véletlenszám generátor implementációjára:
+
+```c
+static uint x = 3;
+
+void seed(uint s) { x = s; }
+
+uint rand() {
+ x = F(x);
+ return x;
+}
+```
+
+lényegében ez is egy kaotikus rendszer, csak megfelelő $F$ függvényt kell választani. Azt szeretnénk, hogy egyenletes legyen, és hogy $|F'(x)| > 1$ nagy és állandó legyen.
+
+Egy lehetséges $F$ függvény az alábbi (ún. _kongruenciagenerátor_):
+
+$$
+F(x) = \{g \cdot x + c\}
+$$
+
+Ahol $\{\}$ a törtrész függvényt jelenti. Ekkor $F$ grafikonja az alábbi:
+
+{width=100%}
+
+Ez sajnos viszonylag determinisztikus, ezért biztonsági okokból nem használható.
+
+## Kaotikus rendszerek a síkon
+
+Próbáljunk meg a nyulak szigetéhez hasonlóan más kaotikus rendszereket létrehozni, melyeket síkon lehet ábrázolni. Ismét lesz egy $F$ iterált függvényünk, amely által alkotott pontsorozatot ha a síkon ábrázoljuk, akkor valamilyen érdekes alakzatra számítunk. Most a komplex sík egyik pontját, azaz egy $z = x + \bm{i} y$ komplex számot fogunk megadni $F$-nek. Ennek az az előnye, hogy $F$ továbbra is egy egyváltozós függvény, viszont az az egy változó a komplex síkon egy pontnak felel meg.
+
+Nézzünk egy példát arra, hogy mi lehet $F$. Tekintsük a
+
+$$
+F \colon z \mapsto z^2
+$$
+
+függvényt. Ez minden komplex számot négyzetre emel, és így alkot egy pontsorozatot a komplex síkon.
+
+Érdemes polárkoordinátákban is kifejezni $z$-t, hiszen az geometriai jelentést is hordoz magával.
+
+$$
+z = r e^{\bm{i}\theta}
+$$
+
+Ezt behelyettesítve $F$-be:
+
+$$
+F\colon r e^{\bm{i}\theta} \mapsto r^2 e^{2\bm{i}\theta}
+$$
+
+azaz észrevehetjük, hogy ha alkalmazzuk $F$-et $z$-re, akkor az $r$ abszolútérték a négyzetére, a $\theta$ szög pedig a kétszeresére változik:
+
+$$
+\begin{align*}
+r \mapsto r^2 \\
+\theta \mapsto 2\theta
+\end{align*}
+$$
+
+A szög kétszereződése most annyira nem érdekes, hiszen az $f \colon x \mapsto 2x$ egy lineáris függvény, viszont az abszolútérték változását egy négyzetes függvény írja le, amelyből már származik pár érdekes tulajdonság. Vizsgáljuk meg, hogy $F$ különböző bemenetek esetén milyen pontsorozatokat alkot! Három esetet különítünk el:
+
+### Első eset: $r \lt 1$
+
+Ekkor $r$, azaz $|z|$ kisebb mint $1$. Mivel az $f \colon x \mapsto x^2$ függvényre ezen a tartományon igaz az, hogy $f(x) \lt x$, ezért $f$ ismételt alkalmazásával $r$ értéke egyre csak csökkenni fog, amit geometriailag úgy lehet értelmezni, hogy ha a kezdőpontunk az egységkörön belül van, akkor a pontsorozat az origóba "esik", oda konvergál. A szög duplázódása miatt egy spirális pályát ír le a pontsorozat ahogy az origóba tart.
+
+Mivel az origó az $F$-nek egy stabil fixpontja, ezért logikus, hogy oda konvergál a pontok egy része, viszont nézzük meg a többi esetet.
+
+### Második eset: $r \gt 1$
+
+Hasonlóan érvelve beláthatjuk, hogy mivel az $]1, \infty[$ tartományon $f(x) > x$, ezért a pontjaink sehova sem fognak konvergálni, egyre csak távolabb kerülünk az origótól. Ez a pálya is spirális, de divergens.
+
+### Harmadik eset: $r = 1$
+
+Vizsgáljuk meg a konvergens és divergens tartományok határát. Ha az egységkörön választunk egy pontot, akkor mivel $1 = 1^2$, ezért a pontok sosem hagyják el az egységkört. A három eset egy ábrán (az első eset kék, a második zöld, a harmadik piros):
+
+{width=100%}
+
+A szög változása miatt egyre nagyobb ugrásokban "keringünk" az origó körül, de se nem közelítjük, se nem távolodunk tőle. Ez azt jelenti, hogy $f$ a kör pontjait állítja elő.
+
+Találkoztunk már hasonlóval. Idézzük fel, hogy egy $x$ fixpont esetén $x = F(x)$. Itt is valami hasonló történik, csak most nem egy fixpontunk van, hanem egy "fixkörünk", hiszen ha a körön választunk egy pontot, az sosem hagyja el a kört, szóval pongyolán megfogalmazva olyan, mintha $\text{kör} = F(\text{kör})$. Vezessünk be erre egy fogalmat!
+
+### Attraktorok
+
+!!! info 12.1. Definíció (Attraktor)
+ A $H$ halmazt az $F$ függvény _attraktorának_ nevezzük, ha:
+
+ $$
+ H = F(H)
+ $$
+
+ azaz $H$ pontjaink képe összességében éppen a $H$ halmazt adja.
+
+ ??? example Precízebb definíció
+ Mit is értünk pontosan a $H = F(H)$ jelölés alatt? Elsőre úgy tűnhet, hogy azt, hogy $H$ bármely $x$ elemére igaz, hogy ha alkalmazzuk rajta az $F$ függvényt, akkor $F(x)$ is $H$ beli lesz:
+
+ $$
+ \forall x \in H \colon F(x) \in H
+ $$
+
+ azaz
+
+ $$
+ F(H) \sube H
+ $$
+
+ és ez igaz is, viszont csak az egyik irányba! Ha $H$ attraktora $F$-nek, akkor a fenti állítás tényleg igaz, viszont a fenti állításból nem következik, hogy $H$ attraktora $F$-nek.
+
+ Hogy lássuk, hogy miért, tegyük fel, hogy $F$ egy olyan függvény, hogy $H$-nak mindig ugyan abba a pontjába viszi az értékeket, tehát minden $x$-re $F(x)$ ugyan az az érték. Ekkor $H$-nak nem áll elő az összes pontja, tehát nem lehet $F$ attraktora, viszont a fenti állítás mégis igaz rá.
+
+ A korábbi példánkban ez olyan lenne, mintha a $\theta$ szöget egy konstans függvény írta volna le, mondjuk $\theta = \pi$. Ekkor a kör bármely pontjára $F$-et alkalmazva a $z_{0} = e^{\bm{i}\pi}$ pontot kaptuk volna. Viszont nem ezt tapasztaltuk, hanem $F$ ismételt alkalmazásával előbb utóbb megkaptuk a kör összes pontját, azaz minden $x$ ponthoz létezett egy olyan $y$ pont, hogy $y$-ból megkaptuk $x$-et:
+
+ $$
+ \forall x \in H \thickspace \exists y \in H \colon x = F(y)
+ $$
+
+ azaz
+
+ $$
+ H \sube F(H)
+ $$
+
+ Az első állítással párosítva ez a két állítás ekvivalens azzal, hogy $H$ attraktora $F$-nek, és pontosan ezt is értjük a $H = F(H)$ jelölés alatt: $F$ csakis kizárólag $H$ pontjait állítja elő ($F(H) \sube H$), viszont az _összes_ pontot $H$-ban előállítja ($H \sube F(H)$). Se többet, se kevesebbet.
+
+ Tehát akkor összegezve:
+
+ $$
+ H \text{ attraktora } F \text{-nek} \iff H \sube F(H) \land F(H) \sube H
+ $$
+
+ azaz kifejtve:
+
+ $$
+ H \text{ attraktora } F \text{-nek} \iff \forall x \in H : \Big[(F(x) \in H) \land (\exists y \in H \colon x = F(y))\Big]
+ $$
+
+Így már precízen meg tudjuk fogalmazni azt, hogy mit értünk az alatt, hogy $\text{kör} = F(\text{kör})$. Ha a példánkban $H$-nak az egységkört választjuk, akkor pontosan azt kapjuk, amit az intuíciónk sugallt. Bizonyos értelemben kiterjesztettük a fixpontok fogalmát halmazokra.
+
+Ahogy a fixpontok esetében is voltak stabil és labilis pontok, így az attraktorok közül is lesznek stabilak és labilisak. A példánkbeli attraktor labilis, hiszen ha egy picit elmozdulunk az egységkörről, akkor vagy az origóba konvergálunk, vagy a végtelenbe divergálunk, de vissza az attraktorra semelyik esetbe se kerülünk.
+
+### Inverz iterációs módszer
+
+A labilis attraktorokból hogyan tudnánk stabilakat csinálni? Erre a feladatra ad megoldást az inverz iterációs módszer. Az az ötlet, hogy _ha $H$ halmaz $F$-nek egy labilis attraktora, akkor $F^{-1}$-nek stabil attraktora_, és fordítva. Később belátjuk, hogy miért, de először nézzünk egy példát.
+
+Legyen $F\colon x \mapsto x^2$, $H$ pedig az egységkör. Ekkor fennáll a $H = F(H)$ egyenlet. Alkalmazzuk $F^{-1}$-et mindkét oldalra:
+
+$$
+H = F(H) \rightarrow F^{-1}(H) = H
+$$
+
+tehát azt kaptuk, hogy ha $H$ attraktora $F$-nek, akkor $F^{-1}$-nek is. Tudjuk, hogy $F$ esetén $z_{n+1} = z_{n}^2$, de mi a helyzet $F^{-1}$-el? Ekkor
+
+$$
+z_{n+1} = \pm \sqrt{z_n}
+$$
+
+Ez persze nem egy függvény, hanem egy kétértékű leképezés, de mivel teljesül rá az, hogy $F^{-1}(H) = H$, ezért ez nem fog zavarni minket. A fenti egyenletből $r$-t és $\theta$-t kifejezve:
+
+$$
+\begin{align*}
+r_{n+1} &= \sqrt{n} \\
+\theta_{n+1} &= \frac{\theta}{2} + \pi \cdot \{0|1\}
+\end{align*}
+$$
+
+ahol a $\{0|1\}$ jelölés azt jelenti, hogy $z_{n+1} = + \sqrt{z_n}$ esetben $0$-val, $z_{n+1} = - \sqrt{z_n}$ esetben pedig $1$-el szorozzuk meg $\pi$-t.
+
+Próbáljuk meg egy pontra alkalmazni ezeket a kifejezéseket! Ennek az eredménye az alábbi képen látható.
+
+{width=100%}
+
+Mivel nem egy függvényünk van, hanem egy kétértékű kifejezésünk, ezért egy pontból kettő lesz, melyek egymás tükörképei az origóra nézve. Az előző példában láttuk, hogy az $f'\colon x \mapsto x^2$ függvény a $]-1, 1[$ tartományon a nullához konvergál, a $]-\infty, -1[ \; \cup \; ]1, \infty[$ tartományon pedig a végtelebe divergál, és ez volt az oka annak, hogy az attraktorunk labilis volt: mindkét esetben csak távolodtunk az $1$-től.
+
+Most viszont az $f\colon x \mapsto \sqrt{x}$ függvényünkre már más lesz igaz. A $]0, 1[$ és az $]1, \infty[$ tartományon is az $1$-hez konvergál! A kifejezésünkben lényegében kétszer van ez az $f$ függvény, csak egyszer $+$, máskor meg $-$ előjellel, így lefedik a teljes $]-\infty, \infty[$ intervallumot, ahol végig az egységkörhöz konvergálnak! Így beláthatjuk, hogy az attraktorunk _stabil_.
+
+Ezt precízebben megfogalmazva - megfelelően nagy $n$ esetén
+
+$$
+r_n = \sqrt[2^n]{r_0} \approx 1
+$$
+
+Ez megfelel annak az állításnak, hogy $F^{-1}$ csak az attraktor pontjait állítja elő. Már csak azt kell belátnunk, hogy az attraktor _összes_ pontját előállítja, melyhez a fázisszöget kell majd vizsgálnunk:
+
+$$
+\begin{alignat*}{2}
+\theta_n &= \frac{\theta_0}{2^n} &&+ \pi \cdot \{0|1\} . \{0|1\} \{0|1\} \ldots \\
+&\approx \underbrace{\cancel{\frac{\theta_0}{2^n}}}_{n \to \infty} &&+ \pi \cdot \{0|1\} . \{n-1 \text{ számjegyű bináris szám}\}
+\end{alignat*}
+$$
+
+mivel a fázisszög mindig feleződik, ezért a kezdeti $\theta_0$ szögnek a $2^n$-enede jelenik meg. Minden egyes lépésben vagy $0 \cdot \pi$-t vagy $1 \cdot \pi$-t adtunk hozzá, ami után megint osztottunk kettővel, és ismét hozzáadtunk. Értelmezhetjük ezeket az összeadásokat és kettővel való osztásokat is mint egy darab bináris számmal való szorzás. Nézzünk egy példát:
+
+$$
+\begin{align*}
+\theta_1 &= \frac{\theta_0}{2} + \pi \cdot 1 \\
+\theta_2 &= \frac{\theta_1}{2} + \pi \cdot 0 = \frac{\frac{\theta_0}{2} + \pi \cdot 1}{2} + \pi \cdot 0 = \frac{\theta_0}{2^2} + \pi \cdot 0 + \frac{\pi \cdot 1}{2^1} \\
+\theta_3 &= \frac{\theta_2}{2} + \pi \cdot 1 = \ldots = \frac{\theta_0}{2^3} + \pi \cdot 1 + \frac{\pi \cdot 0}{2^1} + \frac{\pi \cdot 1}{2^2} \\
+&\ldots
+\end{align*}
+$$
+
+Emeljünk ki $\pi$-t:
+
+$$
+\begin{align*}
+\theta_3 &= \frac{\theta_0}{2^3} + \pi \cdot 1 + \frac{\pi \cdot 0}{2^1} + \frac{\pi \cdot 1}{2^2} \\
+\theta_3 &= \frac{\theta_0}{2^3} + \pi \cdot (1 + 0 \cdot 2^{-1} + 1 \cdot 2^{-2}) \\
+&\ldots \\
+\theta_n &= \frac{\theta_0}{2^n} + \pi \cdot (1 + 0 \cdot 2^{-1} + 1 \cdot 2^{-2} + \ldots + 1 \cdot 2^{-(n-1)})
+\end{align*}
+$$
+
+A zárójelben pont egy bináris számot kapunk, ahol a kettedes pont előtt egy, utána pedig $n-1$ számjegy áll.
+
+??? example Számrendszerek segítség
+ Emlékezzünk vissza, hogy például tízes számrendszerben egy számot szintén hasonló alakra lehet hozni:
+
+ $$
+ 74.513_{10} = 7 \cdot 10^{1} + 4 \cdot 10^{0} + 5 \cdot 10^{-1} + 1 \cdot 10^{-2} + 3 \cdot 10^{-3}
+ $$
+
+ Hasonlóan működik ez kettes számrendszerben is:
+
+ $$
+ 101.11_2 = 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 + 1 \cdot 2^{-1} + 1 \cdot 2^{-2}
+ $$
+
+ A fenti esetben is ugyan ez történik.
+
+Mivel minden lépésben a $+$-os és a $-$-os ágat is végrehajtjuk, ezért az $n.$ lépésben az $n$ bites számunk összes kombinációja meg fog jelenni, tehát a $[0, 2\pi[$ tartományban egyenletesen minden pontot lefedünk. Ezzel beláttuk azt is, hogy a kör összes pontja előáll (legalábbis az $n \to \infty$ esetben, a gyakorlatban meg csak közelítőleg).
+
+Fontos még kiemelni, hogy a káosz egyik tulajdonságát nagyon jól szemlélteti ez a példa, mégpedig a kezdőfeltételek információjának eltűnését. Hiszen nagy $n$ esetén bármely $r_0$-ra $\sqrt[2^n]{r_0} \approx 1$ és bármely $\theta_0$-ra $\theta_0/2^n \approx 0$, tehát ha mondjuk $n = 10^{100}$, akkor $r_n$-ből és $\theta_n$-ből lehetetlen kitalálni, hogy mi volt $r_0$ és $\theta_0$.
+
+Ezt a folyamatot algoritmikus szemptonból is megközelíthetjük. A $z_0$ kezdeti pontra ha alkalmazzuk a kétértékű leképezésünk, akkor két pontot kapunk, a $+\sqrt{}$ és a $-\sqrt{}$ irányba egyet-egyet. Ezekre ismételten a leképezésünket alkalmazva további pontokat kapunk, egy bináris fa struktúrában.
+
+Az exponenciális növekedés miatt ha ezt meg akarnánk programozni, akkor nagyon hamar elfogyna a gépünk memóriája, tehát felmerülhet a kérdés, hogy ahelyett, hogy szélességi bejárást folytatunk, és a teljes fát ábrázolni akarjuk, nem tudjuk valahogy ezt lecserélni valamilyen mélységi bejárásra?
+
+Ez annak felelne meg, mintha a bináris fa tetejéről kiindulva mindig csak az egyik élen mennénk le, azaz mindig vagy $+\sqrt{}$ vagy $-\sqrt{}$-el képeznénk új pontokat. Ezt a választást úgy kéne meghoznunk, hogy a mélységi bejárás által meglátogatott pontok is elég sűrűn lefedjék az attraktort, ami közel sem triviális. Ha mindig csak $+\sqrt{}$ vagy $-\sqrt{}$ irányba megyünk, akkor a $\theta_n$ fázisszög $0$ és $2\pi \equiv 0$ marad végig, tehát nem fedjük le az attraktort.
+
+Próbáljunk meg mondjuk felváltva választani, ekkor:
+
+$$
+\begin{align}
+\theta_{2n} \approx 1.010 \ldots \cdot \pi = \frac{4 \pi}{3} \\
+\theta_{2n + 1} \approx 0.101 \ldots \cdot \pi = \frac{2 \pi}{3}
+\end{align}
+$$
+
+Sajnos láthatjuk, hogy még így is csak két különböző pontot sikerült elérnünk, és ez általánosítható: ha egy $n$ hosszú periódussal haladunk, akkor $n$ darab pontot fogunk lefedni csak. Ez azt jelenti, hogy semmilyen periodikus sorozattal nem tudjuk elérni, hogy lefedjük a teljes attraktort.
+
+A megoldást azt fogja jelenteni, hogy _véletlenszerűen_ választunk a leképzés két eredménye közül. Ekkor pozitív valószínűsége van bármely pontnak arra, hogy kiválassza az algoritmusunk. Ezzel tehát megoldottuk a kezdeti problémánkat: nem kell szélességi bejárást csinálni, ami az összes erőforrásunkat megenné, hanem szimplán minden leképezés után csak az egyik ággal dolgozunk tovább, amit véletlenszerűen döntünk el.
+
+### Attraktorok felrajzolása
+
+Mielőtt elkezdünk programokat írni, ki kell találnunk, hogy egyáltalán hogyan tudjuk vizualizálni az attraktorainkat. Az egyik megközelítés az lehet, hogy felismerjük, hogy az attraktor az divergens és konvergens régiókat választ el egymástól. Ha az összes konvergens pontot feketére színezzük, és a divergenseket fehéren hagyjuk, akkor a keletkező fekete alakzatoknak a határavonalai lesznek a függvény attraktorai.
+
+Hogyan tudjuk eldönteni, hogy egy pont divergens-e vagy sem? Tudjuk, hogy például $F \colon z \mapsto z^2$ esetében
+
+$$
+z_{n+1}=z_{n}^2
+$$
+
+tehát, ha
+
+$$
+\lim_{n \to \infty} z_n \lt \infty
+$$
+
+akkor nem divergens. Persze amikor programozunk, akkor közelítenünk kell, általában jó nagy $n$-ig elmegyünk, és megnézzük, hogy meghalad-e egy bizonyos távolságot a $|z_n|$.
+
+??? example "Fekete-fehér az unalmas"
+ Későbbi diákon, illetve az interneten is sok helyen színekkel ábrázolják a Julia halmazokat.
+
+ Ne jöjjünk zavarba, az alap logika ugyan az, annyi változtatást tehetünk, hogy a divergáló pontoknál megnézzük a küszöböt elérve, hogy milyen távol kerültek az origótól. A "leggyorsabban" divergáló ponthoz ha hozzárendelünk egy sötétkéket, a "leglassabban" konvergálóhoz pedig egy pirosat, és közöttük pedig lineárisan interpolálunk, akkor máris megkaphattuk azokat a szép színes Julia halmazokat amik fel-fel bukkannak az interneten.
+
+### Julia halmaz
+
+Így, hogy minden eszközünk meg van rá, próbáljunk meg felrajzolni pár attraktort! Ahogy korábban is láttuk, az $F \colon z \mapsto z^2$ függvény attraktora az egységkör. Lássuk tehát!
+
+{width=100%}
+
+Hát... ennél azért könnyebb algoritmusaink is vannak körök felrajzolására...
+
+Próbáljunk kicsit módosítani $F$-en, hogy érdekesebb alakzatokat kapjunk. Nézzük például az
+
+$$
+F': z \mapsto z^2 + c
+$$
+
+függvényt, ahol $c \in \cnums$. Ekkor ha variáljuk $c$ értékét, rettenetesen sok érdekes attraktort kapunk:
+
+{width=100%}
+
+Az $F'$ összes attraktorának halmazát _Julia halmaznak_ nevezik (ejtsd: \[zsúlia\]).
+
+#### Implementáció
+
+Nézzük meg a kitöltött Julia halmaz implementációját. Pszeudokód szinten relatívan egyszerű: a kamerának kiválasztjuk egy pixelét (pontosabban egy olyan tartományt a virtuális világban ami egy pixelnek felel meg), és megnézzük, hogy az a pont divergál-e vagy sem. Ehhez választunk egy jó nagy küszöböt, és alkalmazzuk rá az $F'$ függvényt. A konvergenciájától függően vagy feketére vagy fehérre színezzük, és megyünk tovább (ehhez a megközelítéshez kódot az előadásdiákon találtok).
+
+Érezhető viszont, hogy ez picit lassú. Nagyon sok időt töltünk el olyan pontokkal is, amik már pár iteráció után divergálnak, és ha nagyon hatékonyak akarunk lenni, akkor a divergens pontokkal még csak foglalkoznunk se kéne. Másrészt pedig pixelvezérelt, ami a modern, nagy felbontású képernyők esetében nem hatékony.
+
+Próbáljuk meg implementálni a fentebbi véletlenszerűségre alapuló algoritmust. Csak az attraktor pontjait (a konvergens pontok nélkül) előállíthatjuk az inverz iteráció módszerével is. Ez egy "gyökvezérelt" megközelítés, és sokkal hatékonyabb lesz. Az alapjait már fentebb tárgyaltuk: az attraktor egy pontjából elindítjuk az iterációt és minden lépésben alkalmazzuk $F^{-1}$-et a pontunkra, és véletlenszerűen választunk a $\pm$ előjelek között. Ezt elég nagy küszöbig ismételve, ha az összes pontot amit bejártunk kiszínezünk feketére, akkor megkapjuk az attraktort.
+
+Stabil attraktorok esetén könnyű meghatározni az attraktor egy pontját (elindítunk egy sorozatot az attraktor közeléből, és ami után elértük, azokat a pontokat amikkel csak megközelítettük eldobjuk), viszont labilis attraktorok esetén muszáj az attraktor egy pontját, azaz $F$ vagy $F^{-1}$ egy fixpontját kiválasztanunk.
+
+```cpp
+const int DEPTH = 100;
+
+void generate_attractor(Complex c) {
+ // z = z^2 + c másodfokú egyenlet valamelyik gyöke
+ Complex z = get_starting_value(c);
+
+ for(n = 0; n < DEPTH; n++) {
+ if(VisibleInWindow(z)) {
+ pixel = WindowViewport(z);
+ image[pixel] = black;
+ }
+ // z = sqrt(z - c)
+ z = F_inverse(z, c);
+
+ // randomly choose pos or neg root
+ if (get_random_number(0, 1) > 0.5) z = -z;
+ }
+}
+```
+
+Részletesebb magyarázathoz ajánlom az [előadásvideó ezen részét](https://youtu.be/4-5_UzT6SFQ?si=9OIrHGFQrlBpCLUV&t=2317).
+
+## Mandelbrot halmaz
+
+Mandelbrot arra volt kíváncsi, hogy miért van az, hogy a Julia halmazok néhány $c$-re összefüggőek, bizonyos esetekben viszont meg különálló ponthalmazok. Definiált egy halmazt, ami azon $c$ komplex számokból áll, amelyekre az ahhoz tartozó Julia halmaz összefüggő.
+
+Ha a Mandelbrot halmazt ábrázoljuk a síkon, akkor több dolgot is tapasztalhatunk:
+
+- az alakzat fraktális, tehát bármennyire is ráközelítünk nem egyszerűsödik le, végtelenségig új alakzatok és komplexitások tűnnek fel.
+- nem önhasonló, tehát a végtelen komplexitás soha sem ismétlődik
+
+Ha egy pontra "végtelenségig" rá tudnánk közelíteni, akkor a közvetlen környezetében a hozzá tartozó Julia halmaz jelenne meg. A Mandelbrot halmazt az emberiség által ismert legbonyolultabb geometriai alakzatnak tartják.
+
+!!! example Érdekességek
+ Egy videó, ami ugyan kicsit szájbarágósan, de élvezhetően elmagyarázza a komplex számokat és a Mandelbrot halmazt: [The Mandelbrot Set (VSauce)](https://youtu.be/MwjsO6aniig?t=71)
+
+ Isten létezésének bizonyítása a Mandelbrot halmazzal (ennek még kevesebb köze van az anyaghoz): [Proving God exists using Math](https://www.youtube.com/watch?v=z0hxb5UVaNE)
+
+ A 3D változata "Mandelbulb" néven ismert.
+
+Hogyan tudnánk mégis ábrázolni? Hát ha pusztán a definícióból indulunk ki, akkor elég nehezen. Szerencsére vannak egyszerűbb módszerek.
+
+### Julia halmazok összefüggősége
+
+Vizsgáljuk meg az iteráció során létrejövő alakzatokat topológiailag. Az "összefüggő" Julia halmazokat azért neveztük annak, mert egy "körvonal" szerű alakzatra hasonlított: ha elindulunk az egyik pontból, és végigmegyünk az alakzaton, akkor visszajutunk az eredeti pontunkba úgy, hogy az alakzat minden pontját meglátogattuk. A nem összefüggő esetben ilyen határgörbe nincs. Nézzük meg, hogy ez milyen implikációkkal bír.
+
+#### Külső határ becslése
+
+Ahogy végrehajtjuk az iterációs folyamatot, próbáljuk meg megbecsülni az egyes lépésekben a külső határt, minél pontosabban! Emlékezzünk vissza, hogy ha $F(z) = z^2 + c$, akkor $F^{-1} = \pm \sqrt{z - c}$. $F^{-1}$ attraktora már stabil, tehát tudunk vele dolgozni.
+
+A kezdeti becslésünk legyen egy jó nagy $H_0$ kör, ami az egész Julia halmazt körülveszi. Ez még igen pontatlan, de minden egyes lépésben majd finomítunk rajta. Itt most $F^{-1}$-et nem csak egy pontra, hanem a $H_0$ körlemez összes pontjára fogjuk alkalmazni. Ennek során két esetet különíthetünk el:
+
+- azok a pontok, amik már eleve rajta voltak az attraktoron nem kerülnek le róla, hiszen tudjuk, hogy $F(H) = H$,
+- azok a pontok, amik nem voltak rajta az attraktoron valamennyivel közelebb kerülnek hozzá, bizonyos részük esetleg rá is érkezik az attraktorra.
+
+Ezek alapján láthatjuk, hogy az attraktoron nem lévő pontok száma csökkent, és egy pontosabb becslést kaptunk, nevezzük $H_1$-nek. Ekkor $H_1$ ugyan úgy tartalmazza a teljes attraktort mint $H_0$, viszont kevesebb olyan pontot tartalmaz, ami nincs az attraktoron. Ezt természetesen tovább ismételhetjük, és azt kapjuk, hogy
+
+$$
+\begin{align*}
+H_1 =& \; F(H_0) \\
+H_2 =& \; F(H_1) \\
+H_3 =& \; F(H_2) \\
+&\vdots
+\end{align*}
+$$
+
+Mivel $H_0$ egy körlemez volt, ezért a határvonala egy kör. Az a kérdés, hogy ahogy iteráljuk a körvonalat, akkor lesz-e egy olyan pont, ahol ez a kör szétesik és különálló pontok összességévé válik?
+
+#### Határ összefüggősége
+
+Ennek eldöntéséhez a kör határára kell végrehajtani $F^{-1}$-et. Mivel a komplex számokon végzett műveleteknek geometriai jelentősége is van, ezért próbáljuk meg grafikusan vizsgálni, hogy mi történik az egyes pontokkal. Tudjuk, hogy
+
+$$
+H_{n+1} = \pm \sqrt{H_n - c}
+$$
+
+ahol $c \in \cnums$, egy konstans az adott Julia halmaz tekintetében.
+
+Vizsgáljuk azt az esetet először, amikor $c$ a $H_n$ körszerű alakzaton belül van. A $H_n - c$ egy eltolás, aminek során a $c$ pontunk az origóba kerül, és a teljes $H_n$ alakzat is ennek megfelelően eltolódik. Ezután a négyzetgyökvonás jön, amihez emlékezzünk vissza, hogy egy tetszőleges $c_0$ komplex számra
+
+$$
+c_0 = r \cdot e^{\bm{i} \theta} \\[1em]
+\text{akkor} \\[1em]
+\sqrt{c_0} = \sqrt{r \cdot e^{\bm{i} \theta}} = \sqrt{r} \cdot e^{\bm{i} \theta/2}
+$$
+
+azaz $c_0$ abszolút értékének (origótól való távolságának) a négyzetgyökét vesszük, a fázisszögének pedig a felét. Ez egy ilyesmi alakzatot eredményez (itt a körvonal összes pontjának vettük a négyzetgyökét)
+
+{width=100%}
+
+Látjuk, hogy mivel a $\theta$ fázisszög feleződött, ezért a teljes körből csak egy félkör lett. Ez persze csak a $+\sqrt{}$ ág, de a $-\sqrt{}$ komponenst megkaphatjuk úgy, ha szimplán tükrözzük a $+\sqrt{}$ alakzatunkat az origóra. Mivel két félkörszerű alakzatot csatlakoztattunk össze az origónál, ezért egy összefüggő alakzatot kaptunk, tehát ebben az esetben $H_{n+1}$ is összefüggő.
+
+Tekintsük meg azt az esetet, amikor $c$ nincs a $H_n$ alakzaton belül. Ekkor ha eltoljuk $H_n$-t úgy, hogy a $c$ pont az origón legyen, akkor az origót nem fogja tartalmazni az eltolt $H_n$. Ez azért fontos, mivel ha ismét vesszük a négyzetgyökét $H_n$-nek, akkor most nem egy félkörszerű alakzatot kapunk, hanem egy körszerű, önálló alakzatot, amit ha tükrözünk az origóra, akkor egy másik, teljesen különálló alakzatot kapunk
+
+{width=100%}
+
+Tehát megkaptuk a válaszunkat a kérdésünkre: egy Julia halmaz akkor összefüggő ha a hozzátartozó $c \in \cnums$ az attraktor által körbevett stabil tartományon belül esik, vagy magának az attraktornak a része.
+
+### Felrajzolás
+
+Így már egy teljesebb definíciót tudunk adni a Mandelbrot halmazra:
+
+!!! info 12.2. Definíció (Mandelbrot halmaz)
+ Azon $c$ komplex számok halmaza, amelyekre:
+
+ - A $z \mapsto z^2 + c$ Julia halmaza összefüggő.
+ - A $c$ a Julia halmaz attraktorában, vagy konvergens tartományában van.
+ - A $z_{n+1} = z_n^2 + c$ iteráció a $c$-ből indítva nem divergens.
+
+Így már sokkal könnyebb felrajzolni grafikusan a Mandelbrot halmazt.
+
+???+ example Déjà vu
+ Ez a vizsgálat nagyon hasonló az eredeti Julia halmaz kiszámításánál alkalmazott iterációhoz, a különbség lényegében az, hogy amikor a Julia halmazt rajzoltuk föl, akkor ez a $c$ komplex szám a halmazunk összes pontjára ugyan olyan értékű volt és azt vizsgáltuk, hogy ha a komplex számból indulunk el, akkor a folyamat divergens-e vagy sem; most pedig ez a $c$ komplex szám nem konstans, hanem az iteráció kezdeti pontjának megfelelő.
+
+A fent említett hasonlóság miatt a Mandelbrot halmazt kirajzoló kód eléggé hasonlít a Julia halmazt kirajzolóhoz:
+
+```cpp
+const int DEPTH = 100;
+
+void Mandelbrot() {
+ for(Y = 0; Y < Ymax; ++Y) {
+ for(X = 0; X < Xmax; ++X) {
+ // Lekérjük az aktuális pixelt
+ Complex c = ViewportWindow(X,Y);
+ Complex z = c; // vagy z = 0, a kettő ekvivalens
+ for(n = 0; n < DEPTH; ++n) z = z * z + c;
+ image[Y][X] = (abs(z) < 2) ? Color.black : Color.white;
+ }
+ }
+}
+```
+
+A fenti kód részletesebb magyarázatát, illetve a hozzá tartozó GPU implementációt az erről szóló [Grafika videóban](https://youtu.be/4-5_UzT6SFQ?si=y_a7fh_TWTc9ZbYI&t=3150) találod.
+
+---
+
+# Kvíz
+
+!!! quote ""
+ A 2024/2025/II félévben nem voltak ebben a témában kvízek.
+
+!!! question 1\. Jelölje ki azon komplex számokat, amelyeket a Mandelbrot halmaz tartalmaz.
+ - $-1+i$
+ - $-1$
+ - $1$
+ - $0$
+ - $i$
+ - $-i$
+
+??? tip Megoldás
+ "Azon $c$ komplex számok, amelyekre a $z \to z^2 + c$ Julia halmaza összefüggő." azaz ahol $z \to z^2 + c$ nem divergál.
+
+ - [ ] -1+i
+ - Magyarázat:
+
+ $$
+ \begin{align*}
+ z_1 &= -1+i \\
+ z_2 &= 1 -2i +i^2 + (-1+i) = -1-i \\
+ z_3 &= 1 +2i +i^2 + (-1+i) = -1+3i \\
+ &\vdots \implies \text{Divergens}
+ \end{align*}
+ $$
+
+ - [x] -1
+ - Magyarázat:
+
+ $$
+ \begin{align*}
+ z_1 &= -1 \\
+ z_2 &= 1 - 1 = 0 \\
+ z_3 &= 0 - 1 = -1 \\
+ &\vdots \implies \text{Oszcillál}
+ \end{align*}
+ $$
+
+ a többi példa gyakorlásnak:
+
+ - [ ] 1
+ - [x] 0
+ - [x] i
+ - [x] -i
+
+---
+
+!!! question 2\. Az $F(z)=e^z + c$ függvényt iteráljuk, ahol a kezdeti állapot $z_0=\frac{\ln(2)}{2} + {i}\frac{\pi}{4}$ és $c=-1-i$. Mennyi az első iteráció után az állapot valós része?
+
+??? tip Megoldás
+ $$
+ \begin{align*}
+ z_1 &= e^{\frac{\ln(2)}{2}} \cdot e^{i\frac{\pi}{4}} -1 -i \\
+ &= \sqrt2 (\cos(\frac \pi 4)+ i \sin(\frac \pi 4)) -1 -i \\
+ &= \sqrt2 \cdot \frac{\sqrt 2}2 (1+ i) -1 -i = 0
+ \end{align*}
+ $$
+
+---
+
+!!! question 3\. Mekkora a Hausdorff dimenziója az alábbi L-rendszer által definiált alakzatnak:
+ F $\to$ FFFFFFFFF
+
+??? tip Megoldás
+ Elképzeljük magunk előtt a teknőcöt, csak egyenesen megyünk, az eredmény egy $9$ részből álló egyenes szakasz.
+ Tehát ha nem ugrik be egyből, hogy ez $1$ dimenziós, akkor itt van levezetve:
+
+ $$
+ D = \frac{\log{N}}{\log(1/r)} = \frac{\log 9}{\log{\frac 1 {1/9}}} = 1
+ $$
+
+---
+
+!!! question 4\. Mekkora a Hausdorff dimenziója az alábbi L-rendszer által definiált alakzatnak:
+ F $\to$ -90F+90F+90FF-90F-90FF+90F+90F
+
+??? tip Megoldás
+ Érdemes lerajzolni, szép négyszögjelféleség.
+ A szakaszok hossza az egész kiterjedésnek $1/3$-a, és $9$ szakaszunk (ahogy $9$ F betű is) van.
+
+ $$
+ D = \frac{\log{N}}{\log(1/r)} = \frac{\log 9}{\log 3} = 2
+ $$
+
+---
+
+!!! question 5\. Nagy Britannia partvidékének hosszát megmérve $256$ km-es vonalzóval, a hossz $2048$ km-re adódott. Amikor megismételtük a mérést $128$ km-es vonalzóval, akkor eredményül $2560$ km-t kaptunk. Mekkora a partvidék vonalzó dimenziója?
+
+??? tip Megoldás
+ $$
+ r = \frac{128}{256}
+ $$
+
+ $$
+ N = \frac{20}{8}
+ $$
+
+ Tehát:
+
+ $$
+ D = \frac{\log{N}}{\log(1/r)} = 1.32
+ $$
+
+---
+
+!!! question 6\. Tekintsük az alábbi iterált függvényt: $F(x)=2x(1-x)$. Mekkora a függvény legnagyobb fixpontjának az értéke?
+
+??? tip Megoldás
+ Az $x = 2x(1-x)$ helyen.
+
+ $$
+ \begin{align*}
+ x &= 2x - 2x^2 \\
+ 0 &= 2x^2 - x \\
+ x_1 &= 0 \\
+ x_2 &= \frac 1 2 \\
+ \end{align*}
+ $$
+
+ Tehát a válasz $0.5$
+
+---
+
+!!! question 7\. Tekintsük az alábbi iterált függvényt: $ F(x)=Cx(1-x)$. Legalább mekkorának kell lennie a $C$ faktornak, hogy az iteráció ne legyen konvergens?
+
+??? tip Megoldás
+ A stabil pontok:
+
+ $$
+ \begin{align*}
+ x &= Cx(1-x) \\
+ x_1 &= 0 \\
+ x_2 &= \frac{C-1}{C}
+ \end{align*}
+ $$
+
+ Az $x_0$ pont akkor stabil, ha $|F'(x_0)| < 1$, tehát:
+
+ $$
+ \begin{align*}
+ F'(x) &= C(1-2x) \\
+ F'(x_1) &= C
+ \end{align*}
+ $$
+
+ tehát $|C| < 1$ és
+
+ $$
+ \begin{align*}
+ F'(x) &= C(1-2x) \\
+ F'(x_2) &= -C + 2
+ \end{align*}
+ $$
+
+ $|-C+2| < 1$ azaz $1 < C < 3$ vagyis a válasz $3$
+
+---
+
+!!! question 8\. Adja meg az alábbi Sierpinski szőnyeg Hausdorff dimenzióját:
+ 
+
+??? tip Megoldás
+ $$
+ r = \frac{1}{3}
+ $$
+
+ $$
+ N=8
+ $$
+
+ Tehát:
+
+ $$
+ D = \frac{\log 8}{\log 3} = 1.9
+ $$
+
+---
+
+!!! question 9\. Mekkora a Hausdoff dimenziója az alábbi alakzatnak (két értékes jegyre):
+ 
+
+??? tip Megoldás
+ $$
+ r = \frac{1}{2}
+ $$
+
+ $$
+ N=3
+ $$
+
+ Tehát:
+
+ $$
+ D = \frac{\log 3}{\log 2} = 1.58
+ $$
diff --git a/docs/notes/sem4/computer_graphics/lectures/2.md b/docs/notes/sem4/computer_graphics/lectures/2.md
new file mode 100644
index 0000000..d877300
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/2.md
@@ -0,0 +1,374 @@
+
+
+# Grafikus hardver és szoftver
+
+## Funkcionális modell
+
+A felhasználónak mutatunk egy virtuális világot, amit tud módosítani, és ezeket a módosításokat látja is. Az alábbi grafikus csővezetékrendszer mutatja ezt be:
+
+{width=100%}
+
+A CPU-ra megírt program (amit mi írunk pl. C++-ban) az a bemeneti csővezetéket irányítja. A GPU műveletei közül ami pirossal van jelölve, azokhoz "fix hardware implementáció" tartozik, azaz mi nem tudunk bele nyúlni. A zölddel jelölt műveletekre viszont nekünk is hatásunk lehet, úgynevezett _vertex_ és _pixel shader_-ek írásával.
+
+A GPU csak pontokat, szakaszokat, és háromszögeket tud elfogadni. Minden ezekkel van közelítve, csak aprólékosan.
+A _vektorizáció_ folyamán tetszőleges görbéket hozunk létre ezekből.
+
+## Szoftver architektúra
+
+{width=100%}
+
+Az eseménykezeléshez glutot használunk, a lényeg, hogy a main-ben regisztrálunk event handlereket (pl. onDisplay) és az operációs rendszer eseményeire a glut callback-ként hívja a mi függvényünket. Eseményvezérelt programozás lesz.
+
+## OpenGL
+
+{width=100%}
+
+Elemezzük a pipelinet:
+
+- VBO (vertex buffer object): ebben tárolunk pontokat és a hozzá tartozó alakzatokat
+- VAO (vertex array object): ebben több VBO-t tárolhatunk, a műveletek (transzformációk, vágás) ezen történnek.
+
+Felmerülhet a kérdés, hogy hogyan éri meg a VBO-kat tárolni a VAO-ban? Több megközelítés lehet: csinálhatjuk például azt, hogy az egyik VBO csak a pontok koordinátáit tárolja el, a másik csak a pontok színeit, stb. Ezeket utána külön `AttribArray`-ekbe töltjük fel. Könnyebben kezelhető, hiszen a különböző féle adatok el vannak különítve, de nem túl hatékony. Egy másik lehetőség, hogy egy darab VBO van, és minden pont minden tulajdonsága ebben van. Nehezebb kezelni, hiszen vegyesen vannak az adatok, több programozási energiabefektetést igényel, viszont hatékonyabb.
+
+??? example Bővebben a VBO/VAO-ról...
+ A VBO és VAO megértését segítő [videó](https://www.youtube.com/watch?v=Rin5Cp-Hhj8).
+
+A `glDrawArrays` függvény juttatja el ezeket a VBO/VAO-kat a GPU-hoz. Ezek floating point regiszterekbe kerülnek. A vertex shader meghatározza a normalizált eszközkoordináta-rendszert ($(-1, -1)$ és $(1, 1)$ között). Ezután a `gl_Position` tárolja a normalizált eszközkoordinátákat, az itt lévő regiszterek pedig például színértéket tárolhatnak.
+
+!!! note ""
+ A `gl_Position`-ben tárolt értékek mindig 4 dimenziósak lesznek és a 3D-s projektív geometriai szabályok szerint lesznek értelmezve.
+
+
+
+Ezt követően fix műveleti egységek mennek végbe (vágás, raszterizáció, stb.). Ezek optimalizált hardware műveletek.
+
+- Vágás: kidobjuk ami "nem látszik".
+- Viewport transzformáció: A normalizált eszközkoordinátákból a képernyő koordináta-rendszerévé ($(0, 0)$ és pl. $(600, 800)$ között) való transzformálás.
+- Raszterizáció: Egy adott sokszög csúcspontjai ismeretében meghatározza az összes olyan pixelt ami benne van a sokszögben, interpolálja a regiszter értékeket (pl. szín).
+
+Ezeket követően már konkrét pixelekkel dolgozik a GPU. A fragment shader a pixelek tényleges színét határozza meg. Végezetül kompozitálás után a pixelek bekerülnek a rasztertárba, ahonnan már egyenesen a képernyőre kerülnek. A kompozitálás azért fontos, hiszen itt dől el, hogy melyik pixelek lennének más pixelek "mögött", az átlátszóság kezeléséhez kiemelten fontos.
+
+### Primitívek
+
+Tételezzük fel, hogy tetszőleges pontunk a VAO-ban (legyenek ezek $x_i$-vel jelölve, ahol $i \in \N $). A `gl_DrawArrays` hogyan fogja őket értelmezni? Tekintsük először a függvény paramétereit:
+
+```cpp
+glDrawArrays(primitiveType, startIdx, numOfElements);
+```
+
+A `startIdx` és `numOfElements` magáért beszélnek, viszont a `primitiveType`-ról részletesebben szót kell ejteni. Ez a jegyzet 7 darab ilyen primitívet tárgyal, ezek pedig:
+
+- `GL_POINTS`: külön pontokként jeleníti meg a VAO pontjait
+- `GL_LINES`: kettessével összeköti a megadott pontokat, így például az alábbi _szakaszok_ jönnének létre: $(x_0, x_1), (x_2, x_3), ...$
+- `GL_LINE_STRIP`: az adott pontot mindig a következő ponttal köti össze: $(x_0, x_1), (x_1, x_2), (x_2, x_3), ...$
+- `GL_LINE_LOOP`: ugyan az mint a `GL_LINE_STRIP`, csak a legutolsó pontot a legelsővel köti össze
+- `GL_TRIANGLES`: minden három egymás utáni pont egy háromszög: $(x_0, x_1, x_2), (x_3, x_4, x_5), ...$
+- `GL_TRIANGLE_STRIP`: az utolsó pontot veszi hozzá az előző kettőhöz: $(x_0, x_1, x_2), (x_1, x_2, x_3), (x_2, x_3, x_4) ...$
+- `GL_TRIANGLE_FAN`: az első ponthoz veszi a legutóbbi kettőt: $(x_0, x_1, x_2), (x_0, x_3, x_4), (x_0, x_5, x_6) ...$
+
+### Állapotgép jelleg
+
+Az OpenGL egy állapotgép, azaz nem kell mindig minden függvénynek megadni minden paramétert, hanem ezeket "globálisan" beállítjuk, utána pedig a függvények ezekkel dolgoznak (Például nem kell a pontok méretét megadni a `glDrawArrays`-ben, hanem a `glPointSize` függvénnyel beállítjuk ezt az értéket, utána pedig erre hivatkozik minden függvény.).
+
+## Példa programok
+
+A hivatalos ppt-kben található pár példa program, amelyeken keresztül láthatjuk az imént tárgyaltakat kódban is.
+
+
+
+## Input kezelése
+
+Az operációs rendszernél a koordináta-rendszer origója a bal felső sarokban található, az $y$ tengely fejjel lefelé van! A `glViewport` viszont a bal alsó sarkot tekinti origónak, tehát valahogy így néz ki a dolog:
+
+{width=100%}
+
+Tehát ha a normalizált eszközkoordinátákat szeretnénk megmondani az ablak koordinátái alapján akkor:
+
+$$
+\begin{align*}
+x_{\text{ndc}} &= \left(\frac{x − x_{\text{offset}}}{\text{viewWidth}}\right) \times 2 − 1 \\[2.75ex]
+y_{\text{ndc}} &= \left(\frac{y_{\text{OpenGL}} − y_{\text{offset}}}{\text{viewHeight}}\right) \times 2 - 1
+\end{align*}
+$$
+
+ahol $y_{\text{OpenGL}}$ már az OpenGL szerint értelmezett koordináta! Azaz ha az ablakunk például $1000 \times 1000$ és az `onMouse` eseménykezelő szerint az egér $y$ koordinátája $267$, akkor $y_{\text{OpenGL}} = 1000 - 267 - 1$.
+
+## Adatok feldolgozása
+
+```cpp
+glEnableVertexAttribArray(0); // engedélyezi az írást ezekbe a regiszterekbe
+
+// beállítja a regiszter tulajdonságait
+glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+// Paraméterek: id, hány darab számot tárol, milyen típusú, isFixedPoint,
+// stride, offset
+
+// adatok feltöltése
+glBufferData(GL_ARRAY_BUFFER, size_in_bytes, &startOfArray[0], GL_STATIC_DRAW);
+// a mód lehet dinamikus is attól függően állítjuk, hogy gyakran cserélődik-e
+// az adat
+```
+
+Az adatainkat uniform változókon keresztül is a GPU-hoz tudjuk juttatni. Ezek olyan változók, amik a CPU-ból (értsd: a C++ kódunkból) állíthatók a shader programban. Nem a pontok adatai közé tartoznak (pl. [később](5.md/#összegzés) az MVP mátrix)
+
+Mi a megvalósításnál dupla bufferelést használtunk (a háttér buffert rajzoljuk, a előteret mutatjuk a usernek és ezt a kettőt cserélgetjük). Ezt a `glutSwapBuffers();` függvényhívással értük el.
+
+??? example Konvex burok
+ Ezen a programon lett bemutatva az OpenGL használata
+ {width=100%}
+ (ez nem az optimális algoritmus, de egészen használható)
+
+---
+
+# Kvíz
+
+!!! question 1\. Hány háromszöget próbál kirajzoltatni az alábbi programsor?
+ `glDrawArrays(GL_TRIANGLE_FAN, 5, 7);`
+
+??? tip Megoldás
+ Öt darabot (Első három pont alkot egy háromszöget, utána minden maradék pont egy újabb háromszöget eredményez.).
+
+ `glDrawArrays(MODE, start, count)` $\Rightarrow$ az 5-ös rész csak azt jelenti, hogy az 5. től kezdve szeretnénk kirajzolni 7 pontnyit.
+
+ A GL_TRIANGLE_FAN az első 2 pontból még nem tud háromszöget rajzolni, úgyhogy csak a 3.-tól kezdve, viszont akkor minden új ponttal rajzol egy darab háromszöget
+
+ Vagyis 7-2 = 5 darabot tud rajzolni
+
+ [*(Másik számokkal szemléltető kép)*](https://i.sstatic.net/G0JGo.png)
+
+---
+
+!!! question 2\. Az `onMouse` eseménykezelő egy eseményt kapott, amelyben az átadott koordináták $(916, 54)$ volt. Mi ennek a pontnak a normalizált eszközkoordináta-rendszerbeli $y$ koordinátája, ha az alkalmazásablak felbontása $1000 \times 1000$ az utolsó nézeti beállítás pedig a `glViewport(100, 200, 800, 700)` volt.
+ Kis segítség: `glViewport(x, y, width, height)`, és a bal alsó sarokból veszi az offsetet, az egér viszont bal felülről számol.
+
+??? tip Megoldás
+ 1\. Az egér koordinátáinak átalakítása OpenGL ablakkordinátákká
+
+ Az ablak felbontása $1000 \times 1000$, ahol az egér $y$ koordinátája $54$ (az ablak felső sarkából számítva).
+
+ OpenGL-ben az $y$ koordináta az ablak alsó sarkából indul, így az átváltás:
+
+ $$
+ y_{\text{OpenGL}} = 1000 - 54 - 1 = 945
+ $$
+
+ 2\. Normalizált koordináták számítása
+
+ A fenti képletbe helyettesítve:
+
+ $$
+ y_{\text{ndc}} = \left(\frac{945 - 200}{700}\right) \times 2 - 1 \approx 1.1286
+ $$
+
+---
+
+!!! question 3\. Egészítsük ki egész számokkal az alábbi programot úgy, hogy a 10 elemű `vtxData` tömb teljes egészébe a VBO-ba másolódjon.
+ A `pos` adattag a csúcspont árnyaló 0. regiszterébe, a `norm` adattag az 1. regiszterébe, a `tex` adattag a 2. regiszterébe.
+ {width=100%}
+
+??? tip Magyarázat
+ Az elején a struktúrát megnézzük, akkor látjuk, hogy:
+ 1 db `vec3` az 3 float-ból
+ 1 db `VertexData` az 3 `vec3`-ból áll
+
+ A $360$ azért annyi, mert byte-okban kell megadni és egy float az 4 byte, vagyis $4 \cdot 3 \cdot 3 \cdot 10$ byte lesz feltöltve.
+
+ A $3$ azért annyi, mert egy `vec3` valójában 3 floatból áll, a $36$ az a `VertexData` mérete, az offset pedig szintén byte-ban az adat pozíciójának offset-je
+
+---
+
+!!! question 4\. Mik igazak a `gl_Position` regiszterre?
+ Ha 3D euklideszi geometriában dolgozik a vertex shader, akkor ide a Descartes koordinátákat kell írni kiegészítve a $w=1$-gyel
+
+ Az ebbe pakolt pont koordinátáit a GPU a 3D projektív geometria szabályai szerint értelmezi, azzal a megkötéssel, hogy a nemnegatív $w$ koordinátájú pontokat tartja meg csak a vágás.
+
+??? tip Megoldás
+ Első állítás: magyarázat picit korábban volt, de a lényeg annyi, hogy perspektív térábrázolásra van kitalálva a GPU, ezért érdemes úgy használni $\implies$ `gl_Position = (vp.x, vp.y, vp.z, 1)`)
+
+ Második állítás: ezt csak későbbi előadáson részleteztük, de érdemes megjegyezni, hogy ami nem látszik az le lesz vágva.
+
+---
+
+!!! question 5\. Az alábbiak közül melyik OpenGL programokkal befolyásolhatjuk a pixel shader program működését?
+
+??? tip Megoldás
+ A `glUniform` - ez volt az egyetlen felsorolva, amire igaz volt, a többi az vagy független pl. viewport vagy már fragment shading.
+
+---
+
+!!! question 6\. Válasszuk ki az igaz állításokat. Feltételezzük, hogy a GPU háromszögeket dolgoz fel és a `glDrawArrays(GL_TRIANGLES, 0, 30)` OpenGL hívás hatására.
+ - Lehet olyan csúcspontárnyalót írni, amely esetén a GPU nem rajzol ki semmit a vbo tartalmától függetlenül
+ - A GPU csúcspont árnyaló programjában ki tudjuk számítani egy háromszög súlypontját.
+ - A csúcspontárnyaló dönthet arról, hogy a pontokat a háromszög csúcspontjaiként vagy háromszög legyezőként (`GL_TRIANGLE_FAN`) értelmezze.
+ - Ha a háromszög súlypontját a pixel árnyalóban számoljuk ki, akkor azt elég egyetlen pixelre, és az eredményt át lehet adni a többi pixel árnyalójának.
+ - A vágás során a primitív típusa (`GL_TRIANGLES`) lényegtelen.
+ - A GPU pixel árnyaló programja eldönti, hogy melyik pixelt színezze ki a kért színre.
+
+??? tip Megoldás
+ - [x] Lehet olyan csúcspontárnyalót írni, amely esetén a GPU nem rajzol ki semmit a vbo tartalmától függetlenül
+ - Magyarázat: Például: `void main() { gl_Position = vec4(0, 0, 0, 0); }`
+ - [ ] A GPU csúcspont árnyaló programjában ki tudjuk számítani egy háromszög súlypontját.
+ - Magyarázat: Nem tudjuk, egyszerre mindig csak egy csúcsponttal foglalkozunk egy számítási egységen.
+ - [ ] A csúcspontárnyaló dönthet arról, hogy a pontokat a háromszög csúcspontjaiként vagy háromszög legyezőként (`GL_TRIANGLE_FAN`) értelmezze.
+ - Magyarázat: Nem, ezt mi állítjuk be. Az OpenGL állapotgép
+ - [ ] Ha a háromszög súlypontját a pixel árnyalóban számoljuk ki, akkor azt elég egyetlen pixelre, és az eredményt át lehet adni a többi pixel árnyalójának.
+ - Magyarázat: Nem így működik...
+ - [ ] A vágás során a primitív típusa (`GL_TRIANGLES`) lényegtelen.
+ - Magyarázat: Nem lényegtelen, mert ettől függ mit rajzolunk ki, és különböző alakzatokat különböző módon kell vágni
+ - [ ] A GPU pixel árnyaló programja eldönti, hogy melyik pixelt színezze ki a kért színre.
+ - Magyarázat: Az OpenGL egy állapotgép, nem "dönt" semmiről.
+
+---
+
+!!! question 7\. Válassza ki a helyes állításokat az OpenGL körrajzoló képességével kapcsolatban.
+ - Az OpenGL nem tud kört rajzolni, mert a művelet felesleges, hiszen a kör közelíthető szabályos sokszöggel.
+ - Az OpenGL nem tud kört rajzolni, mert a GPU fejlesztők nem ismerték a kör egyenletét.
+ - Az OpenGL nem tud kört rajzolni, mert projektív geometriában nincs távolság, ezért nincs kör sem, helyette keletek lehetnek, azok viszont túl bonyolultak lennének a vágás és raszterizáció hw. implementációjához.
+ - Az OpenGL nem tud kört rajzolni, hogy kitoljon a programozókkal.
+ - Az OpenGL-nek a kör középpontját és sugarát kell átadni, hogy ki tudja rajzolni.
+
+??? tip Megoldás
+ - [x] Az OpenGL nem tud kört rajzolni, mert a művelet felesleges, hiszen a kör közelíthető szabályos sokszöggel.
+ - Magyarázat: Lásd [fentebb](#funkcionális-modell)
+ - [ ] Az OpenGL nem tud kört rajzolni, mert a GPU fejlesztők nem ismerték a kör egyenletét.
+ - Magyarázat: Szerintem a $8$ általánost elvégeszték azért a GPU fejlesztők.
+ - [x] Az OpenGL nem tud kört rajzolni, mert projektív geometriában nincs távolság, ezért nincs kör sem, helyette kúpszeletek lehetnek, azok viszont túl bonyolultak lennének a vágás és raszterizáció hw. implementációjához.
+ - Magyarázat: Projektív geometria nem egy [metrikus tér](https://hu.wikipedia.org/wiki/Metrikus_tér), mivel nincsen távolság definiálva.
+ - [ ] Az OpenGL nem tud kört rajzolni, hogy kitoljon a programozókkal.
+ - Magyarázat: Néha olyan érzés mintha igaz lenne...
+ - [ ] Az OpenGL-nek a kör középpontját és sugarát kell átadni, hogy ki tudja rajzolni.
+ - Magyarázat: Eleve nem tud kört rajzolni, tök mindegy, hogy mit adunk meg neki. Legfeljebb háromszögekkel közelíti.
+
+---
+
+!!! question 8\. Jelöljük be az alábbi programra vonatkozó igaz állításokat:
+ !!! quote ""
+ A 2024/2025/II. félévet követően feltehetően már nem kérdez rá erre, mert azóta más a `framework.h`
+
+ ```cpp
+ #include
+ #include
+ #include
+
+ void onDisplay(), onInitialization();
+
+ int main(int argc, char * argv[]) {
+ glutInit(&argc, argv);
+ glutInitContextVersion(3, 3);
+
+ glutInitWindowSize(600, 600);
+ glutInitWindowPosition(100, 100);
+ glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
+ glutCreateWindow(“Hi Graphics");
+
+ glewExperimental = true;
+ glewInit();
+ glViewport(0, 0, 600, 600);
+
+ onInitialization();
+ glutDisplayFunc(onDisplay);
+ glutMainLoop();
+
+ return 1;
+ }
+ ```
+
+??? tip Megoldás
+ - [x] Csak Microsoft Windows operációs rendszer alatt fordul le. (Hiszen `#include `)
+ - [x] A rajzolás célterülete a teljes alkalmazó ablak. (Hiszen a viewportot teljesen kitöltjük, nincs offset)
+ - [x] Egy pixelt 64 biten fog a hardver tárolni a rasztertárban. (Hiszen `glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);` emiatt - 2 buffer, 4 channel, 8 bit / szín $\Rightarrow 2 \cdot 4 \cdot 8 = 64$)*
+ - [x] Egyetlen sor törlésével a program Unix alatt is fordíthatóvá válik. (A kérdéses sor a `#include `)
+ - [ ] Ha Visual Studio-t használunk, akkor semmit sem kell installálni és a Web-ről letölteni, hogy leforduljon.
+ - [ ] A nézeti téglalap $100 \times 100$ pixelből áll.
+ - [ ] A `glutCreateWindow` után hívhatunk OpenGL függvényeket. (nem, csak akkor hívhatóak, ha inicializáltuk az OpenGL-t, ami az `onInitialization`-ban történik a framework-ben)
+ - [ ] Hibás, hogy az `opengl.h` nincs beincludeolva. (nem hibás, mert ezért van nekünk a glew könyvtár - ez segít eldönteni, hogy az OpenGL melyik verzióját vagyunk képesek használni)
+ - [ ] Ez OpenGL 3.0-ás verzióra készül fel. (nem, a glew eldönti)
+ - [ ] Ez OpenGL 1.0-ás verzióra készül fel. (nem, a glew eldönti)
+
+---
+
+!!! question 9\. Az alábbi program szándéka szerint egy zöld háromszöget rajzolna ki $\varphi$ radiánnal elforgatva, de nem működik. Mely sorokban van hiba?
+ !!! quote ""
+ A 2024/2025/II. félévet követően feltehetően már nem kérdez rá erre, mert azóta más a `framework.h`
+
+ ```cpp
+ void onDisplay( ) {
+ glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT);
+
+ int location = glGetUniformLocation(shaderProgram, "color");
+
+ glUniform3f(location, vec3(0.0f, 1.0f, 0.0f));
+
+ float MVPtransf[4][4] = {
+ cos(phi), sin(phi), 0, 0,
+ -sin(phi), cos(phi), 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1
+ };
+
+ location = glGetUniformLocation(shaderProgram, "MVP");
+ glUniformMatrix4fv(location, 1, GL_FALSE, &MVPtransf[0][0]);
+
+ glBindVertexArray(vao);
+ glDrawArrays(GL_TRIANGLES, 1, 3 );
+ glutSwapBuffers( );
+ }
+ ```
+
+??? tip Megoldás
+ - `glUniform3f(location, vec3(0.0f, 1.0f, 0.0f));`
+ - Hiba: $3$ `float` változót vár paraméternek
+ - `glUniformMatrix4fv(location, 1, GL_FALSE, &MVPtransf[0][0]);`
+ - Hiba: A mátrix a kódban sorfolytonos formában van megadva, de az OpenGL alapértelmezetten oszlopfolytonos mátrixokat vár. Ahhoz, hogy a mátrixunk helyesen töltődjön fel, a transzponálást jelző paraméternek `GL_TRUE`-nak kellene lennie.
+ - `glDrawArrays(GL_TRIANGLES, 1, 3 );`
+ - Hiba: Ez a hívás $3$ csúcspontot dolgoz fel az 1-es indextől kezdve, ami egyetlen háromszöget (az {1, 2, 3} csúcsokból) rajzol ki. Ez nem feltétlenül hiba, de ha a VBO-ban lévő első háromszöget ({0, 1, 2}) szeretnénk kirajzolni, a helyes hívás `glDrawArrays(GL_TRIANGLES, 0, 3)` lenne.
+
+---
+
+!!! question 10\. Mely könyvtárak szükségesek feltétlenül, azaz nem csupán opcionálisak, az GPU OpenGL könyvtáron keresztüli programozásához?
+
+??? tip Megoldás
+ OpenGL (nincs további helyes opció)
+
+---
+
+!!! question 11\. Hány csúcspontot fog tartalmazni az alábbi VBO?
+ ```cpp
+ unsigned int vbo;
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ double vertices[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(0); // AttribArray 0
+ glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
+ ```
+
+??? tip Megoldás
+ $16$, mert nagyon trükkösen `double` arraybe lettek pakolva a pontok, de `float`-ként lesznek feltöltve. Mivel a `double` kétszer annyi helyet használ fel, mint a `float`, ezért 16 float-nyi helyet fognak elfoglalni.
diff --git a/docs/notes/sem4/computer_graphics/lectures/3.md b/docs/notes/sem4/computer_graphics/lectures/3.md
new file mode 100644
index 0000000..7689551
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/3.md
@@ -0,0 +1,483 @@
+# Pontok és klasszikus görbék
+
+??? example Érdeklődőknek
+ Akiket mélyebben érdekel a téma, azoknak a további érdekes videót ajánljuk, az első 21 perce még néhol fedi is a tananyagot: [The Continuity of Splines - Freya Holmér](https://youtu.be/jvPPXbo87ds)
+
+## Koordináták
+
+A motivációnk továbbra is az, hogy próbáljunk absztrakt matematikai fogalmakat számokkal kifejezni, hogy a GPU is megértse. Egy GPU nem tudja mi az a "pont", de ha definiálunk egy koordináta-rendszert, akkor már számokkal ki tudjuk fejezni, hogy mi az a "pont", így pedig már tudjuk programozni a GPU-t.
+
+Általában egy koordináta-rendszer egy geometriai referencia rendszert jelent, amelyben mérési utasításokat adunk (például: lépj kettő strigulát balra az $x$-tengelyen, és hármat felfele az $y$-tengelyen), és ezekből következtethetők le a pontok. Descartes koordináták esetén két merőleges egyenes a referencia rendszer, de ezt a rendszert megváltoztatva kaphatunk egy új koordináta-rendszert. Polárkoordináták esetén például a referencia rendszerünk egy félegyenes, és a mérési utasítások azok, hogy melyik irányba induljunk el ($\phi$) és hogy mennyit sétáljunk a félegyenesen ($r$).
+
+### Baricentrikus koordináták
+
+Baricentrikus koordináták esetén a geometriai referencia rendszer néhány pont, az utasítás pedig az, hogy mindegyik $r_i$ ponthoz rendelünk egy $m_i$ súlyt. Így a rendszer $r$ súlypontja meghatároz egy pontot. Ekkor azt mondjuk, hogy $r$ az $r_1, r_2, ..., r_n$ pontok **kombinációja** (nemnegatív súlyok esetén **konvex kombinációja**):
+
+$$
+r = \frac{\sum_i m_i r_i}{\sum_i m_i} = \sum_i \alpha_i r_i
+$$
+
+ahol konvex kombináció esetén $r$ az a $r_i$ pontok konvex burkán belül van (ahol a konvex burok azon minimális konvex halmaz, amely az összes pontot tartalmazza).
+
+Például egy egyenes az két pont kombinációja, egy sík pedig három pont kombinációja. Konvex kombinációkat használva két pont egy szakaszt határoz meg, három pedig egy háromszöget.
+
+Itt a súlypontot fizikai értelemben is súlypontnak kell tekinteni, $r$ pontban a forgatónyomaték zérus:
+
+$$
+\sum_i (r_i - r) \times m_i g = 0
+$$
+
+azaz ha ebben a pontban "megtámasztjuk" a rendszert, akkor nyugalomban lesz.
+
+Mire is jó ez nekünk? Arra, hogy görbéket ábrázoljunk:
+
+- Az explicit egyenlet $y = mx+b$ nem jó nekünk, hiszen csak egyeneseket lehet vele rajzolni, kanyargós görbéket nem (ennek az az oka, hogy $f(x) = mx+b$ esetén $f$ egy _injektív_ függvény, azaz egy $x$-hez mindig egy darab $y$ tartozik).
+- Az implicit egyenlet $f(x,y) = 0$ már ad lehetőségeket, de még picit komplikált megkonstruálni (azt fogjuk megnézni, hogy hogyan lehet egyszerűbbé tenni).
+
+## Görbék
+
+A legkézenfekvőbb az lenne, ha függvényeket használhatnánk a görbék leírására, de függvényekkel nem tudunk olyan görbéket megadni, ahol egy $x$ értékhez több $y$ is tartozik. Viszont az az ötlet, hogy a pontok koordinátáinak a viszonyát valamilyen egyenletbe foglaljuk, az előnyös lesz, így kapjuk meg a görbék _implicit_ egyenleteit.
+
+Például egy $p$ pontra illeszkedő, $\underline{n}$ normálvektorú egyenes implicit egyenletét le lehet vezetni abból, hogy mi azon $r$ pontokat keressük, amik $p$-t egy $\underline{n}$ vektorra merőleges vektorral eltolva kaphatóak, azaz $(r-p)$ vektor legyen merőleges $\underline{n}$-re, más szóval $\underline{n} \cdot (r-p) = 0$. Koordinátákra bontva, és átrendezve megkapjuk, hogy a korábbi egyenletünk $ax + by + c = 0$ alakra hozható.
+
+Tehát minden egyeneshez tartozik egy lineáris egyenlet (lineáris, mivel $x$ és $y$ első hatványon vannak), de vajon nemlineáris egyenlet is meghatározhat egyenest? A válasz az, hogy igen, például $(ax + by + c)^2 = 0$ is egy egyenes egyenlete, hiszen a gyökök nem változtak (nem került be új pont).
+
+Ha kicsit közelebbről megtekintjük az $\underline{n} \cdot (r-p)$ kifejezést, akkor észrevehetjük, hogy ez igazából $r$ pont távolsága a keresett egyenestől. Amikor ezt a távolságot $0$-nak vesszük, akkor azt mondjuk, hogy azokat a pontokat keressük, amik rajta vannak az egyenesen, azaz magának az egyenesnek a pontjait. Viszont ha az előjelét tekintjük, akkor például meg tudjuk mondani egy adott $r'$ pont az egyenes melyik oldalán van (melyik félsíkban helyezkedik el a pont).
+
+### Kvadratikus görbék
+
+Példák: $r(x,y)$ azon pontok, amik kielégítik az alábbi egyenleteket
+
+- Kör: $(r - c)^2 - R^2 = 0$ ($c$-től $R$ távolságra lévő pontok halmaza)
+
+- Ellipszis: $|r - f_1| + |r - f_2| = C$ (azon $r$ pontok halmaza, amelyeknek $f_1$ és $f_2$ fókuszpontoktól mért távolság összege konstans $C$)
+
+- Hiperbola: $|r - f_1| - |r - f_2| = C$ (azon $r$ pontok, amelyek a $f_1$ és $f_2$ fókuszpontoktól mért távolság különbsége állandó $C$)
+
+- Parabola: $|r - f| = n \cdot (r - p)$ (Azon $r$ pontok halmaza, amelyek az $f$ fókuszponttól mért távolsága megegyezik az $\underline{n}$ normálvektorú és $p$ helyvektorú egyenestől mért távolsággal)
+
+Sok abszolút értéket használtunk a definíciókban, de négyzetre emeléssel ezeket el tudnánk tüntetni.
+
+#### Megadásuk
+
+- Implicit alakban:
+$f(x,y) = a_{11} x^2 + a_{22} y^2 + 2a_{12} xy + 2a_{13} xy + 2a_{23}y + a_{33} = 0$
+
+- Mátrix alakban:
+$\displaystyle [x,y,1] \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}$
+
+Ezekkel már egész komplex görbéket meg lehet adni. Általában mátrix alakban szoktuk megadni az együtthatókat, ezt kell implementálni programokban is.
+
+### Paraméteres egyenletek
+
+Nem csak kvadratikus görbékkel, de parametrikus egyenletekkel ($r(t)$-t használva) is le lehet írni görbéket, például:
+
+{width=100%}
+
+Ez mozgásként fogalmazza meg a görbét, nem pedig feltétel rendszerként, mint az implicit egyenletek esetében. Általánosságban minden dimenzióhoz kell egy mozgás függvény, komponensenként egy.
+
+### Szabadformájú görbék
+
+Ezekhez a görbékhez nem konkrét egyenleteket adunk meg, hanem vezérlő/kontrollpontokat, és azok határozzák meg a görbéket. Az a motivációnk, hogy ezzel a technikával sokkal komplexebb, élethűbb, természetesebb görbéket lehet létrehozni, mint például kvadratikus görbéket használva.
+
+A létrejövő görbéhez fog tartozni egy parametrikus függvény, és ennek a meg kell határozni az alakját (pl. polinom, exponenciális, stb...), és a gyakorlatban a mérnökök általában polinom függvényeket használnak. Ezekkel (Taylor-sorok révén) bármilyen másik függvény tetszőleges közelíthető. Nekünk a feladatunk ennek a polinom függvénynek az együtthatóinak meghatározása a kontrollpontok alapján.
+
+Az általános alakja ezeknek a görbéknek a következő:
+
+$$
+x(t) = \sum_i a_i \cdot t^i \qquad y(t) = \sum_i b_i \cdot t^i \qquad z(t) = \dots
+$$
+
+A továbbiakban tárgyalt görbék két főbb csoportba esnek: _interpolációk_ és _approximációk_. Az interpolációs görbék azok minden kontrollpontjukon át is mennek, míg az approximációs görbék általában csak a kezdő és végpontokon mennek át, a többi pontot csak "közelítik".
+
+Elvárjuk a görbétől, hogy:
+
+- természetes legyen, azaz $C^2$ folytonos (maga a görbe, és az első két deriváltja is folytonos),
+- szép legyen (kis görbületváltozás, indokolatlan hullámzás nélkül),
+- független legyen a koordináta-rendszertől (ha változik a koordináta-rendszer, akkor a görbe maga ne változzon, legfeljebb más számokkal kell majd leírni),
+ - Ezt a súlypont analógiával fogjuk biztosítani.
+- lokális vezérelhetőség teljesüljön rajta, azaz egy kontrollpont változtatása csak a pont szűk környezetében változtassa meg a görbét.
+
+#### Lagrange interpoláció
+
+A vezérlőpontokhoz rendelünk csomóértékeket, amik azt fogják jelképezni, hogy melyik "időpillanatban" kell "meglátogatni" az adott pontot. Ha van $n$ pontunk, akkor semmi sem akadályoz meg minket abban, h ezekre illesszünk egy $n + 1000$ fokszámú polinomot, viszont érezhető, hogy nekünk a minimális fokszámú polinom lenne előnyös. Ez az $n-1$-ed fokú lesz.
+
+Legyenek $r_1, r_2, ..., r_n$ kontrollpontok, amikhez a $t_1, t_2, ..., t_n$ csomóértékek ("súlyok") tartoznak, és egy $t$ futóváltozónk. Ekkor:
+
+$$
+r(t) = \sum_i L_i(t) \cdot r_i
+$$
+
+ahol
+
+$$
+L_i(t) = \frac{\prod_{j \neq i} (t-t_j)}{\prod_{j \neq i}(t_i - t_j)}
+$$
+
+Ha $t = t_k$, akkor $L_i(t_k) = 1$, ha $i = k$, különben $0$.
+
+Mivel minden súly hat minden pontra, ezért ha az egyik kontrollpontot odébb rakjuk, az a teljes görbére kihat, tehát _nincs_ lokális vezérelhetőség, vagyis nem alkalmazható bonyolult görbékre.
+
+#### Hermite interpoláció
+
+A Lagrange interpoláció általánosítása (ugyanazokkal a bajokkal küzd). A Hermite-interpolációnál nem csak a kontrollpontok helyzetét ($p_i$), hanem az azokon áthaladó görbe érintővektorát (sebességét, $v_i$) is megadjuk. Ez lehetővé teszi a görbe viselkedésének pontosabb irányítását a csomópontokban.
+
+Csak azt az esetet vettük, ahol két $p_1, p_2$ pont van és csak a $v_1, v_2$ sebességük van megadva.
+
+Mivel négy feltételt adunk meg ($p_1, v_1, p_2, v_2$), ezért ennyi ismeretlennel kell tudni számolni, tehát harmad fokú polinom lesz:
+
+$$
+r(t) = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i) + a_0
+$$
+
+Mivel a deriváltra is van feltétel, ezért ezt is használjuk:
+
+$$
+\dot{r}(t) = 3 a_3 (t - t_i)^2 + 2 a_2 (t - t_i) + a_1
+$$
+
+Az egyenletekbe helyettesítsük be a megkötéseket (legyen $t_i$ a 0. időpont):
+
+$$
+\begin{align*}
+&r(t_i) = p_i = a_0 \qquad \text{(hiszen itt }t = 0\text{)} \\
+&r(t_{i+1}) = p_{i+1} = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i)^1 + a_0 \\
+&\dot{r}(t_i) = v_{i} = a_1 \\
+&\dot{r}(t_{i+1}) = v_{i+1} = 3 a_3 (t - t_i)^2 + 2 a_2 (t - t_i) + a_1
+\end{align*}
+$$
+
+Az egyenletek megoldása:
+
+$$\begin{align*}
+&a_0 = p_i \\
+&a_1 = v_i \\[2.75ex]
+&a_2 = \frac{3(p_{i+1} - p_i)}{(t_{i+1} - t_i)^2} - \frac{(v_{i+1} + 2 v_i)}{t_{i+1} - t_i} \\[2.75ex]
+&a_3 = \frac{2 (p_i - p_{i+1})}{(t_{i+1} - t_i)^3} + \frac{v_{i+1} + v_i}{(t_{i+1} - t_i)^2}
+\end{align*}$$
+
+#### Beziér approximáció
+
+Az a cél, hogy a súlyfüggvény ne oszcilláljon, amit eddig például az váltott ki, hogy a súlyok _pozitív és negatív_ értéket is felvehettek. Most $B_i(t) \geq 0$ minden esetben. Nemnegatív súlyfüggvény esetén viszont _konvex kombinációról_ beszélünk, a konvex burok tulajdonság fennáll. Fontos kiemelni, hogy ez már csak egy _approximáció_.
+
+Egy másik kikötés, hogy a súlyok arányosan hassanak a függvényre, azaz
+
+$$
+\sum_i B_i(t) = 1
+$$
+
+teljesül.
+
+Ehhez a Bernstein-polinomokat használjuk súlyfüggvényként, amelyek a következő módon kaphatjuk meg:
+
+$$
+1^n = (t + (1-t))^n \overset{\text{*}}{=} \sum_{i = 0}^n \binom{n}{i} \cdot t^i (1-t)^{n-i}
+$$
+
+$*$: a [binomiális tétel](../appendix/math_appendix.md#binomiális-tétel) miatt
+
+Ezek alapján a $B_i(t)$ súlyfüggvény a következő lesz:
+
+$$
+B_i(t) = \binom{n}{i} \cdot t^i (1-t)^{n-i}
+$$
+
+ahol $t \in [0,1]$. Maga az $r(t)$ görbe pedig:
+
+$$
+r(t) = \sum_{i = 0}^{n} B_i(t) \cdot r_i
+$$
+
+Egy hátránya a módszernek az, hogy ha sok kontrollpontunk van, akkor az egyik változása elhanyagolható lesz. Ráadásul az éles változásokat is nehéz megjeleníteni, mert túl sok pont hat a görbére.
+
+### Splineok
+
+Az összes eddig tárgyalt módszerrel az az alapvető probléma, hogy közelítőleg annyiad fokú polinommal dolgozunk ahány kontrollpontunk van, és a súlyfüggvények lényegében végig nem nullák. Bonyolult görbékhez viszont sok kontrollpont kell, azaz a megnőtt polinom fokszám miatt vagy oszcillál a görbe, vagy annyira nehezen érhető el bármilyen változtatás, hogy használhatatlan lesz az eredmény.
+
+Ezeknek a megoldásoknak az orvoslására lettek kitalálva a *splineok*. Ilyenkor ugyanis nem növeljük a polinom fokszámát, hanem a kontrollpontokhoz több, alacsonyabb szintű polinomot rendelünk, és ezekből építjük fel a teljes görbét.
+
+#### Catmull-Rom spline
+
+Ez egy interpolációs technika. Minden két egymás követő pont közé egy Hermite interpolációs görbét illesztünk. Az egymás utáni szakaszokon a lezáró és kezdő pontok sebessége megegyezik, így nem fog ugrásszerűen változni a görbe.
+
+Ez a technika csak [$C^1$ folytonos](../appendix/math_appendix.md#folytonosság), de közelítőleg $C^2$ folytonossá tehetjük, ha a sebességeket megfelelő heurisztikával választjuk ki. Viszont ehhez kell egy függvény arra is, hogy a $v_i$-ket is meghatározzuk. Ehhez a pontnak a 2 szakaszát egyenes vonalú egyenletes mozgásnak fogjuk venni és annak az átlagsebességét fogjuk használni.
+
+$$
+v_i = \frac{1}{2}\left(\frac{r_{i+1} - r_i}{t_{i+1} - t_i} + \frac{r_i - r_{i-1}}{t_i - t_{i-1}}\right)
+$$
+
+Itt a $t$ csomóértékeket mi határozzuk meg (a számolós feladatban az $i.$ ponthoz $i$ értéke tartozott azt hiszem).
+
+Fontos megemlíteni, hogy egy gyakran használt paraméterezési mód a Catmull-Rom spline esetén a _uniform_ paraméterezés. Ez azt jelenti, hogy $\forall i \in \N$ esetén $t_{i+1} - t_i = 1$. Ebben az esetben a fenti képlet leegyszerűsödik:
+
+$$
+v_i = \frac{1}{2}(r_{i+1} - r_{i-1})
+$$
+
+
+
+---
+
+# Kvíz
+
+!!! question 1\. Egy Bézier görbe kontrollpontjai $(4,8), (7,9), (4,4)$
+ Mi a Bézier görbe $t=1.0$ paraméterre felvett pontjának x koordinátája?
+
+??? tip Megoldás
+ Van-e bármi trükk, hogy elkerüljük a számolást?
+
+ Igen van, hiszen $t = 1$ esetén a görbe utolsó pontjánál járunk, amit a görbe biztosan érint vagyis $r(1) = (4,4) \implies$ a válasz $4$
+
+ De mégis hogyan kéne kiszámolni?
+
+ $r(t) = \sum_{i = 0}^{n} B_i(t) \cdot r_i \qquad B_i(t) = \binom{n}{i} \cdot t^i (1-t)^{n-i} \\ \qquad$
+
+ 1\. $n = 0 \ : \ B_0(1) = \binom{2}{0} \cdot 1^0 (1-1)^{2-0} = \cfrac{2^0}{0! \cdot (2-0)!} \cdot 1 \cdot 0$
+
+ $\implies 0 \cdot (4, 8) = (0, 0)$
+
+ 2\. $n = 1 \ : \ B_1(1) = \binom{2}{1} \cdot 1^1 (1-1)^{2-1} = \cfrac{2^1}{1! \cdot (2-1)!} \cdot 1 \cdot 0$
+
+ $\implies 0 \cdot (7, 9) = (0, 0)$
+
+ 3\. $n = 2 \ : \ B_2(1) = \binom{2}{2} \cdot 1^2 (1-1)^{2-2} = \cfrac{2^2}{2! \cdot (2-2)!} \cdot 1 \cdot 1$
+
+ $\implies 1 \cdot (4, 4) = (4, 4)$
+
+ $(0,0) + (0,0) + (4,4) = (4,4) \implies$ a válasz még mindig $4$
+
+---
+
+!!! question 2\. Adottak egy Lagrange görbe kontrollpontjai és a csomóértékei. Mi a Lagrange görbe $t=0.9$ paraméterre felvett pontjának az $x$ koordinátája?
+ $$
+ \def\arraystretch{1.5}
+ \begin{array}{|c|c|}
+ \hline
+ (x, y) & t \\ \hline
+ (4,5) & 0 \\ \hline
+ (6,4) & 1 \\ \hline
+ (7,10) & 2 \\ \hline
+ \end{array}
+ $$
+
+??? tip Megoldás
+ A képlet:
+
+ $$
+ r(t) = \sum_i L_i(t) \cdot r_i \qquad L_i(t) = \frac{\prod_{j \neq i} (t-t_j)}{\prod_{j \neq i}(t_i - t_j)}
+ $$
+
+ Számolás: *(0-tól számozok mert úgy kényelmesebb)*
+
+ - $i = 0: L_0(0.9) = \frac{(0.9 - 1) \cdot (0.9 - 2)}{(0 - 1) \cdot (0 - 2)} = \frac{0.11}{2}$
+ - $i = 1: L_1(0.9) = \frac{(0.9 - 0) \cdot (0.9 - 2)}{(1 - 0) \cdot (1 - 2)} = \frac{-0.99}{-1}$
+ - $i = 2: L_2(0.9) = \frac{(0.9 - 0) \cdot (0.9 - 1)}{(2 - 0) \cdot (2 - 1)} = \frac{-0.09}{2}$
+
+ $\frac{0.11}{2} \cdot (4,5) + \frac{-0.99}{-1} \cdot(6,4) + \frac{-0.09}{2} \cdot (7, 10) = (0.22, 0.275) + (5.94, 3.96) + (-0.315, -0.45) = (5.845, 3.785) \implies 5.845$
+
+---
+
+!!! question 3\. Adottak egy Catmull-Rom görbe kontrollpontjai és a csomóértékei. Mi a Catmull-Rom görbe $t=1.5$ paraméterre felvett pontjának az $x$ koordinátája?
+
+ $$
+ \def\arraystretch{1.5}
+ \begin{array}{|c|c|}
+ \hline
+ (x, y) & t \\ \hline
+ (4,8) & 0 \\ \hline
+ (7,9) & 1 \\ \hline
+ (4,4) & 2 \\ \hline
+ (7,3) & 3 \\ \hline
+ \end{array}
+ $$
+
+??? tip Megoldás
+ 1. A $1 < t < 2$, vagyis ezek között a pontok között fogjuk vizsgálni
+
+ 2. $v_i$-k kiszámítása:
+ - $\displaystyle v_i = \frac{1}{2}\left(\frac{r_{i+1} - r_i}{t_{i+1} - t_i} + \frac{r_i - r_{i-1}}{t_i - t_{i-1}}\right) \\ \quad$
+ - $\displaystyle v_1 = \frac{1}{2}(\frac{(4,4) - (7,9)}{2-1} + \frac{(7,9) - (4,8)}{1-0}) =\frac{(0, -4)}{2} \\ \quad$
+ - $\displaystyle v_2 = \frac{1}{2}(\frac{(7,3) - (4,4)}{3-2} + \frac{(4,4) - (7,9)}{2-1}) = \frac{(0,-6)}{2}$
+
+ 3. Hermite paraméterei:
+ - $a_0 = p_i = (7,9)$
+ - $a_1 = v_i = (0, -2) \\$
+ - $\displaystyle a_2 = \frac{3(p_{i+1} - p_i)}{(t_{i+1} - t_i)^2} - \frac{(v_{i+1} + 2 v_i)}{t_{i+1} - t_i} = \\[2.75ex] = \frac{3((4,4) - (7,9))}{1} - \frac{(0,-3) + 2 \cdot (0, -2)}{1} = (-9,-8) \\[2.75ex]$
+ - $\displaystyle a_3 = \frac{2 (p_i - p_{i+1})}{(t_{i+1} - t_i)^3} + \frac{v_{i+1} + v_i}{(t_{i+1} - t_i)^2} = \\[2.75ex] = \frac{2 ((7,9) - (4, 4))}{1} + \frac{(0,-3) + (0,-2)}{1} = (6, 5)$
+
+ 4. Maga a függvény:
+ - $r(t) = a_3 (t - t_i)^3 + a_2 (t - t_i)^2 + a_1 (t - t_i)^1 + a_0$
+ - $r(1.5) = a_3 (1.5 - 1)^3 + a_2 (1.5 - 1)^2 + a_1 (1.5 - 1)^1 + a_0$
+ $r(1.5) = (6,5) \cdot 0.125 + (-9,-8) \cdot 0.25 + (0, -2) \cdot 0.5 + (7,9)$
+ $r(1.5) = (0.75, 0.625) + (-2.25,-2) + (0, -1) + (7,9)$
+ $r(1.5) = (5.5,6.625) \implies 5.5$ a válasz
+ :skull:
+
+---
+
+!!! question 4\. Jelöljük be az igaz állításokat!
+ - A Bezier görbe C2 folytonos.
+ - A $B_i(t)$ Bezier bázisfüggvényeknek nincs valós gyöke a 0-n és az 1-en kívül.
+ - A Bezier görbe interpolálja a kontrollpontjait.
+ - Ha n pontunk van, akkor a $B_i(t)$ Bezier bázisfüggvények n-ed fokú polinomok.
+ - A $B_i(t)$ Bezier bázisfüggvények a Bernstein polinomok.
+ - A Lagrange görbe a Bezier görbe speciális esete.
+ - A $B_i(t)$ Bezier bázisfüggvények nemnegatívak.
+ - A Bézier görbe a Lagrange görbe speciális esete.
+ - A $B_i(t)$ Bezier bázisfüggvények összege 1.
+
+??? tip Megoldás
+ - [x] A Bezier görbe C2 folytonos.
+ - [x] A $B_i(t)$ Bezier bázisfüggvényeknek nincs valós gyöke a 0-n és az 1-en kívül.
+ - [ ] A Bezier görbe interpolálja a kontrollpontjait.
+ - [ ] Ha n pontunk van, akkor a $B_i(t)$ Bezier bázisfüggvények n-ed fokú polinomok.
+ - [x] A $B_i(t)$ Bezier bázisfüggvények a Bernstein polinomok.
+ - [ ] A Lagrange görbe a Bezier görbe speciális esete.
+ - [x] A $B_i(t)$ Bezier bázisfüggvények nemnegatívak.
+ - [ ] A Bézier görbe a Lagrange görbe speciális esete.
+ - [x] A $B_i(t)$ Bezier bázisfüggvények összege 1.
+
+---
+
+!!! question 5\. Jelöljük be az igaz állításokat!
+ - Három nem egy egyenesbe eső pont kombinációjaként a három pont által definiált sík bármely pontja előállítható. *(igen, súlyozástól függ)*
+ - A súlypontra felírt forgatónyomaték mindig zérus, ha a pontjainkat bármilyen erővel is támadjuk.
+ - A súlypontot megfogva, a test nem mozdítható el. *(ezen a ponton stabilan áll, de ettől még mozgatható)*
+ - A súlyokat használva kombinációs faktorként, pontok konvex kombinációja mindig a súlypontot adja meg. *(ezt képzeld el egy háromszögre, ahol a súlyok konvex kombinációja valóban a súlypontot adja)*
+ - Ha $r_i$ pontba $m_i$ súlyt (i=1,2,...) helyezünk, akkor a rendszer súlypontja $\displaystyle \sum_i m_i \cdot r_i$
+
+??? tip Megoldás
+ - [x] Három nem egy egyenesbe eső pont kombinációjaként a három pont által definiált sík bármely pontja előállítható.
+ Magyarázat: Igen, súlyozástól függ
+ - [ ] A súlypontra felírt forgatónyomaték mindig zérus, ha a pontjainkat bármilyen erővel is támadjuk.
+ - [ ] A súlypontot megfogva, a test nem mozdítható el.
+ - Magyarázat: Ezen a ponton stabilan áll, de ettől még mozgatható
+ - [x] A súlyokat használva kombinációs faktorként, pontok konvex kombinációja mindig a súlypontot adja meg.
+ - Magyarázat: Ezt képzeld el egy háromszögre, ahol a súlyok konvex kombinációja valóban a súlypontot adja
+ - [ ] Ha $r_i$ pontba $m_i$ súlyt (i=1,2,...) helyezünk, akkor a rendszer súlypontja $\displaystyle\sum_i m_i \cdot r_i$
+ - Magyarázat: Ehhez még le kell osztani az összsúllyal $\displaystyle\sum_i m_i$-vel, hogy igaz legyen
+
+---
+
+!!! question 6\. Jelöljük be az igaz állításokat!
+ - A hiperbola megadható kvadratikus implicit függvénnyel.
+ - Ahogy az $x=\cos(t)$, $y=\sin(t)$ körmozgást definiál, az $x=\cosh(t)$,$ y=\sinh(t)$ egy hiperbolán való mozgást.
+ - Ha van egy olyan függvényünk, amely kifejezi egy pont és egy alakzat távolságát, akkor a függvény az alakzat implicit függvénye.
+ - Az egyenes y=m*x+b alakú explicit egyenletével a sík bármely egyenese definiálható.
+ - Egy körnek egyetlen parametrikus egyenlete van.
+ - A körnek van explicit és parametrikus egyenlete, de implicit egyenlete nincs.
+ - A tractrix a körmozgás és a haladó mozgás szuperpozíciója.
+ - A hegy tetejéről az aljáig leggyorsabban egyenespályán csúszhatunk le.
+ - Ahogy az $x=\cos(t)$, $y=\sin(t)$ állandó sebességű körmozgást definiál, az $x=\cosh(t)$, $y=\sinh(t)$ egy hiperbolán való állandó sebességű mozgást.
+ - Egy implicit függvény az alakzat és egy pont távolságát adja meg.
+ - Ha egy alakzatnak az implicit egyenlete nem $a*x+b*y+c=0$ alakú, akkor az alakzat nem lehet egyenes.
+
+??? tip Megoldás
+ - [x] A hiperbola megadható kvadratikus implicit függvénnyel.
+ - [x] Ahogy az $x=\cos(t)$, $y=\sin(t)$ körmozgást definiál, az $x=\cosh(t)$,$ y=\sinh(t)$ egy hiperbolán való mozgást.
+ - [x] Ha van egy olyan függvényünk, amely kifejezi egy pont és egy alakzat távolságát, akkor a függvény az alakzat implicit függvénye.
+ - [ ] Az egyenes y=m*x+b alakú explicit egyenletével a sík bármely egyenese definiálható.
+ - Magyarázat: Az y tengellyel párhuzamos egyenesek nem
+ - [ ] Egy körnek egyetlen parametrikus egyenlete van.
+ - Magyarázat: Ugyanazt a köregyenletet végtelen sok módon fel tudod írni
+ - [ ] A körnek van explicit és parametrikus egyenlete, de implicit egyenlete nincs.
+ - Magyarázat: Implicit van neki, explicit esetekre bontással van igazából
+ - [ ] A tractrix a körmozgás és a haladó mozgás szuperpozíciója.
+ - [ ] A hegy tetejéről az aljáig leggyorsabban egyenespályán csúszhatunk le.
+ - [ ] Ahogy az $x=\cos(t)$, $y=\sin(t)$ állandó sebességű körmozgást definiál, az $x=\cosh(t)$, $y=\sinh(t)$ egy hiperbolán való állandó sebességű mozgást.
+ - Magyarázat: Nem állandó sebességű
+ - [ ] Egy implicit függvény az alakzat és egy pont távolságát adja meg.
+ - [ ] Ha egy alakzatnak az implicit egyenlete nem $a*x+b*y+c=0$ alakú, akkor az alakzat nem lehet egyenes.
+ - Magyarázat: Nagyon egyszerű ellenpélda: $ax + by + c)^2 = 0$
+
+---
+
+!!! question 7\. Jelöljük be az igaz állításokat!
+ - Az $L_i(t)$ Lagrange bázisfüggvények összege 1.
+ - A Lagrange görbe C2 folytonos.
+ - Az $L_i(t)$ Lagrange bázisfüggvényeknek a gyökei a csomóértékek a $t_i$-t kivéve.
+ - A Lagrange interpoláció a Hermite interpoláció speciális esete.
+ - Az $L_i(t)$ Lagrange bázisfüggvényeknek nincs valós gyöke.
+ - Az $L_i(t)$ Lagrange bázisfüggvények nemnegatívak.
+ - Az Hermite interpoláció a Lagrange interpoláció speciális esete.
+ - Ha n pontunk van, akkor az $L_i(t)$ Lagrange bázisfüggvények n-ed fokú polinomok.
+ - A csomóértékek megválasztása nem befolyásolja a Lagrange görbe alakját.
+
+??? tip Megoldás
+ - [x] Az $L_i(t)$ Lagrange bázisfüggvények összege 1.
+ - Magyarázat: Az előadáson volt egy diagram a piros, kék ... színekkel és a lényeg, hogy minden pont hatása összesen 1
+ - [x] A Lagrange görbe C2 folytonos.
+ - [x] Az $L_i(t)$ Lagrange bázisfüggvényeknek a gyökei a csomóértékek a $t_i$-t kivéve.
+ - [x] A Lagrange interpoláció a Hermite interpoláció speciális esete.
+ - [ ] Az $L_i(t)$ Lagrange bázisfüggvényeknek nincs valós gyöke.
+ - Magyarázat: Attól még, hogy magas fokú, lehet neki
+ - [ ] Az $L_i(t)$ Lagrange bázisfüggvények nemnegatívak.
+ - Magyarázat: De van ilyen is, a számolós példában is
+ - [ ] Az Hermite interpoláció a Lagrange interpoláció speciális esete.
+ - Magyarázat: Pont fordítva, az általánosítása
+ - [ ] Ha n pontunk van, akkor az $L_i(t)$ Lagrange bázisfüggvények n-ed fokú polinomok.
+ - Magyarázat: $n-1$
+ - [ ] A csomóértékek megválasztása nem befolyásolja a Lagrange görbe alakját.
+ - Magyarázat: De, benne vannak a képletben
+
+---
+
+!!! question 8\. Jelöljük be az igaz állításokat!
+ - A Catmull-Rom görbe bázisfüggvényei nemnegatívak.
+ - A Catmull-Rom görbe a kontrollpontok konvex burkán belül fut.
+ - A Catmull-Rom görbe harmadfokú polinom a kontrollpontok számától függetlenül.
+ - A Catmull-Rom görbe egy pontjára minden kontrollpont hat.
+ - A Catmull-Rom görbe bázisfüggvények összege 1.
+ - A Catmull-Rom görbe C2 folytonos.
+ - A Catmull-Rom görbe Hermite interpolációs görbékből épül fel.
+ - A Catmull-Rom spline a Bezier görbe speciális esete.
+ - Ha n pontunk van, akkor a Catmull-Rom görbe $n-1$-ed fokú polinom.
+
+??? tip Megoldás
+ - [x] A Catmull-Rom görbe Hermite interpolációs görbékből épül fel.
+ - Magyarázat: Ez a definíciója.
+ - [x] A Catmull-Rom görbe bázisfüggvények összege 1.
+ - Magyarázat: Igen, mivel a Hermite az általánosítása a Lagrange-nak
+ - [x] A Catmull-Rom görbe harmadfokú polinom a kontrollpontok számától függetlenül.
+ - Magyarázat: Igen, mert Hermite-t használ
+ - [ ] A Catmull-Rom görbe bázisfüggvényei nemnegatívak.
+ - Magyarázat: De azok, mert Hermit-et használ
+ - [ ] A Catmull-Rom görbe C2 folytonos.
+ - Magyarázat: A szegmensek ezt így nem korlátozzák be
+ - [ ] A Catmull-Rom görbe a kontrollpontok konvex burkán belül fut.
+ - [ ] A Catmull-Rom görbe egy pontjára minden kontrollpont hat.
+ - Magyarázat: Pont úgy lett kialakítva, hogy ne
+ - [ ] A Catmull-Rom spline a Bezier görbe speciális esete.
+ - Magyarázat: Lásd fentebb.
+ - [ ] Ha n pontunk van, akkor a Catmull-Rom görbe $n-1$-ed fokú polinom.
+ - Magyarázat: Nem, mert szegmensekből áll
diff --git a/docs/notes/sem4/computer_graphics/lectures/4.md b/docs/notes/sem4/computer_graphics/lectures/4.md
new file mode 100644
index 0000000..1b136ef
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/4.md
@@ -0,0 +1,178 @@
+
+
+# Transzformációk
+
+A _transzformáció_ egy pontfüggvény, ponthoz pontot rendel (pl. nyújtás, forgatás, ...). Ez a definíció véges számú pont esetén tökéletesen megfelel, viszont ha már végtelen sok pontot tartalmazó primitíveket (egyeneseket, háromszögeket) akarnánk transzformálni, akkor problémákba ütköznénk. Ezeket a primitíveket képletekkel definiáljuk, és egyes transzformációk elrontják ezeket a képleteket.
+
+Vegyük példának a tengely menti nyújtás transzformációt. Ha egy körre alkalmazzuk ezt, akkor a létrejövő alakzat valamiféle ellipszis lenne, viszont egy ellipszist már nem lehet ugyanazzal a képlettel megadni mint egy kört, hiszen egy körhöz elég egy pont és egy sugár, viszont egy ellipszishez már nem. Így kezelhetetlenné válik az új alakzatunk.
+
+Mi olyan transzformációkat szeretnénk, amik nem rontják el így az alakzatainkat, azaz szakaszt szakaszba, és háromszöget háromszögbe képeznek. Minden más alakzatot úgyis ezekkel közelítünk, szóval ha ezek pontosak maradnak, akkor minden más is.
+
+Szerencsére a legtöbb hasznos transzformáció (eltolás, elforgatás, nyújtás, nyírás, tükrözés, stb...) azok ilyenek. Felvehetünk egy még szigorúbb megkötést: ha két egyenes párhuzamos volt a transzformáció előtt is és utána is, akkor a transzformációt _affin transzformációnak_ nevezzük.
+
+## Affin transzformációk
+
+Hasonlóan mint a görbék eseténél, a transzformációkat is jó lenne valahogy képletesen/számszerűleg kifejezni, hogy le tudjuk programozni őket. A görbékkel ellentétben viszont most könnyebb lesz mátrixokkal dolgozni, mert asszociatívak, vagyis:
+
+$$
+(((v \cdot M_1) \cdot M_2) ... \cdot M_n) = v \cdot (M_1 \cdot M_2 \cdot ... \cdot M_n)
+$$
+
+Az affin transzformációk fix pontja az origó (pl. forgatás középpontja), viszont nem mindegyiknek van (pl. eltolásnak nincs). Persze ez nem azt jelenti, hogy csak az origó körül lehet forgatni, hiszen ha van egy tetszőleges $p$ fix pontunk ami körül szeretnénk forgatni, akkor elég annyi, ha a forgatás transzformáció előtt egy olyan eltolást alkalmazunk, ami a $p$ fix pontunkat az origóba viszi. Ez után elvégezhetjük a forgatást, és végül visszacsináljuk az első eltolást.
+
+OpenGL-ben mátrixok feltöltése:
+
+```cpp
+// location (e.g. "MVP"), count, is transpose, the matrix (in a 1d array format)
+glUniformMatrix4fv(location, 1, GL_TRUE, &matrix[0])
+```
+
+Ha nem egy pontot/szakaszt/háromszöget szeretnénk kirajzolni vagy nem egyenestartó transzformációt akarunk használni, akkor elvégezhetjük a transzformációt, és a végeredményt visszaalakíthatjuk szakaszokra, háromszögekre.
+
+További példák: eltolás, forgatás, tükrözés, scaling, irányfüggő megnyújtás.
+Ellenpélda: inverzió (egyenesből kört, vagy körből egyenest csinál)
+
+### Gyakran használt mátrixok
+
+#### Forgatás (z tengely körül)
+
+$$
+\begin{bmatrix}
+ \cos(\varphi) & \sin(\varphi) & 0 & 0 \\
+ -\sin(\varphi) & \cos(\varphi) & 0 & 0 \\
+ 0 & 0 & 1 & 0 \\
+ 0 & 0 & 0 & 1
+\end{bmatrix}
+$$
+
+#### Eltolás
+
+$$
+\begin{bmatrix}
+ 1 & 0 & 0 & v_x \\
+ 0 & 1 & 0 & v_y \\
+ 0 & 0 & 1 & v_z \\
+ 0 & 0 & 0 & 1
+\end{bmatrix}
+$$
+
+#### Skálázás
+
+$$
+\begin{bmatrix}
+ s_x & 0 & 0 & 0 \\
+ 0 & s_y & 0 & 0 \\
+ 0 & 0 & s_z & 0 \\
+ 0 & 0 & 0 & 1
+\end{bmatrix}
+$$
+
+## Homogén lineáris transzformációk
+
+Az euklideszi geometriának vannak hiányosságai, például középpontos vetítésre alkalmatlan, ezért projektív geometriát fogunk használni, (möbius féle) homogén koordinátákkal.
+
+!!! info Emlékeztető
+ A projektív geometriát részletesen [ebben](1.md/#18-projektív-geometria) a fejezetben tárgyaltuk.
+
+Az affin transzformációk a homogén lineáris transzformációk speciális esete, hiszen ott meg volt kötve, hogy az utolsó sornak muszáj $[0,0,0,1]$-nek lennie. Általános esetben -- mivel projektív geometriát használunk -- nincs ez a megkötés.
+
+Itt is ugyan úgy mátrixokat használunk, amik egyeneseket egyenesekbe, kombinációkat kombinációkba, és konvex kombinációkat konvex kombinációkba képeznek le. Fontos kiemelni, hogy ez csak invertálható mátrixok esetén igaz: ha nem invertálható mátrixszal dolgozunk, akkor lehetnek elfajulások, mint például síkból egyenes, vagy egyenesből pont.
+
+
+
+Fontos megemlíteni az _átfordulási problémát_, melyhez [itt](https://youtu.be/wBZxuKloteA&t=2489) található részletesebb magyarázat.
+
+---
+
+# Kvíz
+
+!!! question 1\. Egy affin transzformáció a $(0,0)$ pontot a $(3,4)$ pontra, az $(1,0)$ pontot a $(4,3)$ pontra, $(0,1)$ pontot a $(2,4)$ pontra képezi le. Mi lesz a $(4,4)$ pont képének $x$ koordinátája?
+
+??? tip Megoldás
+ $(0, 0) \to (3, 4) \\ \qquad 0 \cdot a + 0 \cdot b + c = 3 \\ \qquad 0 \cdot d + 0 \cdot e + f = 4 \\ \qquad c = 3, f= 4$
+ $(1, 0) \to (4, 3) \\ \qquad 1 \cdot a + 0 \cdot b + 3 = 4 \\ \qquad 1 \cdot d + 0 \cdot e + 4 = 3 \\ \qquad a = 1, d = -1$
+ $(0, 1) \to (2, 4) \\ \qquad 0 \cdot 1 + 1 \cdot b + 3 = 2 \\ \qquad 0 \cdot (-1) + 1 \cdot e + 4 = 4 \\ \qquad b = -1, e= 0$
+
+ $(4, 4) \Rightarrow \\ \quad 4 \cdot 1 + 4 \cdot (-1) + 3 = ? \\ \quad 4 \cdot (-1) + 4 \cdot 0 + 4 = ? \\ \quad (3, 0) \Rightarrow 3$ a válasz
+
+---
+
+!!! question 2\. A 2D világba tett kamera középpontja $(168,968)$ a kameraablak szélessége $14$ magassága $7$. Mi lesz az $(221,16)$ világkoordináta-rendszerbeli pont megfelelőjének $x$ koordinátája normalizált eszközkoordináta-rendszerben?
+
+??? tip Megoldás
+ A kamera középpontja a normalizált eszközkoordináta-rendszerben: $(0, 0)$
+
+ Az innen relative $+(7, 3.5)$ világkoordináta lesz a $(0.5, 0.5)$ (ez az ablak szélességből látszik).
+
+ Vagyis a kapott pontunk pozíciója:
+
+ $$
+ \left(\frac{(221 - 168)}{14 / 2}, \frac{(16 - 968)}{7 / 2} \right) = \left(\frac{53}{7}, \frac{-952}{3.5} \right) = (7.5714, -272)
+ $$
+
+ (azért kell $/2$-vel számítani a képernyőszélességet, mert a normalizált az $[-1, 1]$ intervallumon van, vagyis a szélessége $2$ lenne)
+
+---
+
+!!! question 3\. Melyek az alábbiak közül affin transzformációk?
+ - Eltolás
+ - $x$ tengelyre vetítés
+ - Az $(1, 3)$ pont körüli forgatás
+ - Nyírás: $x'=x$; $y'=y+ax$
+ - Origóra tükrözés
+ - Helyben hagyás
+ - $x$ tengely mentén végrehajtott skálázás
+
+??? tip Megoldás
+ Mindegyik az, az inverzió lenne a kivétel, de az nem szerepelt.
+
+---
+
+!!! question 4\. Adott két egyenes implicit egyenletükkel:
+ $e: 4x+5y+2.5=0$
+ $f: 12x+15y+14=0$
+
+ Számítsuk ki a metszéspont harmadik homogén $w$ koordinátáját.
+
+??? tip Megoldás
+ Keresztszorzást használva találjuk meg a metszéspontot:
+
+ $$
+ \begin{align*}
+ p &= (4, 5, 2.5) \times (12,15,14) \\
+ p.x &= a.y \cdot b.w - a.w \cdot b.y = (5 \cdot 14) - (2.5 \cdot 15) = 32.5 \\
+ p.y &= a.w \cdot b.x - a.x \cdot b.w = (2.5 \cdot 12) - (4 \cdot 14) = -26 \\
+ p.w &= a.x \cdot b.y - a.y \cdot b.x = (4 \cdot 15) - (5 \cdot 12) = 0 \\
+ &\implies \text{A válasz } 0
+ \end{align*}
+ $$
+
+---
+
+!!! question 5\. Egy sík implicit egyenlete: $8.5x+7y+4.4z+2.1=0$.
+ A síkot a $(4,3,5)$ vektorral eltoltuk.
+ Mennyi a transzformált sík normálvektorában az $x$ és $y$ komponensek aránya, azaz $\cfrac{n.x}{n.y}$.
+
+??? tip Megoldás
+ Az eltolás nem változtat azon, hogy merre áll a sík (csak azon, hogy hol van) $\implies$ a válasz továbbra is $8.5 / 7 \approx 1.2143$
+
+---
+
+!!! question 6\. A síkgeometriában egy háromszög három csúcsának homogén koordinátái $(0,0,3)$,$(2,0,2)$ és $(2,4,2)$. Mekkora a háromszög területe?
+
+??? tip Megoldás
+ A pontokat normalizáljuk:
+
+ $$
+ (0,0,1), (1,0,1), (1,2,1)
+ $$
+
+ Ha mentális modelt alkotunk ezekről a pontokról, akkor [triviálisan megsejthetjük](https://cdn.discordapp.com/emojis/1394642603701571605.webp?size=240), hogy az alap $1$, a magasság pedig $2$.
+
+ A háromszög területe:
+
+ $$
+ T = \frac{a \cdot m_a}{2} = 1
+ $$
+
+ A válasz tehát $1$.
diff --git a/docs/notes/sem4/computer_graphics/lectures/5.md b/docs/notes/sem4/computer_graphics/lectures/5.md
new file mode 100644
index 0000000..80f060a
--- /dev/null
+++ b/docs/notes/sem4/computer_graphics/lectures/5.md
@@ -0,0 +1,977 @@
+# 2D képszintézis
+
+Feltételezzük, hogy a virtuális világunk a kétdimenziós Euklideszi sík. Hogyan tudjuk ezt a világot megjeleníteni a képernyőn?
+
+Vannak objektumjaink, amiknek tudjuk a helyét a virtuális világban. Szükségünk lesz egy kamerára, ami azt jelöli majd ki, hogy a virtuális világból mennyit látunk (hol vagyunk, merre nézünk, stb). A végső fénykép pixelekből áll, szóval minden pixelről el kell dönteni, hogy milyen színű legyen. Ha minden objektumhoz rendelünk egy színt, aztán pedig ez az objektum feltűnik egy adott pixelen, akkor tudjuk, hogy annak a pixelnek milyen színűnek kell lennie. (Ha több objektum is verseng egy adott pixelért, azaz van overlap, akkor explicit prioritást használunk, azaz konkrétan van egy szám minden objektumhoz, ami megmondja, hogy milyen sorrendben rajzoljuk ki őket)
+
+Hogyan tudunk kapcsolatot teremteni az objektumaink és a képernyő között? Két irányból közelíthetjük meg:
+
+- pixelvezértel (pixel $\rightarrow$ objektumok)
+- objektumvezérelt (objektumok $\rightarrow$ pixel)
+
+Az objektumvezérelt gyakran hatékonyabb, mint a pixelvezérelt, azt fogjuk preferálni.
+
+## Pixelvezérelt képszintézis
+
+Induljunk a pixelek felől. A képernyőn véges számú pixel van, tehát elég annyit csinálnunk, hogy minden egyes pixelben eldöntjük, hogy melyik objektum látszódik benne. Transzformáljuk a pixeleket világkoordináta-rendszerbe, és ezután pedig amelyik objektumra landolunk, az van abban a pixelben (figyelembe véve a prioritásukat).
+
+Ez a megközelítés az egyszerűbb, pixelenként egy pontot kell csak transzformálni, utána pedig az objektum prioritása szerint csökkenő sorrendben eldönteni, hogy egy adott primitív tartalmazza-e a transzformált pontunkat.
+
+A hátránya az, hogy nagyon lassú. [Később](8.md/#összegzés) majd látunk egy példát konkrét számokkal, de általánosságban ha nem csak 1-1 képet szeretnénk generálni, hanem másodpercenként sokat, akkor legtöbbször ez a megközelítés alkalmatlan.
+
+### Tartalmazás
+
+Az egyenleteink csak az alakzatok határán lévő pontokat adják meg, viszont nekünk legtöbbször kitöltött alakzatok is kellenek. Ehhez el kell tudni dönteni egy pontról, hogy egy alakzaton belül van-e, azaz tartalmazza-e.
+
+Implicit görbék (például gömbök) esetén adott az $f(x,y)$ implicit egyenletünk. Ha $f(x,y) = 0$ akkor a határpontokat kapjuk, viszont vizsgálhatjuk azt is, hogy nagyobb-e, vagy kisebb-e mint $0$ egy adott pontban az $f(x,y)$. Általánosságban:
+
+$$
+\boxed{
+\begin{align*}
+f(x,y) &\gt 0 \, \text{: kívül} \\
+f(x,y) &= 0 \, \text{: határon} \\
+f(x,y) &\lt 0 \, \text{: belül}
+\end{align*}
+}
+$$
+
+Parametrikus görbék esetén a függvényünk nem pontokat, hanem $t$ időpillanatokat vár, tehát ezt a trükköt nem egészen alkalmazhatjuk. Ekkor a következőt tehetjük: állítsunk a pontunkra egy olyan félegyenest, ami szeli a parametrikus görbénket. Ezután számoljuk meg, hogy az egyenes hányszor metszi az alakzatot, mielőtt a pontunkba érkezik. Ha páratlan sokszor, akkor a pont az alakzaton belül van, ha páros sokszor, akkor az alakzaton kívül van.
+
+??? example Magyarázat
+ Tekintsük az alábbi ábrát:
+
+ 
+
+ Ha a "végtelenből" elindulunk a félegyenesünkön a pontunk felé, akkor természetesen az objektumon kívül vagyunk (hiszen nem lehet végtelen nagy az objektum) és ekkor még egyszer sem metszettük az objektumot, tehát a metszési szám $0$. Amikor először metsszük, akkor mivel eddig kint voltunk, ezért belülre kerülünk, és a metszési szám is megnő egyel, azaz egy páros számról ($0$) egy páratlan szám ($1$) lett. Ha ezután elhagyjuk az objektumot, akkor mivel eddig bent voltunk, ezért most kívülre esünk, és a metszések száma is paritást vált. Ugyan ezzel a logikával haladva a pontunk felé amikor elérjük, el tudjuk dönteni a metszési szám alapján, hogy belül, vagy kívül vagyunk.
+
+#### Implementáció (tartalmazás)
+
+Később majd látunk részletesebb (és hasznosabb) példákat, de a teljesség kedvéért az alábbi minimális, tartalmazás vizsgálásra fókuszált kódrészletet is a jegyzetbe tettük.
+
+??? example Kódrészlet
+ ```cpp
+ struct Object { // base class
+ vec3 color;
+ virtual bool In(vec2 r) = 0; // containment test
+ };
+
+ struct Circle : Object {
+ vec2 center;
+ float R;
+ bool In(vec2 r) { return (dot(r-center, r-center) < R*R); }
+ };
+
+ struct HalfPlane : Object {
+ vec2 r0, n; // position vec, normal vec
+ bool In(vec2 r) { return (dot(r–r0, n) < 0); }
+ };
+
+ struct GeneralEllipse : Object {
+ vec2 f1, f2;
+ float C;
+ bool In(vec2 r) { return (length(r-f1) + length(r-f2) < C); }
+ };
+
+ struct Parabola : Object {
+ vec2 f, r0, n; // f=focus, (r0,n)=directrix line, n=unit vec
+ bool In(vec2 r) { return (fabs(dot(r-r0, n)) > length(r–f));}
+ };
+
+ class Scene { // virtual world
+ list