OBSAH WEBU
ČTĚTE!
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
temata:11-rasterizace:main [2016/05/26 12:21] xpavel27 [DDA - Digital Differential Analyser] |
temata:11-rasterizace:main [2016/05/27 11:41] (aktuální) xpavel27 [Bresenhamův algoritmus] |
||
---|---|---|---|
Řádek 36: | Řádek 36: | ||
* Používá ”floating-point aritmetiku”, pak se zaokrouhluje | * Používá ”floating-point aritmetiku”, pak se zaokrouhluje | ||
* Nízká efektivita, náročná implementace do HW | * Nízká efektivita, náročná implementace do HW | ||
+ | * V podstate **x** sa inkrementuje a **y** sa zväčšuje o smernicu | ||
+ | * Vzorec smernice je vyssie, je to podiel prirastku y a x | ||
|<m>x_{n + 1} = x_n + 1</m>| | |<m>x_{n + 1} = x_n + 1</m>| | ||
|<m>y_{n + 1} = y_n + k, k = (y_2 − y_1)/(x_2 − x_1)</m> ... směrnice| | |<m>y_{n + 1} = y_n + k, k = (y_2 − y_1)/(x_2 − x_1)</m> ... směrnice| | ||
- | </box> | ||
<code> | <code> | ||
- | LineBres(int x1, int y1, int x2, int y2) | + | LineDDA(int x1, int y1, int x2, int y2) |
{ | { | ||
- | int dx = x2-x1, dy = y2-y1; | + | double k = (y2-y1)/(x2-x1); |
- | int P = 2*dy – dx; | + | double y = y1; |
- | int P1 = 2*dy, P2 = P1 - 2*dx; | + | |
- | int y = y1; | + | |
for (int x = x1; x <= x2; x++) | for (int x = x1; x <= x2; x++) | ||
{ | { | ||
draw_pixel( x, y); | draw_pixel( x, y); | ||
- | if (P >= 0) | + | y += k; |
- | { P += P2; y++; } | + | |
- | else | + | |
- | P += P1; | + | |
} | } | ||
} | } | ||
</code> | </code> | ||
+ | </box> | ||
==== Error control DDA ==== | ==== Error control DDA ==== | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> | ||
* modifikace DDA | * modifikace DDA | ||
+ | * V podstate len používame premennú **E** kde ukladame smernicu | ||
+ | * Ak je hodnota **E** aspoň **0.5** a viac inkrementujeme **X** a odpočítame **jedničku** | ||
<code> | <code> | ||
Řádek 82: | Řádek 81: | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> | ||
- | * nejpoužívanější, velmi efektivní, snadná implementace do HW | + | Nejpoužívanější, velmi efektivní, snadná implementace do HW\\ |
- | * používá celočíselnou aritmetiku, sčítání, porovnání | + | Používá celočíselnou aritmetiku, sčítání, porovnání\\ |
- | * posun v ose Y podle znaménka **prediktoru** | + | Posun v ose Y podle znaménka **prediktoru**\\ \\ |
- | + | * Pokud <m>E_i + k \ge 0.5</m>, potom <m>E_{i + 1} = E_i + k - 1</m>\\ | |
- | Pokud <m>E_i + k \ge 0.5</m>, potom <m>E_{i + 1} = E_i + k</m>\\ | + | * Pokud <m>E_i + k < 0.5</m> potom <m>E_{i + 1} = E_i + k</m>\\ |
- | Pokud <m>E_i + k < 0.5</m> potom <m>E_{i + 1} = E_i + k - 1</m>\\ | + | |
Takze po vynásobení rovnic <m>2\Delta x</m>: | Takze po vynásobení rovnic <m>2\Delta x</m>: | ||
- | |<m>P_0 = 2\Delta y - \Delta x</m>| | + | * <m>P_0 = 2\Delta y - \Delta x</m> |
- | + | * <m>P_i < 0 \doubleright P_{i + 1} = P_i + 2\Delta y</m> | |
- | |<m>P_i < 0 \doubleright P_{i + 1} = P_i + 2\Delta y</m>| | + | * <m>P_i \ge 0 \doubleright P_{i + 1} = P_i + 2 \Delta y - 2 \Delta x</m> |
- | |<m>P_i \ge 0 \doubleright P_{i + 1} = P_i + 2 \Delta y - 2 \Delta x</m>| | + | V podstate: |
+ | * nepracujeme so smernicou ale len s prírastkami | ||
+ | * vytvoríme si tri predikáty | ||
+ | * Upravovaný predikát: <m>P_0 = 2\Delta y - \Delta x</m> | ||
+ | * Menší ako nula: <m>P_1 = 2\Delta y</m> | ||
+ | * Aspoň nula: <m>P_2 = P_1 - 2\Delta x</m> | ||
+ | * následne upravovaný predikát inkrementujeme o hodnotu P1 alebo P2 | ||
+ | * v prípade, že je P aspoň 0 inkrementujeme y | ||
<code> | <code> | ||
LineBres(int x1, int y1, int x2, int y2) | LineBres(int x1, int y1, int x2, int y2) | ||
{ | { | ||
- | int dx = x2-x1, dy = y2-y1; | + | int dx = x2-x1; |
+ | int dy = y2-y1; | ||
int P = 2*dy – dx; | int P = 2*dy – dx; | ||
int P1 = 2*dy, P2 = P1 - 2*dx; | int P1 = 2*dy, P2 = P1 - 2*dx; | ||
Řádek 113: | Řádek 119: | ||
</code> | </code> | ||
</box> | </box> | ||
- | |||
===== Kružnice ===== | ===== Kružnice ===== | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> | ||
Řádek 133: | Řádek 138: | ||
* Používá ”floating-point aritmetiku” | * Používá ”floating-point aritmetiku” | ||
* nízká efektivita, náročná implementace v HW | * nízká efektivita, náročná implementace v HW | ||
+ | * vykreslujeme ve smere hodinových ruciciek. | ||
* od bodu [0,R] po pixelech dokud není x=y | * od bodu [0,R] po pixelech dokud není x=y | ||
|<m>dx = 1, y = \sqrt(R^2-x^2)</m>| | |<m>dx = 1, y = \sqrt(R^2-x^2)</m>| | ||
- | </box> | ||
+ | {{ temata:11-rasterizace:obyckruh.png?500 }} | ||
+ | </box> | ||
==== Vykreslení kružnice jako N-úhelník ==== | ==== Vykreslení kružnice jako N-úhelník ==== | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> | ||
- | * varianta DDA pro kružnici-floating point, nízka efektivita, vysoká náročnost implementace v HW | ||
- | * rekurentní posun o konstaní přírůstek úhlu(sin a cos se počítají pouze jednou) | ||
- | |<m>x_{n + 1} = x_n \cos\alpha − y_n \sin\alpha</m>| | + | * **Info** |
+ | * varianta DDA pro kružnici-floating point | ||
+ | * aplikace rotacní transformace bodu. | ||
+ | * používá "floating-point aritmetiku". | ||
+ | * nízká efektivita, nárocná implementace do HW. | ||
+ | * rekurentní posun o konstaní přírůstek úhlu | ||
+ | * funkce sin a cos jsou vypocítány pouze jednou! | ||
+ | * souradnice X a Y se zaokrouhlují na nejbližší celé císlo. | ||
+ | * vypoctené souˇradnice spojujeme úseckami. | ||
- | |<m>y_{n + 1} = x_n \sin\alpha − y_n \cos\alpha</m>| | + | * **Vzorce** |
- | </box> | + | * <m>x_{n + 1} = x_n \cos\alpha − y_n \sin\alpha</m> |
+ | * <m>y_{n + 1} = x_n \sin\alpha − y_n \cos\alpha</m> | ||
+ | * **V podstate** | ||
+ | * Vypočítame cos jedného uhla <m>\cos (2\pi / N)</m> | ||
+ | * Vypočítame sin jedného uhla <m>\sin (2\pi / N)</m> | ||
+ | * Začneme na súradnici R,0 | ||
+ | * Pre každý uhol vypočítame nové x a y podľa vzorca | ||
+ | |||
+ | {{ temata:11-rasterizace:kruhuholnik.png?500 }} | ||
+ | </box> | ||
==== Midpoint algoritmus ==== | ==== Midpoint algoritmus ==== | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> | ||
- | * variace na Bresenhamův =>celočíselná aritmetika, vysoká efektivita, snadná implementace | + | * variace na Bresenhamův |
+ | * celočíselná aritmetika | ||
+ | * vysoká efektivita | ||
+ | * snadná implementace | ||
* po pixelu od [0,R] dokud <m>x = y</m> | * po pixelu od [0,R] dokud <m>x = y</m> | ||
+ | * startovací hodnota je <m>p_i = 1 − R</m> | ||
|<m>p_i = (x_i + 1)^2 + (y_i − 1/2)^2 − R^2</m>| | |<m>p_i = (x_i + 1)^2 + (y_i − 1/2)^2 − R^2</m>| | ||
- | |||
|<m>p_i < 0 \doubleright y_{i + 1} = y_i, p_{i+1} = p_i + 2x_i + 3</m>| | |<m>p_i < 0 \doubleright y_{i + 1} = y_i, p_{i+1} = p_i + 2x_i + 3</m>| | ||
- | |||
|<m>p_i \ge 0 \doubleright y_{i + 1} = y_i - 1, p_i + 1 = p_i + 2x_i − 2y_i + 5</m>| | |<m>p_i \ge 0 \doubleright y_{i + 1} = y_i - 1, p_i + 1 = p_i + 2x_i − 2y_i + 5</m>| | ||
- | * startovací hodnota je <m>p_i = 1 − R</m> | + | {{ temata:11-rasterizace:basenkruh.png?500 }} |
- | <code> | + | |
- | CircleMid(int s1, int s2, int R) | + | |
- | { int x = 0, y = R; | + | |
- | int P = 1-R, X2 = 3, Y2 = 2*R-2; | + | |
- | while (x < y) | + | |
- | { | + | |
- | draw_pixel_circle(x, y); | + | |
- | if (P >= 0) | + | |
- | { P += -Y2; Y2 -= 2; y--; } | + | |
- | P += X2; | + | |
- | X2 += 2; | + | |
- | x++; | + | |
- | } | + | |
- | } | + | |
- | </code> | + | |
</box> | </box> | ||
- | |||
===== Elipsa ===== | ===== Elipsa ===== | ||
Řádek 187: | Řádek 196: | ||
* úhlem natočení hlavní poloosy | * úhlem natočení hlavní poloosy | ||
* rovnicí elipsy popisující geometrii: <m>F(x, y) : b^2x^2 + a^2y^2 − a^2b^2 = 0</m> | * rovnicí elipsy popisující geometrii: <m>F(x, y) : b^2x^2 + a^2y^2 − a^2b^2 = 0</m> | ||
- | Je 4x symetrická. | + | * je 4x symetrická. |
+ | * výpočet pre štvrtinu bodov | ||
</box> | </box> | ||
Řádek 198: | Řádek 208: | ||
* založen na určování polohy midpointu vůči elipse | * založen na určování polohy midpointu vůči elipse | ||
* V ose X/Y postupujeme o 1, v Y/X o posunu rozhoduje znaménko prediktoru. | * V ose X/Y postupujeme o 1, v Y/X o posunu rozhoduje znaménko prediktoru. | ||
- | </box> | ||
+ | {{ temata:11-rasterizace:midelipsa.png?500 }} | ||
+ | </box> | ||
===== Křivky ===== | ===== Křivky ===== | ||
<box left round blue 90%|**Popis**> | <box left round blue 90%|**Popis**> |