Görbeív-rajzolás

Tartalom

Görbeív-rajzolás. 1

Tartalom.. 1

0 Kiindulópont 2

1 Szakaszrajzolás. 2

1.1 Naiv megoldás. 2

1.2 Első javítás. 3

1.3 Második javítás. 3

1.4 Javítás a fényerő-problémán. 4

2 Körrajzolás. 5

2.1 A körív pontjai: (, ) 5

2.2 A körív pontjai: (r*cos(a), r*sin(a)) 5

2.3 A körív követése. 6

 


 

0 Kiindulópont

A képernyőn a „normál” koordinátarendszer:

A két koordinátarendszer közötti áttérést ráhagyjuk a PontRajzol eljárásra, amely felhasználja a képernyőre pontot rajzoló Pont utasítást [1]:

Eljárás PontRajzolás(Konstans x,y:Valós):
  [globális input: ks, ko]
  s:=Kerekít(ks-y); o:=Kerekít(ko+x)[2]
  Ha s
Î[0,MaxY] és oÎ[0,MaxX] akkor Pont(o,s)
Eljárás vége.

1 Szakaszrajzolás

A feladat: szakaszt rajzolni (x1,y1) és (x2,y2) között. Föltehető, hogy x1£x2.

1.1 Naiv megoldás

A két ponton húzható egyenes egyenlete: y=(y2-y1)/(x2-x1)*(x-x1)+y1

A megoldás lényege:

1.   vegyük sorra x lehetséges (egész) értékeit [x1,x2] között, és

2.   rajzoljuk ki az (x,y(x)) pontot!

Eljárás SzakaszRajzolás(Konstans x1,y1,x2,y2:Egész):
  Változó
    x,y,it:Valós

  it:=(y2-y1)/(x2-x1)  [iránytangens]
  Ciklus x=x1-től x2-ig [3]
     y:=(x-x1)*it+y1; PontRajzolás(x,y)
  Ciklus vége
Eljárás vége.

Problémák:

  1. x1=x2–re nem működik.
  2. it£1 (legfeljebb 45° lejtésszög) esetén „folytonos” pixelek sorozata a szakasz, it>1 (több, mint 45° lejtésszög) esetén „szakadozott” pixelek sorozata.
  3. a lejtéssel változó fényerő:

Pl.:       it=0, akkor a „fénysűrűség”=(N-fénypont)/(N pixelnyi hossz)=1,

                        it=1, akkor a „fénysűrűség”=(N-fénypont)/(*(N pixelnyi hossz))=»0,71.

Az alábbiakban először az első két problémára keresünk megoldást.

1.2 Első javítás

Válasszuk szét az it£1, it>1, és x1=x2 eseteket! A 2. esetben cseréljük föl x és y szerepét, a 3. esetben speciálisan erre az esetre specifikálunk egy eljárást.

Eljárás SzakaszRajzolás(Konstans x1,y1,x2,y2:Egész):
  Változó
    x,y,it:Valós

  Ha x1=x2 akkor
   
FüggőlegesRajzolás(x1,y1,y2)
   különben
   
it:=(y2-y1)/(x2-
x1)  [iránytangens]
    Ha it
£1 akkor
        Ciklus x=x1-től x2-ig
          y:=(x-x1)*it+y1; PontRajzolás(x,y)
        Ciklus vége
      különben
        Ciklus
y=y1-től y2-ig
          x:=(y-y1)/it+x1; PontRajzolás(x,y)
        Ciklus vége
    Elágazás vége
  Elágazás vége
Eljárás vége.

1.3 Második javítás

Válasszuk meg úgy az x-irányú lépésközt, hogy az megfelelő legyen minden esetben (a függőleges esetet kivéve). Ez elérhető, ha az x-irányú eltérés (hx) és az y-irányú eltérés (hy) maximumával normáljuk a lépésközöket.

Hány lépést (k) kell tenni?

x2=x1+k*lx  Û  k=(x2-x1)/lx  Û  k=(x2-x1)/(hx/h)  Û 
 
Û  k=(x2-x1)*h/hx  Û  k=(x2-x1)*h/(x2-x1)  Û  k=h

Hasonlóan (és nem meglepő módon) ugyanezt kapjuk az y-irányban is.

Eljárás SzakaszRajzolás(Konstans x1,y1,x2,y2:Egész):
  Változó
    lx,ly,x,y:Valós
    k,hx,hy,h:Egész

  hx:=x2-x1; hy:=y2-y1
  Ha Abs(hx)>Abs(hy) akkor h:=Abs(hx) különben h:=Abs(hy)
  Ha h=0 akkor
    PontRajzolás(x1,y1)
   különben
   
lx:=hx/h  [
x–irányú lépésköz]
    ly:=hy/h  [
y–irányú lépésköz]
    x:=x1; y:=y1; PontRajzolás(x1,y1)  [
kezdőpont]
    Ciklus k=1-től h-ig
      x:+lx; y:+ly; PontRajzolás(x,y)
    Ciklus vége
  Elágazás vége
Eljárás vége.

1.4 Javítás a fényerő-problémán

Ötlet:

         kiegészíteni további (azonos színű, fényességű) pontokkal a „töréseknél”. (A színezés csak az új pontok kiemelését szolgálja.)

Szövegdoboz: ■■■□□□□□□	■□□□
□□□■■■□□□	□■□□
□□□□□□■■■	□□■□
    helyett
■■■□□□□□□	■□□□
□□■■■■□□□	■■□□
□□□□□■■■■	□■■□

Ami után a probléma „megfordul”:

Ui..    ha it=1, akkor h pont helyett h+(h-1) pont lesz,
így a fénysűrűség= ((2*h-1)-fénypont)/(*(h pixelnyi hossz))»
» ((2*h)-fénypont)/(*(h pixelnyi hossz))=*(h-fénypont)/(h pixelnyi hossz)=»1,41

Ötlet:

         kiegészíteni kisebb (számítható) fényerejű pontokkal.

Szövegdoboz: ■■■□□□□□□	■□□□
□□□■■■□□□	□■□□
□□□□□□■■■	□□■□
    helyett
■■■□□□□□□	■□□□
□□ý■■■□□□	ý■□□
□□□□□ý■■■	□ý■□

2 Körrajzolás

A feladat körívet rajzolni. Vegyük észre, hogy

1.      a kör szimmetriája miatt, ha az(x,y) pont rajta van az íven , akkor az (-x,y), (x,-y),
(-x,-y)pontok is rajta lesznek. (Sőt további szimmetriatengelyei is vannak, amelyek kihasznál­hatók!)

2.      az (x0,y0) középpontú kör a (0,0) középpontú eltolásával egyszerűen megkapható, amelyet ismét rábízhatunk a PontRajzol eljárásra.

2.1 A körív pontjai: (, )

Mivel a körív pontjai kielégítik az y2=r2-x2 egyenletet, kapjuk a kézen fekvő megoldást:

Eljárás KörRajzolás(Konstans r:Egész):
  Ciklus x=0-tól r-ig
    y:=Egész(Négyzetgyök(r*r-x*x))
    PontRajzolás(x,y); PontRajzolás(-x,y)
    PontRajzolás(x,-y); PontRajzolás(-x,-y)
  Ciklus vége
Eljárás vége.

Probléma:

            Az ív „meredek” érintőjű részén szakadozik.

2.2 A körív pontjai: (r*cos(a), r*sin(a))

Ezen a problémán segíthetünk azzal, hogy „egyenletesen” járjuk be a negyed körívet. Nem x-szerint haladunk, hanem origóból azonos (Da) szögelfordulással haladva:

Eljárás KörRajzolás(Konstans r:Egész):
  Változó
   
Da,a: Valós

  Da:=???
  Ciklus
a=0-tól p/2-ig Da-asával
    x:=r*cos(
a); y:=r*sin(a)
    PontRajzolás(x,y); PontRajzolás(-x,y)
    PontRajzolás(x,-y); PontRajzolás(-x,-y)
  Ciklus vége
Eljárás vége.

Meggondolandó a Da választása! Ha túl kicsire választjuk, akkor sokszor fogja ugyanazt a pontot kiszínezni, ha meg túl nagyra, akkor meg kimaradnak pontok.

Legyen Da-nyi fordulat az r-sugarú íven kb. 1 pixelnyi! Azaz  Da / (2*p) = 1 / (2*r*p)

Þ Da = 1 / r

2.3 A körív követése

Egy, a görbék rajzolására általánosan alkalmazható ötlet:

1.   kiindulás a görbe egy alkalmas kezdőpontjából,

2.   válasszunk valamilyen elképzelhető haladási (rajzolási) irányt (balra/jobbra és/vagy fel/le),

3.   az irányba eső szomszédos (mondjuk: 5) pontokat vizsgáljuk meg: melyik tér el legkevésbé a görbétől [4]. S arra lépjünk tovább!

Pl.:

     oo
      
no
      
oo

A kör esetén megint csak az első negyedbeli ívét használjuk föl „vezérlőként”.

Eljárás KörRajzolás(Konstans r:Egész):
  Változó
    x,y,rr:Valós

  x:=0; y:=r; rr:=r*r
  Ciklus amíg y
³0
    PontRajzolás(x,y); PontRajzolás(-x,y)
    PontRajzolás(x,-y); PontRajzolás(-x,-y)
    Elágazás
      (x+1)*(x+1)+y*y
£rr esetén
            x:+1          [vízszintesen]
      (x+1)*(x+1)+(y-1)*(y-1)
£rr esetén
           
y:-1; x:+1    [vízszintesen és le]
      egyéb esetben
           
y:-1          [
le]
    Elágazás vége
  Ciklus vége
Eljárás vége.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Megjegyzés:

Az világos, hogy az algoritmusbeli feltételek –sorrendjükkel együtt– feltételezik, hogy a „vezérlő szerepű” körív-darab éppen az 1. negyedbe eső negyed körív, sőt, hogy a rajzolás az (0,r)-től kezdődik. (Ui.: y³0; és elegendő 5 helyett a rajzon jelzett 3 „próbapont”; a „leg­kevésbé eltérés”-t helyettesíthetjük a „a körlapba először belépés”-sel.)

Észre kell vennünk, hogy az általános algoritmust csak „e-pontossággal” kö­veti a fenti, ui. elképzelhető, hogy bár a jobbra lépés lenne a legjobb, mi még­is a „jobbra-le” szomszédot választjuk, mert ő az első még bennmaradó. Ez a hiba azonban a kör „körségét” nem befolyásolja, az ívtől való elszakadástól nem kell tartanunk.

 



[1] ami a TurboGrafikában (Graph unit a Turbo/FreePascal-ban): PutPixel(o,s,pontSzín).

[2] Érdemes eljátszadozni a Kerekít függvény helyett Egészrész-szel.

[3] Ha x1£x2.nem lenne feltehető, akkor a ciklus Sgn(x2-x1)-esével szervezzük

[4] Ez egy jó, nem ritkán nehezen megválaszolható kérdés! Gyakran helyettesítik valami hasonló, de könnyebben megvá­laszolhatóval.