Presentatie titel Rotterdam, 00 januari 2007 Computer Graphics Technische Informatica
Les 2 Les 2 gaat over de hoofdstukken: 3.1 Scan-conversie van een punt 3.2 Scan-conversie van een lijn 3.3 Scan-conversie van een cirkel 3.4 Scan-conversie van een ellips 3.5 Scan-conversie van een bogen en sectoren 3.6 Scan-conversie van een rechhoek 3.7 Opvullen van een gebied 3.8 Scan-conversie van een karakter
Inleiding Veel figuren bestaan uit primitieven (punt,lijn,..enz) Deze zijn gedefinieerd in de continue ruimte i.p.v. pixels in de discrete beeld ruimte Bijv. een lijn heeft vergelijking door 2 eindpunten Het grafische systeem moet die vergelijking converteren naar de beeldruimte. Dit heet scan- conversie of rastering Dit hoofdstuk gaat over wiskundige en algoritmische apecten van scan-conversie Primitieven zoals punt,lijn,cirkel,ellips,..enz.
Scan-conversie: punt Een wiskundig punt (float x,float y) moet geconverteerd worden naar een pixel op lokatie (x’,y’) Dit kan op 2 manieren; 1. Door (x’,y’) gelijk te maken aan het integer gedeelte van (x,y) (het gehele getal) Dit kan met de Floor functie x’= Floor(x), y’=Floor(y) Deze levert de grootste waarde af die ≤ argument
Scan-conversie: punt Alle punten die voldoen aan: x’≤ x<x’+1 en y’≤y<y’+1 worden afgebeeld op pixel (x’,y’) Het plaats de oorsprong in de linkerhoek van het pixel (zie fig 3-1a)
Scan-conversie: punt Voorbeeld: P1(1.7,0.8) pixel (1,0) P2(2.2,1.3) pixel (2,1) P2(2.8,1.9) pixel (2,1) 2. De Floor functie kan ook anders ingevuld worden: x’= Floor(x+0,5), y’=Floor(y+0,5) Alle punten die voldoen aan: x’-0,5 ≤ x< x’+0,5 en y’+0,5 ≤y<y’+0,5 worden afgebeeld op pixel (x’,y’)
Scan-conversie: punt Het plaats de oorsprong in het centrum van het pixel (zie fig 3-1b) Voorbeeld: P1(1.7,0.8) pixel (2,1) P2(2.2,1.3) pixel (2,1) P2(2.8,1.9) pixel (3,2) De 2e benadering wordt gebruikt Andere voorbeelden van afrondfuncties: Floor(4.8) 4 Floor(4.1) 4 Ceil(4.8) 5 Ceil(4.1) 5 Round(4.8) 5 Round(4.1) 4
Scan-conversie: lijn Een lijn wordt bepaald door 2 eindpunten P 1 en P 2 ( zie fig 3-2) De vergelijking van de lijn is y=mx+b m=helling; b=snijpunt y-as Men kiest m ≥ 1 ( rest wordt afgeleid) m=∞, horizontaal,vertikaal worden apart berekend
Scan-conversie: lijn Directe berekening: P 1 en P 2 converteren naar pixel P 1 ’(x 1 ’,y 1 ’) en P 2 ’(x 2 ’,y 2 ’) De helling wordt dan: Het snijpunt y-as b = y 1 ’ - m.x 1 ’ Het nadeel hiervan is dat er floating point berekeningen zijn
Scan-conversie: lijn DDA algoritme: (Digital Differential Algoritme) Dit is een incrementele scan-conversie methode Na iedere stap i wordt opnieuw x i+1 en y i+1 berekend Als (x i,y i ) berekend is als een punt op de lijn, dan moet het volgende punt (x i+1,y i+1 ) voldoen aan ∆x/∆y=m Hierbij is ∆y= y i+1 -y i en ∆x=x i+1 -x i Nu is y i+1 =y i + ∆x.m
Scan-conversie: lijn Als |m| ≤ 1 starten we met x=x’en y=y’en maken ∆x=1 De y-coordinaat wordt dan y i+1 =y i +m Dit gaat door tot y=y 2 ’ Als |m| > 1 starten we met x=x’en y=y’en maken ∆y = 1 De x-coordinaat wordt dan x i+1,= x i +1/m Dit gaat door tot x=x 2 ’ Alle punten zijn dan pixels DDA is sneller omdat er geen floating point vermenigvuldigingen zijn Wel een floating point optelling (1/m eenmalig berekend)
Scan-conversie: lijn Bresenham algoritme: Dit is een efficiente incrementele methode om scan-conversie van een lijn uit te voeren Het gebruikt alleen integer optelling,aftrekken en vermenigvuldigen met 2 (schuif-operatie) In fig 3-3 is een lijn getekend voor 0<m<1 Om een volgend punt te vinden moet gekozen worden voor S of T (naar opzij of naar beneden) Zonder afleiding wordt het resultaat:
Scan-conversie: lijn
int x=x’, y=y’; int dx=x 2 ’- x 1 ’, dy = y 2 ’-y 1 ’ ; int dT=2(dy-dx), dS= 2dy; int d=2dy-dx; setPixel(x,y); while( x < x 2 ’ ) { x++; if (d <0) d=d +dS; else { y++; d= d+dT;} } setPixel(x,y); }
Scan-conversie: cirkel Er zijn verschillende manieren om een cirkel te berekenen Een cirkel is symmetrisch Door 1 punt te bereken kunnen 8 punten ingevuld worden ( zie fig 3-4) De punten zijn: P 1 =(x,y)P 5 =(-x,-y) P 2 =(y,x)P 6 =(-y,-x) P 3 =(-y,x)P 7 =(y,-x) P 4 =(-x,y)P 8 =(x,-y)
Scan-conversie: cirkel
Er zijn 2 definities voor een cirkel: 1. 2e orde polynoom (2 e graads vergelijking) y 2 =r 2 –x 2 zie fig. 3-5 Hierin is: x=x-coordinaat y=y-coordinaat r= straal Inefficient algoritme vanwege de vele berekeningen (wortel, kwadraat,enz)
Scan-conversie: cirkel 2. Goniometrische functie (zie fig 3-6) x=rcosθ y=rsinθ x= x-coordinaat y= y-coordinaat R= cirkel straal Θ = hoek Bij deze methode gaat θ van 0 tot π/4 en x en y worden berekend Dit kost nog meer rekentijd om sin en cos te berekenen dan de 1 e methode
Scan-conversie: cirkel Bresenham algoritme: Dit is een efficiente incrementele methode om scan-conversie van een cirkel uit te voeren Het gebruikt alleen integer optelling,aftrekken en vermenigvuldigen met 2 (schuif-operatie) Alleen de berekening van is nodig (zie fig 3-7 De beste benadering van de echte cirkel zijn punten in het raster,die er dicht bij zijn door: 1. Beweeg in de x-richting 1 stap 2. Beweeg in de x-richting 1 stap en de negatieve y-as 1 stap
Scan-conversie: cirkel Een keuze van 1 van de 2 dient te worden gemaakt Neem aan dat (x i,y i ) de coordinaten zijn van het laatst geconverteerde punt na stap i (zie fig 3-8)
Scan-conversie: cirkel
Dan is pixel P=(x i,y i ) Dan is pixel T=(x i +1,y i ) Dan is pixel S=(x i +1,y i -1) Stel D(T)= (x i +1) 2 + y i 2 – r 2 Stel D(S)= (x i +1) 2 + (y i -1) 2 – r 2 D geeft de relatieve afstand van een pixelcentrum tot de echte cirkel D(T) is altijd positief (buiten de cirkel) D(S) is altijd negatief (binnen de cirkel)
Scan-conversie: cirkel Een beslississingsvariabele d i is als volgt gedefinieerd: d i = D(T) + D(S) d i = 2(x i +1) 2 +y i 2 +(y i -1) 2 – 2r 2 Als d i <0 dan is |D(T)| < |D(S)| en wordt pixel T gekozen Als d i ≥0 dan is |D(T)| ≥ |D(S)| en wordt pixel S gekozen Nu de beslissingsvariable d i+1 bepalen voor de volgende stap:
Scan-conversie: cirkel d i+1 = 2(x i+1 +1) 2 +y i+1 2 +(y i+1 -1) 2 - 2r 2 Nu is: d i+1 -d i = 2(x i+1 +1) 2 +y i+1 2 +(y i+1 -1) 2 - 2r 2 -2(x i +1) 2 -y i 2 -(y i -1) 2 + 2r 2 = 2(x i+1 +1) 2 +y i+1 2 +(y i+1 -1) 2 -2(x i +1) 2 -y i 2 -(y i -1) 2 Daar x i+1 = x i +1 d i+1 =d i +2(x i +2) 2 +y i+1 2 +(y i+1 -1) 2 -2(x i +1) 2 -y i 2 -(y i -1) 2
Scan-conversie: cirkel d i+1 =d i + 2x i 2 + 8x i + 8+ y i y i y i x i 2 - 4x i -2 - y i 2 - y i 2 + 2y i - 1 d i+1 =d i + 4x i + 2( y i y i 2 ) -2( y i+1 - y i ) +6 Als T het gekozen pixel is(d i <0) dan is y i+1 =y i d i+1 =d i + 4x i + 6 Als S het gekozen pixel is(d i ≥0) dan is y i+1 =y i -1 d i+1 =d i + 4x i + 2( y i -1) 2 - 2y i 2 -2( y i -1 - y i ) +6
Scan-conversie: cirkel d i+1 =d i + 4x i + 2y i 2 - 4y i +2- 2y i d i+1 =d i + 4x i - 4y i +10 d i+1 =d i + 4(x i - y i )+10 Conclusie: d i+1 =d i + 4x i + 6 als d i <0 d i+1 =d i + 4(x i - y i )+10 als d i ≥0 Als startpunt kiezen we (x i, y i )=(0,r) Gegeven was d i = 2(x i +1) 2 +y i 2 +(y i -1) 2 – 2r 2 d 1 =2(0+1) 2 + r 2 +(r-1) 2 -2r 2
Scan-conversie: cirkel d 1 =2 + r 2 +r 2 -2r +1-2r 2 = 2 - 2r +1 = 3-2r Voor 90 0 < θ <45 0 geldt dan: int x =0, y=r, d=3-2r; while ( x <= y) { setPixel (x,y) if (d <0) d= d+4x+ 6; else { d=d+4(x-y) +10; y--; } x++; } Er is alleen schuiven (vermenigvuldigen met 4) en optellen
Scan-conversie: ellips De ellips heeft evenals de cirkel symmetrie (4 keer i.p.v. 8 keer) Er zijn 2 definities voor een ellips: 1. 2e orde polynoom (2 e graads vergelijking) (zie fig. 3-9) Hierin is: (h,k)= centrum van de ellips a= lengte van de lange as b=lengte van korte as
Scan-conversie: ellips De waarde van x wordt verhoogd van h tot a Voor iedere stap moet y berekend worden met:
Scan-conversie: cirkel Deze methode is zeer inefficient. De kwadraten, floating point, wortels,enz 2. Goniometrische functie (zie fig 3-10)
Scan-conversie: ellips De vergelijkingen zijn: x=a cos(θ)+h en y=bsin(θ)+k Met (x,y) de coordinaten a=lengte van de lange as b=lengte korte as (h,k)= middelpunt ellips De waarde van θ loopt van 0 tot π/2 radialen De overige posities met symmetrie bepalen De methode is niet efficient Met veel geheugen en lookup tabellen van sinus en cosinus te versnellen
Scan-conversie: ellips Midpoint algorime: Dit is een efficiente incrementele methode om scan-conversie van een ellips uit te voeren Het gebruikt alleen integer optelling,aftrekken en vermenigvuldigen met 2 (schuif-operatie)
Scan-conversie: boog Een boog (fig 3-13a) kan worden gegenereerd met polynomen of goniometrische functies
Scan-conversie: boog Als de goniometrische functie gebruikt wordt: De startwaarde is θ 1 en de eindwaarde θ 2 (zie fig 3-13 a en b) De rest van de stappen zijn identiek als bij een cirkel Als de polynoommethode gebruikt wordt dan varieert de waarde van x1 en x2 (zie fig 3-14) De waarde van y wordt berekend uit Bresenham wordt niet gebruikt omdat de eindpunten moeilijk te berekenen zijn
Scan-conversie: boog
Scan-conversie: sector Een sector wordt geconverteerd door scan- conversie voor een boog uit te voeren en Daarna de scan-conversie voor de 2 lijnen vanuit het centrum Stel sectorcentrum (h,k) Eerst scan-conversie van een boog van θ 1 tot θ 2 Daarna een lijn van (h,k) tot (rcos (θ 1 )+h,rsin (θ 1 )+k ) Daarna een lijn van (h,k) tot (rcos (θ 2 )+h,rsin (θ 2 )+k )
Scan-conversie: rechthoek Een rechthoek waarvan de assen evenwijdig zijn aan de coordinaatassen is bepaald als er 2 hoekpunten bekend zijn (zie fig 3-16a) De overgebleven hoekpunten kunnen worden afgeleid (zie fig 3-16b)
Scan-conversie: rechthoek Als de hoekpunten bekend zijn, worden de coordinaten doorgegeven aan de lijnroutine en scan-conversie van de rechthoek vindt plaats De volgende lijnen worden getekend: De lijn (x 1,y 1 ) naar (x 1,y 2 ) De lijn (x 1,y 2 ) naar (x 2,y 2 ) De lijn (x 2,y 2 ) naar (x 2,y 1 ) De lijn (x 2,y 1 ) naar (x 1,y 1 )
Opvullen van een gebied Het opvullen van een gebied is het kleuren van een gedeelte van een gebied Gebieden kunnen gedefinieerd worden op pixel of meetkundig niveau Op pixel niveau beschrijven we het gebied in termen van de grens pixels (zie fig 3-17a) of de totale pixels die het gebied omvat (zie fig 3- 17b) Voor (a) wordt boundary-fill algoritme gebruikt Voor (b) wordt flood-fill algoritme gebruikt
Opvullen van een gebied Op meetkundig niveau is een gebied gedefinieerd met lijnen en krommen (bijv. een polygoon)
Opvullen van een gebied Boundary-fill Dit is een recursief algoritme dat begint met een startpixel binnen het gebied ( seed) Het algoritme kijkt of dit pixel a) een grenspixel is of b) dat het al gevuld is Als het antwoord nee is wordt het pixel gevuld en roept zichzelf weer aan en een buurpixel wordt gebruikt als nieuw seed Als het antwoord ja is, wordt teruggekeerd naar zijn oorspronkelijke oproep
Opvullen van een gebied Flood-fill Dit algoritme begint met een startpixel (seed) binnen het gebied. Het kijkt of het pixel de orginele kleur heeft van het gebied. Als het antwoord ja is, wordt het pixel gevuld met een nieuwe kleur en gebruikt een buurpixel als nieuw seed wordt opnieuw opgeroepen (recursief) Als het antwoord nee is, wordt teruggekeerd naar zijn oorspronkelijke oproep Deze methode is bruikbaar als er geen uniform gekleurde grens is
Scan-lijn algoritme In plaats van op pixel niveau kan ook een polygoon opgevuld worden (gebieden die meetkundig gedefinieerd zijn met coordinaten) Dit is een snellere methode dan boundary fill We hebben een gebied met hoekpunten V1,V2, V3,.., die verbonden zijn met lijnen E1,E2, E3, …, (zie fig 3-19) We nemen aan dat ieder hoekpunt al een conversie heeft ondergaan naar integer coordinaten (x i,y i )
Scan-lijn algoritme
Het algoritme begint met de eerste scanlijn van de polygoon en vervolgt tot de laatste scanlijn Voor iedere scanlijn berekend het het snijpunt met de polygoon Bijv: scanlijn y snijdt de lijnen E1,E7,E6 en E4 in de punten a,b,c,d De snijpunten worden gesorteerd naar de x- coordinaat en gegroepeerd als paren, bijv (a,b) en (c,d) Daarna wordt een lijn getekend van het 1e punt naar het 2e punt van elk paar
Scan-lijn algoritme Horizontale lijnen worden genegeerd,want die worden automatisch gevuld met de juiste kleur tijdens de scan conversie Bijv: lijn E5 wordt getekend als de scan lijn geconverteerd wordt
Scan-conversie: karakter Karakters, zoals letters en cijfers zijn de bouwblokken van tekst Ze worden gepresenteerd in verschillende stijlen en groottes. De ontwerpstijl van een verzameling karakters heet lettertype of font Gewone fonts zijn Arial, Century, Courrier, enz Ze varieren in verschijning: zwart, schuin, onderstreept, enz Karaktergrootte wordt gemeten in inches en pica’s (punten)
Scan-conversie: karakter 2 basis benaderingen: 1. Raster of bitmap font. Ieder karakter is een verzameling pixels in een bilevel raster patroon (bitmap) zie fig 3-20 Dit is eenvoudig, ieder karakter is al geconverteerd en kan zo ingevoegd worden op een locatie in de bitmap.
Scan-conversie: karakter Er zijn aparte bitmaps nodig voor zwart, schuin, enz. Bovendien zijn schuine bitmaps overlappend in een beeld ( zie fig 3-21) Verder is de grootte van een bitmap afhankelijk van de resolutie.
Scan-conversie: karakter 2. Vector of omtrek font Hierbij worden grafische primitieven zoals lijnen en bogen gebruikt om de omtrek van het karakter te maken (zie fig 3-22) Het is minder compact, en kost veel executietijd voor scan-conversie
Scan-conversie: karakter Echter de vector font kan karakters maken van variable grootte, verschijning en orientatie De getransformeerde primitieven kunnen direct met scan-conversie bewerkt worden, zoals opvullen Of ze kunnen equivalente bitmaps produceren zoals bij 1) Dit verkort de executie tijd bij meerdere aanroepen