Raszteres grafika
Egyenes rajzolása
Kör rajzolása
Ellipszis rajzolása
Raszteres grafika
Feladat:
grafikai primitíveket (pl. vonalat, síkidomot) ábrázolni kép-mátrixszal
meghatározni azokat a képpontokat, amelyek a primitív pontjai, vagy közel
vannak a primitívhez
modell:
képpont (= körlap), amely a négyzetháló csúcspontjaiban helyezhető el
koordináták: egész számok
Vissza a lap tetejére
Egyenes rajzolása:
Tfh.: "vékony" egyenes y = mx + B
meredeksége: 0 < m < 1
(m = 0,1,... triviális speciális esetek)
más esetekben 0 < m < 1 -re visszavezetjük
legyen: x0 < x1 , y0 < y1
1. Alap inkrementális algoritmus
haladjunk balról jobbra x = 1
növekménnyel, válasszuk a legközelebbi képpontot:
(xi, [yi+0.5])
= (xi, [mxi+B+0.5])
a szorzás kiküszöbölhető inkrementálással:
yi+1 = mxi+1+B = m( xi+ x)+ B
= yi+m x = yi+m
Algoritmus:
(ha |m|>1, akkor x-et cseréljük y-nal)
procedure Line(
x0,y0,
x1,y1,
value : integer);
var
x : integer;
dy,dx,y,m : real;
begin
dy := y1-y0;
dx := x1-x0;
m := dy/dx;
y := y0;
for x := x0 to x1 do
begin
WritePixel (x, Round(y), value);
y := y+m
end
end; {Line}
2. Felezőpont algoritmus egyenesre
egész aritmetika elegendő (Bresenham)
elv:
azt a képpontot válasszuk NE és E közül, amelyik közelebb
van a Q metszésponthoz, azaz, hogy Q az M felezéspont
melyik oldalán van, az döntsön a választásban.
tfh.: x0< x1 , y0< y1
| legyen
F(x,y) = |
ax+by+c = 0 |
| dx
= |
x1-x0 |
| dy
= |
y1-y0 |
| F(x,y)
= |
dy·x-dx·y+B·dx
= 0 |
| |
 |
>
0, ha (x,y) az egyenes alatt van, |
| F(x,y) |
=
0, ha (x,y) az egyenesen van, |
| |
< 0,
ha (x,y) az egyenes fölött van. |
felezőpont kritérium:
| |
|
választás: |
| |
 |
>
0, ha M alul, |
NE |
| d
= F(M) = F(xp+1,yp+1/2)
|
=
0, ha M rajta, |
NE
vagy E |
| (d
: döntési változó) |
<
0, ha M fölül |
E |
következő pontnál:
ha E-t választottuk, akkor
E
= dúj-drégi = F(xp+2,yp+1/2)-F(xp+1,yp+1/2)
= dy,
ha NE-t választottuk, akkor
NE
= F(xp+2,yp+3/2)-F(xp+1,yp+1/2)
= dy-dx.
kezdés:
dstart = F(x0+1,y0+1/2)
= F(x0,y0)+dy-dx/2 = dy = dx/2
azért, hogy egész aritmetikával számolhassunk, használjuk inkább az
F(x,y) = 2·(dy·x-dx·y+B·dx)
= 0
függvényt.
procedure MidpointLine(x0,y0,x1,y1,value : integer);
var
dx,dy,incrE,incrNE,d,x,y : integer;
begin
dx := x1-x0;
dy := y1-y0;
d := 2*dy-dx;
incrE := 2*dy;
incrNE := 2*(dy-dx);
x := x0;
y := y0;
WritePixel(x,y,value);
while x < x1 do
begin
if d <= 0 then
begin
d := d + incrE;
x := x + 1
end
else
begin
d := d + incrNE;
x := x + 1;
y := y + 1
end;
WritePixel(x,y,value)
end {while}
end; {MidpointLine}
eredmény: pl.
tulajdonságok:
- csak összeadás és kivonás
- általánosítható körre, ellipszisre
Problémák:
1. Különböző pontsorozat lesz az eredmény ha balról jobbra,
vagy ha jobbról balra haladunk.
legyen a választás:
balról jobbra: d = 0
E-t választani
jobbról balra: d = 0
SW-t választani
(megjegyzés: nem mindig lehet csak balról jobbra haladva rajzolni az
egyeneseket - pl. szaggatott vonallal rajzolt zárt poligon)
2. A vonal pontjainak a sűrűsége függ a meredekségétől
megoldás:
intenzitás változtatása
kitöltött téglalapnak tekinteni az egyenest
Vissza a lap tetejére
Kör rajzolása:
x2+y2 = R2
R : egész
1.
elég egy kör-negyedet megrajzolni (a többi rész a szimmetria
alapján transzformációkkal - pl. tükrözés - előáll)
x 0-tól R-ig növekszik,
y = 
drága eljárás (szorzás, gyökvonás),
nem egyenletes
2. polárkoordinátás alak
x = R·cos
0°-tól 90°-ig növekszik
y = R·sin 
drága eljárás (sin, cos)
Elég egy nyolcad kört kiszámítani:
procedure Circlepoints(x,y,value: integer);
begin
WritePixel (x, y, value);
WritePixel (y, x, value);
WritePixel (y, -x, value);
WritePixel (x, -y, value);
WritePixel (-x, -y, value);
WritePixel (-y, -x, value);
WritePixel (-y, x, value);
WritePixel (-x, y, value);
end; {CirclePoints}
3. Felezőpont algoritmus körre
x 0-tól R/  -ig
elv:
azt a pontot választjuk E és SE közül, amelyikhez
a körív metszéspontja közelebb van
| |
 |
> 0,
ha (x,y) kívül van, |
| F(x,y)
= x2+y2-R2 |
= 0,
ha (x,y) rajta van, |
| |
< 0,
ha (x,y) belül van. |
| |
 |
> 0
SE-t választani |
| d = F(M)
= F(xp+1, yp-1/2) |
= 0
SE vagy E |
| |
< 0
E-t választani |
 |
dúj
= F(xp+2, yp- 3/2) |
 |
|
 |
SE
= 2xp-2yp+5 |
 |
| |
|
|
| dúj
= F(xp+2, yp-1/2) |
|
E
= 2xp+3 |
tehát az iterációs lépések:
1. a döntési változó előjele alapján kiválasztjuk a következő
képpontot
2. d = d + (a választástól
függően) SE
vagy E
kezdés:
kezdőpont: (0,R)
felezőpont: (1,R-1/2)
d = F(1,R-1/2) = 5/4 -R
procedure MidpointCircle (radius, value : integer);
var
x, y : integer; d: real;
begin
x := 0;
y := radius;
d := 5/4-radius;
CirclePoints (x,y,value);
while y>x do
begin
if d<0 then
begin
d := d+2*x+3;
x := x+1
end
else
begin
d := d+2*(x-y)+5;
x := x+1;
y := y-1
end;
CirclePoints (x,y,value)
end {while}
end; {MidpointCircle}
nem egész aritmetika, ezért legyen h új döntési változó:
h = d-1/4
h+1/4 = d < 0
h < -1/4
ekkor kezdéskor
h
= 1-R
igaz, hogy d < 0 helyett h < 1/4-et kellene vizsgálni, de
ez ekvivalens h < 0-val,
tehát egész aritmetika használható: (a sugár is egész)
procedure MidpointCircle (radius, value : integer);
var
x,y,d : integer;
begin
x := 0;
y := radius;
d := 1-radius;
CirclePoints (x,y,value);
while y>x do
begin
if d<0 then
begin
d := d+2*x+3;
x := x+1
end
else
begin
d := d+2*(x-y)+5;
x := x+1;
y := y-1
end;
CirclePoints (x,y,value)
end {while}
end; {MidpointCircle}
4. Másodrendű differenciák
stratégia:
egy függvény értéke becsülhető két pontban felvett értékei
különbségét használva
(ami polinomok esetében alacsonyabb fokszámú lesz).
használjunk első- és másodrendű parciális differenciákat
tudjuk, hogy
E(xp,yp)
= 2·xp+3
SE(xp,yp)
= 2·xp-2·yp+5,
akkor, ha E-t választottuk (xp,yp)
(xp+1,yp),
akkor
E új- E
régi = 2, SE
új- SE régi = 2;
ha SE-t választottuk (xp,yp)
(xp+1,yp-1)
E új- E
régi = 2, SE új- SE
régi = 4.
tehát az iterációs lépések:
1) d előjele alapján a következő képpont kiválasztása
2) d = d+ (a választástól
függően E vagy
SE)
3) E és SE
módosítása (a választástól függően)
procedure MidpointCircle (radius,value : integer);
var
x,y,d,deltaE,deltaSE : integer;
begin
x := 0;
y := radius;
d := 1-radius;
deltaE := 3;
deltaSE := -2*radius+5;
CirclePoints(x,y,value);
while y>x do
begin
if d<0 then
begin
d := d+deltaE;
deltaE := deltaE+2;
deltaSE := deltaSE+2;
x := x+1
end
else
begin
d := d+deltaSE;
deltaE := deltaE+2;
deltaSE := deltaSE+4;
x := x+1;
y := y-1
end;
CirclePoints(x,y,value)
end {while}
end; {MidpointCircle}
Vissza a lap tetejére
Ellipszis rajzolása
a,b
egész
F(x,y) = b2x2
+ a2y2 - a2b2 = 0
szimmetria miatt: elég az első síknegyedben megrajzolni
DaSilva algoritmusa (felezőpont módszer)
bontsuk a negyedet két tartományra:
1. tartománynak vége, ha
a2(yp-1/2)
b2(xp+1)
1. tartományban:
| |
 |
0 SE-t választjuk |
 |
|
| d1
= F(xp+1,yp-1/2) |
|
 |
| |
< 0
E-t választjuk |
| |
 |
drégi
= F(xp+1,yp-1/2), dúj
= F(xp+2,yp-3/2) |
 |
|
|
|
 |
| |
drégi
= F(xp+1,yp-1/2), dúj
= F(xp+2,yp-1/2) |
| |
 |
SE
= b2(2xp+3)
+ a2(-2yp+2) |
|
|
| |
E
= b2(2xp+3) |
2. tartományban:
megoldása házi feladat otthon
kezdés:
kezdőpont: (0,b)
felezőpont: (1,b-1/2)
d = F(1,b-1/2) = b2+a2(-b+1/4)
procedure MidpointEllipse (a,b,value : integer);
var
x,y: integer; d1,d2: real;
begin
x := 0;
y := b;
d1 := b2-a2b+a2/4;
EllipsePoints (x,y,value);
while (a2(y-1/2) > b2(x+1)) do
begin
if d1<0 then
begin
d1 := d1+b2(2x+3);
x := x+1
end
else
begin
d1 := d1+b2(2x+3)+a2(-2y+2);
x := x+1;
y := y-1
end
EllipsePoints (x,y,value)
end; {Region1}
d2 := b2(x+1/2)2+a2(y-1)2-a2b2;
while (y>0) do
begin
if d2<0 then
begin
d2 := d2+b2(2x+2)+a2(-2y+3);
x := x+1;
y := y-1
end
else
begin
d2 := d2+a2(-2y+3);
y := y-1
end;
EllipsePoints (x,y,value)
end {Region2}
end; {MidpointEllipse}
Vissza a lap tetejére
|