Programowanie: Rysowanie linii
From Atariki
Wersja z dnia 00:38, 11 gru 2016 Mono (Dyskusja | wkład) (bledy wspolczynnika kierunkowego) ← Previous diff |
Aktualna wersja Mono (Dyskusja | wkład) (dr.red.) |
||
Linia 1: | Linia 1: | ||
{{SDP}} | {{SDP}} | ||
- | Draw dla trybu lowres (Graphics 15) 160x192 rysujący linię o długości 50 pikseli w pionie od pozycji x,0 o kącie nachylenia z zakresu [-45;45] stopni: | + | Draw dla trybu lowres (Graphics 15) 160x192 rysujący linię o długości 50 pikseli w pionie od pozycji (x,0) o kącie nachylenia z zakresu [-45;45] stopni: |
<pre> | <pre> | ||
- | org $80 | ||
COLOR = 1 ;kolor z zakresu 0,1,2,3 | COLOR = 1 ;kolor z zakresu 0,1,2,3 | ||
+ | org $80 | ||
dx .ds 2 | dx .ds 2 | ||
tmp .ds 1 | tmp .ds 1 | ||
Linia 13: | Linia 13: | ||
ldy #0 | ldy #0 | ||
sty tmp | sty tmp | ||
- | lsr | + | |
- | ror tmp | + | cpx #$80 ;rozszerzenie alpha na 16 bit |
- | lsr | + | |
- | ror tmp | + | |
- | stx dx | + | |
- | cpx #$80 | + | |
scc | scc | ||
dey | dey | ||
- | ldx tmp | + | stx dx |
sty dx+1 | sty dx+1 | ||
+ | |||
+ | lsr ;obliczenie pozycji punktu w linii | ||
+ | ror tmp | ||
+ | lsr | ||
+ | ror tmp | ||
tay | tay | ||
+ | ldx tmp | ||
.rept 49 | .rept 49 | ||
Linia 38: | Linia 40: | ||
tay | tay | ||
.endr | .endr | ||
+ | |||
lda screen+40*49,y | lda screen+40*49,y | ||
and bytemask,x | and bytemask,x | ||
Linia 50: | Linia 53: | ||
</pre> | </pre> | ||
- | Rejestry YX w pętli zawierają pozycję x piksela, modyfikowaną o przyrost dx. Jest to liczba z 6 bitami części ułamkowej (najmłodsze bity rejestru X) i dwoma bitami wskazującymi na pozycję piksela w bajcie (dwa najstarsze bity rejestru X mapowane na konkretne maski przez tablice bytemask i bytepxl). Rejestr Y zawiera pozycję bajtu w linii ekranowej. | + | Algorytm wykorzystuje właściwość funkcji liniowej y=ax+b określającą współczynnik kierunkowy a prostej, jako a=tg(alpha) kąta odchylenia prostej od pionu - określa on poziomy przyrost dx o jaki z każdym krokiem odchylana jest prosta. |
+ | |||
+ | Ponieważ można założyć, że w zakresie [-45;45] stopni a=tg(alpha) jest w przybliżeniu funkcją liniową, dlatego zrezygnowano z obliczania funkcji na rzecz wartości a podawanej bezpośrednio do procedury draw (kąt alpha w zakresie [-45;45] stopni jest mapowany na współczynnik kierunkowy a w zakresie [-$40;$40]). | ||
+ | |||
+ | Rejestry YX w pętli zawierają pozycję x piksela, modyfikowaną o przyrost dx. Jest to liczba z 6 bitami części ułamkowej (najmłodsze bity rejestru X) i 2 bitami wskazującymi na pozycję piksela w bajcie (dwa najstarsze bity rejestru X mapowane na konkretne maski przez tablice bytemask i bytepxl). Rejestr Y zawiera pozycję bajtu w linii ekranowej. | ||
- | Algorytm pomija błędy wynikające z akumulacji znacznika C w części ułamkowej pozycji piksela, ponieważ ma ona rozmiar 6 bitów (64 możliwe wartości) i przy rysowaniu 50 pikseli błąd się nie ujawni. | + | Algorytm zaniedbuje błędy wynikające z małej rozdzielczości części ułamkowej pozycji x piksela (ma ona rozmiar 6 bitów), ponieważ jest ona wystarczająca do rysowania linii o długości mniejszej niż 2<sup>6</sup>=64 pikseli. |
- | Dodatkowo błędy mogące wynikać z niewielkiej rozdzielczości współczynnika kierunkowego (alpha) odcinka w zakresie -45..45 stopni są w przypadku tak krótkiej linii pomijalne. | + | Dodatkowo błędy mogące wynikać z niewielkiej rozdzielczości współczynnika kierunkowego (alpha) odcinka w zakresie [-45;45] stopni są w przypadku tak krótkiej linii pomijalne. |
[[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] |
Aktualna wersja
Draw dla trybu lowres (Graphics 15) 160x192 rysujący linię o długości 50 pikseli w pionie od pozycji (x,0) o kącie nachylenia z zakresu [-45;45] stopni:
COLOR = 1 ;kolor z zakresu 0,1,2,3 org $80 dx .ds 2 tmp .ds 1 ;A = x, X = alpha (U2 - $c0=-45..0=0..$40=45) draw: ldy #0 sty tmp cpx #$80 ;rozszerzenie alpha na 16 bit scc dey stx dx sty dx+1 lsr ;obliczenie pozycji punktu w linii ror tmp lsr ror tmp tay ldx tmp .rept 49 lda screen+40*#,y and bytemask,x ora bytepxl,x sta screen+40*#,y txa adc dx tax tya adc dx+1 tay .endr lda screen+40*49,y and bytemask,x ora bytepxl,x sta screen+40*49,y rts bytemask: :256 .byte ~(%11 << (6 - ((# / 64) * 2))) bytepxl: :256 .byte COLOR << (6 - ((# / 64) * 2))
Algorytm wykorzystuje właściwość funkcji liniowej y=ax+b określającą współczynnik kierunkowy a prostej, jako a=tg(alpha) kąta odchylenia prostej od pionu - określa on poziomy przyrost dx o jaki z każdym krokiem odchylana jest prosta.
Ponieważ można założyć, że w zakresie [-45;45] stopni a=tg(alpha) jest w przybliżeniu funkcją liniową, dlatego zrezygnowano z obliczania funkcji na rzecz wartości a podawanej bezpośrednio do procedury draw (kąt alpha w zakresie [-45;45] stopni jest mapowany na współczynnik kierunkowy a w zakresie [-$40;$40]).
Rejestry YX w pętli zawierają pozycję x piksela, modyfikowaną o przyrost dx. Jest to liczba z 6 bitami części ułamkowej (najmłodsze bity rejestru X) i 2 bitami wskazującymi na pozycję piksela w bajcie (dwa najstarsze bity rejestru X mapowane na konkretne maski przez tablice bytemask i bytepxl). Rejestr Y zawiera pozycję bajtu w linii ekranowej.
Algorytm zaniedbuje błędy wynikające z małej rozdzielczości części ułamkowej pozycji x piksela (ma ona rozmiar 6 bitów), ponieważ jest ona wystarczająca do rysowania linii o długości mniejszej niż 26=64 pikseli.
Dodatkowo błędy mogące wynikać z niewielkiej rozdzielczości współczynnika kierunkowego (alpha) odcinka w zakresie [-45;45] stopni są w przypadku tak krótkiej linii pomijalne.