Programowanie: Rysowanie linii

From Atariki

(Różnice między wersjami)
Jump to: navigation, search
Wersja z dnia 00:32, 11 gru 2016
Mono (Dyskusja | wkład)
(draw)
← Previous diff
Aktualna wersja
Mono (Dyskusja | wkład)
(dr.red.)
Linia 1: Linia 1:
-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:+{{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:
<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 11: 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 36: Linia 40:
tay tay
.endr .endr
 +
lda screen+40*49,y lda screen+40*49,y
and bytemask,x and bytemask,x
Linia 48: 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 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.
-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.+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.

Personal tools