Sisältö. Luento 2: Tulostusprimitiivien toteutus GRAAFISTEN PRIMITIIVIEN TOTEUTUS. Piirtäminen rasteriruudulle. Suoran viivan vaatimukset

Samankaltaiset tiedostot
Luento 3: Tulostusprimitiivien toteutus

Luento 2: Viivan toteutus

Luento 6: Tulostusprimitiivien toteutus

Luento 2: 2D Katselu. Sisältö

Luento 2: Tulostusprimitiivit

Luento 3: 2D Katselu. Sisältö

Sisältö. Luento 6: Piilopinnat. Peruskäsitteet (jatkuu) Peruskäsitteitä. Yksinkertaisia tapauksia. Yksinkertaiset tapaukset jatkuu

Tekijä Pitkä matematiikka

2 Pistejoukko koordinaatistossa

Tekijä Pitkä matematiikka Pisteen (x, y) etäisyys pisteestä (0, 2) on ( x 0) Pisteen (x, y) etäisyys x-akselista, eli suorasta y = 0 on y.

Grafiikka 205. Tässä luvussa käsitellään geometriaa ja graafisia kohteita. Mukana on pääosin alkeisoperaatioita.

Käy vastaamassa kyselyyn kurssin pedanet-sivulla (TÄRKEÄ ensi vuotta ajatellen) Kurssin suorittaminen ja arviointi: vähintään 50 tehtävää tehtynä

Vanhoja koetehtäviä. Analyyttinen geometria 2016

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus

Yleistä vektoreista GeoGebralla

x 5 15 x 25 10x 40 11x x y 36 y sijoitus jompaankumpaan yhtälöön : b)


Ota tämä paperi mukaan, merkkaa siihen omat vastauksesi ja tarkista oikeat vastaukset klo 11:30 jälkeen osoitteesta

yleisessä muodossa x y ax by c 0. 6p

Ympyrä 1/6 Sisältö ESITIEDOT: käyrä, kulma, piste, suora

Juuri Kertaus Tehtävien ratkaisut Kustannusosakeyhtiö Otava päivitetty

Diplomi-insinööri- ja arkkitehtikoulutuksen yhteisvalinta 2017 Insinöörivalinnan matematiikan koe , Ratkaisut (Sarja A)

y=-3x+2 y=2x-3 y=3x+2 x = = 6

MAB3 - Harjoitustehtävien ratkaisut:

Luento 6: Piilopinnat ja Näkyvyys

Suorat ja tasot, L6. Suuntajana. Suora xy-tasossa. Suora xyzkoordinaatistossa. Taso xyzkoordinaatistossa. Tason koordinaattimuotoinen yhtälö.

Tekijä Pitkä matematiikka

Tekijä Pitkä matematiikka Suoran pisteitä ovat esimerkiksi ( 5, 2), ( 2,1), (1, 0), (4, 1) ja ( 11, 4).

Suora 1/5 Sisältö ESITIEDOT: vektori, koordinaatistot, piste

Ratkaisut vuosien tehtäviin

origo III neljännes D

Paraabeli suuntaisia suoria.

Yhtälön oikealla puolella on säteen neliö, joten r. = 5 eli r = ± 5. Koska säde on positiivinen, niin r = 5.

1 Ensimmäisen asteen polynomifunktio

Avaruuden kolme sellaista pistettä, jotka eivät sijaitse samalla suoralla, määräävät

Ratkaisut vuosien tehtäviin

Numeeriset menetelmät

Tekijä Pitkä matematiikka b) Kuvasta nähdään, että b = i 4 j. c) Käytetään a- ja b-kohtien tuloksia ja muokataan lauseketta.

Ellipsit, hyperbelit ja paraabelit vinossa

3 TOISEN ASTEEN POLYNOMIFUNKTIO

Luento 6: Geometrinen mallinnus

A-osio. Tehdään ilman laskinta ja taulukkokirjaa! Valitse tehtävistä A1-A3 kaksi ja vastaa niihin. Maksimissaan tunti aikaa suorittaa A-osiota.

T Vuorovaikutteinen tietokonegrafiikka Tentti

Ratkaisuja, Tehtävät

Toisen asteen käyrien ja pintojen geometriaa Ympyrän ja pallon ominaisuuksia

1. Olkoot vektorit a, b ja c seuraavasti määritelty: a) Määritä vektori. sekä laske sen pituus.

l 1 2l + 1, c) 100 l=0 AB 3AC ja AB AC sekä vektoreiden AB ja

4. Esittäminen ja visualisointi (renderöinti)

Laudatur 4 MAA4 ratkaisut kertausharjoituksiin

l 1 2l + 1, c) 100 l=0

MAB3 - Harjoitustehtävien ratkaisut:

MS-A0202 Differentiaali- ja integraalilaskenta 2 (SCI) Luento 1: Parametrisoidut käyrät ja kaarenpituus

Ympyrän yhtälö

MAA15 Vektorilaskennan jatkokurssi, tehtävämoniste

Geometriaa GeoGebralla Lisätehtäviä nopeasti eteneville

Tekijä Pitkä matematiikka Poistetaan yhtälöparista muuttuja s ja ratkaistaan muuttuja r.

Tehtävien ratkaisut

Kahden suoran leikkauspiste ja välinen kulma (suoraparvia)

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

MS-A0003/A0005 Matriisilaskenta Laskuharjoitus 2 / vko 45

Oppimateriaali oppilaalle ja opettajalle : GeoGebra oppilaan työkaluna ylioppilaskirjoituksissa 2016 versio 0.8

Preliminäärikoe Pitkä Matematiikka

3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö

Tietorakenteet ja algoritmit - syksy

Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla

4.1 Kaksi pistettä määrää suoran

MAA7 Kurssikoe Jussi Tyni Tee B-osion konseptiin pisteytysruudukko! Kaikkiin tehtäviin välivaiheet näkyviin! Laske huolellisesti!

3 Suorat ja tasot. 3.1 Suora. Tässä luvussa käsitellään avaruuksien R 2 ja R 3 suoria ja tasoja vektoreiden näkökulmasta.

KJR-C1001 Statiikka ja dynamiikka. Luento Susanna Hurme

Matikkaa KA1-kurssilaisille, osa 3: suoran piirtäminen koordinaatistoon

VEKTORIKARTTOJEN HYÖDYNTÄMINEN PAIKKATIETOSOVELLUKSISSA

Muutoksen arviointi differentiaalin avulla

Luento 9: Yhtälörajoitukset optimoinnissa

Pyramidi 4 Analyyttinen geometria tehtävien ratkaisut sivu 180 Päivitetty Pyramidi 4 Luku Ensimmäinen julkaistu versio

Geogebra -koulutus. Ohjelmistojen pedagoginen hyödyntäminen

Differentiaaliyhtälöryhmä

Osoita, että kaikki paraabelit ovat yhdenmuotoisia etsimällä skaalauskuvaus, joka vie paraabelin y = ax 2 paraabelille y = bx 2. VASTAUS: , b = 2 2

PRELIMINÄÄRIKOE PITKÄ MATEMATIIKKA

RATKAISUT a + b 2c = a + b 2 ab = ( a ) 2 2 ab + ( b ) 2 = ( a b ) 2 > 0, koska a b oletuksen perusteella. Väite on todistettu.

Helsingin, Itä-Suomen, Jyväskylän, Oulun, Tampereen ja Turun yliopisto Matematiikan valintakoe klo Ratkaisut ja pisteytysohjeet

Differentiaali- ja integraalilaskenta 3 Harjoitus 4/ Syksy 2017

MATEMATIIKAN PERUSKURSSI I Harjoitustehtäviä syksy Millä reaaliluvun x arvoilla. 3 4 x 2,

MATEMATIIKAN KOE, PITKÄ OPPIMÄÄRÄ HYVÄN VASTAUKSEN PIIRTEITÄ

Luento 6: Geometrinen mallinnus

Vektoriarvoiset funktiot Vektoriarvoisen funktion jatkuvuus ja derivoituvuus

Helsingin, Itä-Suomen, Jyväskylän, Oulun, Tampereen ja Turun yliopisto Matematiikan valintakoe klo 10 13

4 Yleinen potenssifunktio ja polynomifunktio

Insinöörimatematiikka D

Aloita Ratkaise Pisteytä se itse Merkitse pisteet saanut riittävästi pisteitä voit siirtyä seuraavaan osioon ei ole riittävästi

5 Rationaalifunktion kulku

811120P Diskreetit rakenteet

(b) = x cos x 1 ( cos x)dx. = x cos x + cos xdx. = sin x x cos x + C, C R.

Aluksi Kahden muuttujan lineaarinen yhtälö

Transkriptio:

Sisältö Tietokonegrafiikka / perusteet Tik-111.300/301 4 ov / 2 ov Suora ja ympyrä Antialiasointi Fill-algoritmit Point-in-polygon Luento 2: Tulostusprimitiivien toteutus Lauri Savioja 09/03 Primitiivien toteutus / 1 Primitiivien toteutus / 2 GRAAFISTEN PRIMITIIVIEN TOTEUTUS HUOM! Oletuksena on XY-koordinaatisto Piirtäminen rasteriruudulle Alkeisoperaationa: SetPixel ( x, y, color ) Suorien viivojen piirtäminen Malli piirturikynällä piirtämisestä Kynä on aina jossakin (CP = Current Position) Inkrementaaliset alkeisoperaatiot: PenUp / PenDown CP' = CP + (±1, ±1) -> 8 eri askelta Pisteet piirrettävissä missä järjestyksessä hyvänsä Koordinaatit suhteellisina määritellyn rasterin origoon nähden Primitiivien toteutus / 3 Primitiivien toteutus / 4 Laskennallisia vaatimuksia Nopea, eli kokonaislukuja yhteen- ja vähennyslaskuja shiftejä Hitaita asioita kertolaskut reaaliluvut kirjastofunktiot, esim. trigonometriset operaatiot Suora Suoran viivan vaatimukset Tasapaksu (tasainen intensiteetti) Portaaton Täsmällinen alku ja loppu Intensiteetti riippumaton pituudesta ja kulmakertoimesta Primitiivien toteutus / 5 Primitiivien toteutus / 6 1

Algoritmi suoran piirtämiseksi Suoran yhtälö y=ax+b Alkupiste (x o,y o ), loppupiste (x 1,y 1 ) DDA (Digital Differential Analyzer) - algoritmi Periaate: pisteitä suoralla voidaan laskea esim. janan päätepisteiden (p 1, p 2 ) avulla esitetystä parametrimuodosta p(t) = p 1 + t *?p = p 1 + t * (p 2 - p 1 ) ; t [0,1] x(t) = x 1 + t *?X y(t) = y 1 + t *?Y = y 1 + m * (t *?X) ; m =?Y /?X eli antamalla t:lle sopivia arvoja ja pyöristämällä lasketut koordinaatit. Primitiivien toteutus / 7 Primitiivien toteutus / 8 DDA (jatkuu) symmetrinen DDA : iteroidaan t-parametria riittävän pienin askelin, jotta kaikki "janalla olevat" (so. lähellä olevat) pisteet tulevat käytyä läpi. yksinkertainen DDA : iteroidaan yksikköaskelin sitä koordinaattia, jonka siirtymä on suurempi, esim. x increment = ±1 ja y increment = m, kun m < 1. heikkouksia: jakolasku alussa liukuluvut, pyöristys joka pisteessä procedure dda (x1, y1, x2, y2 : integer); var dx, dy, steps, k : integer; x_increment, y_increment, x, y : real; dx := x2 - x1; dy := y2 - y1; if abs(dx) > abs(dy) then steps := abs(dx); else steps := abs(dy); x_increment := dx / steps; y_increment := dy / steps; x := x1; y := y1; set_pixel (round(x), round(y)); for k := 1 to steps do x := x + x_increment; y := y + y_increment; set_pixel (round(x), round(y)) end DDA (koodina) Primitiivien toteutus / 9 Primitiivien toteutus / 10 SIGGRAPH diat Bresenhamin algoritmi DDA:ssa turhaa laskentaa, sillä yksi koordinaatti (esim. x) muuttuu aina kokonaisaskelin toisestakin koordinaatista (y) tarvitsee havaita vain muutos, ts. milloin pyöristys antaa eri arvon kuin edellisessä pisteessä. Johdetaan tehokkaampi algoritmi: tarkkaillaan pyöristysvirhettä nousevalla suoralla (0 <= m <= 1 ) x-arvo etenee kokonaisaskelin: round(x) - x = 0 y:n virhe vaihtelee: d = round(y) - y (-0.5,+0.5) merkitään viimeksi piirrettyä pistettä ( x', y' ) = ( round(x), round(y) ) = ( x, y+d ) seuraava piste on ( x+1, y+m ), joka pyöristettynä on round(x+1) = x' + 1 round(y+m) = y', jos d+m < 0.5 = y' + 1, jos d+m >= 0.5 Primitiivien toteutus / 11 Primitiivien toteutus / 12 2

Bresenham (jatkuu) riittää siis tarkkailla lausekkeen s = d + m -0.5 etumerkkiä ja päivittää sitä askelittain: alussa d := 0, eli s0 := m -0.5 joka kierroksella lisätään s := s + m, ja vähennetään s := s - 1, jos s > 0 (koska y' kasvaa yhdellä). siirrytään kokonaislukuihin skaalaamalla s tekijällä 2*dx : m = dy / dx p = 2*dx*s = 2*dx*d + 2*dy - dx eli alussa p0 := 2*dy - dx joka kierroksella p := p + 2*dy ja lisäksi aina kun p > 0: p := p - 2*dx. procedure bres_line (x1, y1, x2, y2 : integer); Bresenham PASCAL-kielisenä: var dx, dy, x, y, x_end, p, const1,const2 : integer; dx := abs(x1 - x2); dy := abs(y1 - y2); p := 2 * dy - dx; const1 := 2 * dy; const2 := 2 * (dy - dx); if x1 > x2 then { if x1 > x2 } end else x := x2; y := y2; x_end := x1 { if x1 <= x2 } x := x1; y := y1; x_end := x2 set_pixel(x, y); while x < x_end do end x := x + 1; if p < 0 then p := p + const1 else set_pixel(x, y) y := y + 1; p := p + const2 Primitiivien toteutus / 13 Primitiivien toteutus / 14 Bresenham (jatkuu) algoritmin edut: ei lainkaan jakolaskua eikä liukulukuja kertolasku vain tekijällä 2 (= bin.luvun sivuttaissiirto) Huom. algoritmi johdettu nousevalle suoralle, dx>0, m < 1. Jos dx < 0, vaihdetaan päätepisteet (p 1, p 2 ) keskenään, tai päivitetään x-arvoa -1:n askelin laskevalle suoralle, -1 < m < 0, vaihdetaan y:n askeleeksi -1 Jos m > 1, vaihdetaan x:n ja y:n roolit keskenään. KÄYRÄT VIIVAT suorien ohella tarvitaan usein myös käyriä: 2 käyrät (ympyrän, ellipsin, parabelin kaaret) splinit (myöhemmin tällä kurssilla) perusprimitiivi POLYLINE tuottaa vain suora-osaisia murtoviivoja, yleistetty primitiivi GDP tarkoitettu mm. käyrien piirtämiseen GDP:n parametrien tulisi pääsääntöisesti olla geometrisia pisteitä, ei esim. polynomiyhtälön kertoimia periaatteessa mikä hyvänsä käyrä voidaan approksimoida murtoviivalla, mutta tehokkaampaa on yleensä tuottaa käyrän pisteet suoraan sen määritelmästä Primitiivien toteutus / 15 Primitiivien toteutus / 16 Käyrät viivat (jatkuu) DDA-algoritmi ja Bresenhamin muunnelma siitä ovat helposti muunnettavissa monille käyrille sopiviksi, mutta on varottava äärellisestä differenssiaskeleesta aiheutuvaa virhettä. Esim. paraabeli voidaan esittää differentiaalimuodossa: y = ax 2 + b <=> dy = 2ax * dx, y(0) = b. Täsmällisen käyrän tuottavassa algoritmissa on otettava huomioon myös termi dx 2 :?y(0) =?x 2?y(n) =?y(n-1) + 2ax *?x Paraabeli koodi x := 0; y := b; dx := 1; dy := dx * dx; dy_const := 2 * a * dx; while x < xmax do x := x + dx; y := y + dy; set_pixel (round(x), round(y)) dy := dy + dy_const; Huom! kun ohitetaan piste, jossa dx = dy, pitäisi x:n ja y:n rooleja muuttaa siten, että askelletaan y:tä yhdellä ja lasketaan dx sen mukaan. Primitiivien toteutus / 17 Primitiivien toteutus / 18 3

Ympyränpiirtoalgoritmi Bresenhamin ympyränpiirtoalgoritmi symmetrian ansiosta riittää tarkastella vain kahdeksasosaa koko ympyrästä; loput pisteet saadaan vaihtamalla x:n ja y:n rooleja ja etumerkkejä (olettaen, että keskipiste on origossa): -x,y x,y -y,x y,x -y,-x y,-x -x,-y x,-y piirtäminen alkaa pisteestä (0,r) ja päättyy, kun x=y. Primitiivien toteutus / 19 Primitiivien toteutus / 20 y exact yi yi-1 Ympyrä (jatkuu) Tarkastellaan askelta i, jossa ollaan viimeksi piirretty piste (x i, y i ), ja seuraavaksi on pääteltävä kumpi pisteistä, (x i +1, y i ) vai (x i +1, y i 1), on lähempänä todellista käyrän pistettä (x i +1, y exact ) : d1 d2 Ympyrä (jatkuu) ympyrän yhtälöstä y 2 = r 2 x 2 saadaan: y exact2 = r 2 (x i + 1) 2, jota voidaan verrata vaihtoehtoisiin pisteisiin: d 1 = y i2 y exact 2 = y i 2 r 2 + (x i + 1) 2, d 2 = y exact2 (y i - 1) 2 = r 2 (x i + 1) 2 (y i - 1) 2 p i = d 1 d 2 = 2(x i + 1) 2 + y i2 + (y i - 1) 2 2r 2 valitaan se piste, jonka etäisyys oikeasta on pienempi, eli jos parametri p i < 0, niin valitaan arvo y i, muuten arvo (y i - 1). xi xi+1 Primitiivien toteutus / 21 Primitiivien toteutus / 22 Ympyrä (jatkuu) Parametrin p arvo seuraavassa pisteessä (x i +1, y i+1 ) voidaan laskea iteratiivisesti edellisessä pisteessä lasketusta arvosta. Edellä laskettua lauseketta muokkaamalla saadaan: p i+1 = 2[(x i +1) + 1] 2 + y 2 i+1 + (y i+1-1) 2 2r 2 = p i + 4x i + 6 + 2(y i +12 - y i2 ) 2(y i+1 - y i ) = p i + 4x i + 6, jos y i+1 = y i = p i + 4x i + 6 4y i + 4, jos y i+1 = y i + 1 aloituspisteessä (0, r) lauseke on: p 1 = 3 2r. procedure bres_circle (x_center, y_center, radius : integer); var p, x, y : integer; procedure plot_circle_points; { 8 symmetric positions } set_pixel(x_center + x, y_center + y); set_pixel(x_center - x, y_center + y); set_pixel(x_center + x, y_center - y); set_pixel(x_center - x, y_center - y); set_pixel(x_center + y, y_center + x); set_pixel(x_center - y, y_center + x); set_pixel(x_center + y, y_center - x); set_pixel(x_center - y, y_center - x) Ympyräkoodi Primitiivien toteutus / 23 Primitiivien toteutus / 24 4

Ympyräkoodi (jatkuu) { bres_circle } x := 0; y := radius; p := 3-2 * radius; while x < y do plot_circle_points; if p < 0 then p := p + 4 * x + 6 else p := p + 4 * (x- y) + 10; y := y - 1; x := x + 1; end if x = y then plot_circle_points; Aliasoituminen l. vieraantumisongelma rasteriviivojen piirtämisessä piirtosuunta vaikuttaa viivan tiheyteen tiheys = 8 / (8 * 2) tiheys = 8 / 8 viivan leveys voi olla vain kokonaisluku xy-suunnissa vinon viivan reuna on porrasmainen (jagged) HUOM! Sama ongelma koskee myös muita graafisia kuvioita. Primitiivien toteutus / 25 Primitiivien toteutus / 26 Antialiasointi-diat Antialiasointi Antialiasointi = vieraantumisongelman ehkäiseminen tavallisin menetelmä on kunkin pikselin sävyttäminen sen mukaan, kuinka suurelta osin piirrettävä kuvio peittää sitä: Primitiivien toteutus / 27 Primitiivien toteutus / 28 Antialiasointi (jatkuu) viivan reunat sumenevat, mutta keskimäärin tasoittuvat mahdollista vain sävynäytöllä (ei mustavalkealla) erityislaitteilla mahdollista pikselien hienosäätö (pixel phasing): porraskohdissa olevia pikseleitä siirretään lähemmäs oikeaa viivaa pikselien suuruutta säädetään viivan kaltevuuden mukaan ALUEEN TÄYTTÄMINEN Kaksi perusperiaatetta: 1) konversio janoiksi pyyhkäisyjuoville 2) värin levittäminen rasterissa Primitiivien toteutus / 29 Primitiivien toteutus / 30 5

Juovakonversio etsitään kultakin pyyhkäisyjuovalta ne janat, jotka jäävät monikulmioalueen sisälle y1 y2 y3 y4 y5 y6 y7 y8 Juovakonversio (jatkuu) voidaan laskea joka juovalle (y=vakio) toisistaan riippumatta, missä kohdissa (x-arvo) juova leikkaa monikulmion reunan tehokkaampaa, jos hyödynnetään koherenssia (so. vierekkäisten juovien samankaltaisuutta): saman reunajanan perättäiset leikkauspisteet juovien kanssa voidaan laskea inkrementaalisesti, kuten janan rasteroinnissa (DDA, Bresenham) kutakin juovaa leikkaa vain osa janoista; likimain sama aktiivinen janajoukko leikkaa myös seuraavaa juovaa (samassa x- järjestyksessä) singulariteettiongelma: montako leikkausta lasketaan, jos pyyhkäisyjuova kulkee monikulmion nurkan kautta? ratkaistaan tarkastelemalla janojen suuntia... x = 1 2 3 4 5 6 87 9 10 Primitiivien toteutus / 31 Primitiivien toteutus / 32 Algoritmin runko TYPE points = ARRAY[1..max_points] OF integer; PROCEDURE fill_area_solid (count : integer; x, y : points); TYPE each_entry = RECORD y_top : integer; {larger y coordinate for line} x_int : real; {x that goes with larger y} delta_y : integer; {difference in y coordinates} x_change_per_scan: real {x change per unit change in y} ; list = ARRAY[0..max_points] OF each_entry; VAR sides : list; first_s, last_s, scan, bottomscan, x_int_count, r : integer; {fill_area_solid} sort_on_bigger_y(count, x, y, sides, bottomscan); first_s := 1; last_s := 1; {initialize pointers into sorted list} FOR scan := sides[1].y_top DOWNTO bottomscan DO update_first_and_last(sides, count, scan, first_s, last_s); process_x_intersections(sides, scan, first_s, last_s, x_int_count); draw_lines(sides, scan, x_int_count, first_s); update_sides_list(sides, first_s, last_s) ; {fill_area_solid} PROCEDURE sort_on_bigger_y (n : integer; x, y : points; VAR sides : list; VAR bottomscan : integer); VAR k, x1, y1, xpix, side_count : integer; FUNCTION next_y (k : integer) : integer; VAR i : integer; {returns next vertex y value which is not equal to y[k]} FOR i := k TO n DO IF y[i] <> y[k] THEN next_y := y[i]; ; Tietorakenteen pohjustus: PROCEDURE put_in_sides_list (VAR sides : list; entry, x1, y1, x2, y2, next_y : integer); VAR maxy : integer; x2_temp, x_change_temp : real; {make adjustments for problem vertices} x_change_temp := (x2 -x1) / (y2 -y1); x2_temp := x2; IF (y2 > y1) AND (y2 < next_y) THEN y2 := y2-1; x2_temp := x2_temp - x_change_temp ELSE IF (y2 < y1) AND (y2 > next_y) THEN y2 := y2 + 1; x2_temp := x2_temp + x_change_temp ; WHILE (entry > 1) AND (maxy > sides[entry -1].y_top) DO sides[entry] := sides[entry - 1]; entry := entry - 1 ; WITH sides[entry] DO {insert into sides list} y_top := maxy; delta_y := abs(y2 - y1) + 1; IF y1 > y2 THEN x_int := x1; maxy=y1; ELSE x_int := x2_temp; maxy:=y2 ; ; x_change_per_scan := x_change_temp {put_in_sides_list} samalla, kun järjestetään janat y -koordinaatin mukaan, ennaltaehkäistään singulariteettiongelmat lyhentämällä kuhunkin nurkkapisteeseen tulevaa janaa loppupäästään Primitiivien toteutus / 33 Primitiivien toteutus / 34 Tietorakenteen pohjustus (jatkuu) Aktiivisen janajoukon rajaaminen: F B Top scanline {sort_on_bigger_y} side_sount := 0; y1 := y[n]; x1 := x[n]; {initialize} bottomscan := y[n]; FOR k := 1 TO n DO IF y1 <> y[k] THEN {put non- horizontal edges in table} side_count := side_count + 1; {pass old point, current point, and y of next non-horizontal point} put_in_sides_list(sides, side_count, x1, y1, x[k], y[k], next_y(k)) ELSE {horizontal} FOR xpix := x1 TO x[k] DO setpixel (xpix, y1, fillcolor); IF y[k] < bottomscan THEN bottomscan := y[k]; y1 := y[k]; x1 := x[k] {save for next side} ; {sort_on_bigger_y} PROCEDURE update_first_and_last (sides : list; count, scan : integer; VAR first_s, last_s : integer); WHILE (sides[last_s + 1].y_top >= scan) AND (last_s < count) DO last_s := last_s + 1; WHILE sides[first_s].delta_y = 0 DO first_s := first_s + 1 ; E G A D C Scan line i AB BC EF FG GA CD DE Sorted Edge List Scan line i+1 first_s last_s Primitiivien toteutus / 35 Primitiivien toteutus / 36 6

VAR tmp : each_entry; tmp := s1; s1 := s2; s2 := tmp ; Leikkauspisteiden laskenta aktiivisille janoille: PROCEDURE process_x_intersections (sides : list; scan, first_s, last_s : integer; VAR x_int_count : integer); VAR k : integer; PROCEDURE swap(s1, s2 : each_entry); {swap reverses placement of two entries within the table sides} PROCEDURE sort_on_x (entry, first_s : integer); WHILE (entry > first_s) AND (sides[entry].x_int < sides[entry -1].x_int) DO swap(sides[entry], sides[entry - 1]); entry := entry - 1 ; {sort_on_x} {process_x_intersections} x_int_count := 0; FOR k := first_s TO last_s DO IF sides[k].delta_y > 0 THEN x_int_count := x_int_count + 1; sort_on_x(k, first_s) ; {process_x_intersections} Sisään jäävien juovan osien tulostaminen: PROCEDURE draw_lines (sides : list; scan, x_int_count, index : integer); VAR k, x, x1, x2 : integer; FOR k := 1 TO round(x_int_count / 2) DO ; {draw_lines} WHILE sides[index].delta_y = 0 DO index := index + 1; x1 := round(sides[index].x_int); index := index + 1; WHILE sides[index].delta_y = 0 DO index := index + 1; x2 := round(sides[index].x_int); index := index + 1; FOR x := x1 TO x2 DO set_pixel(x, scan, fill_color); index := index + 1 Primitiivien toteutus / 37 Primitiivien toteutus / 38 Aktiivisen janalistan päivitys: Päällekkäiset monikulmiot: prioriteettijärjestys PROCEDURE update_side_list (VAR sides : list); VAR k : integer; B B FOR k := first_s TO last_s DO WITH sides[k] DO IF delta_y > 0 THEN {determine next x_int, decrease delta_y} scan line delta_y := delta_y - 1; x_int := x_int - x_change_per_scan A C A C ; {update_side_list} päällekkäisyysjärjestys eri osissa pyyhkäisyjuovaa: A B C C C A B B A Yleinen koherenssiperiaate: geometristen objektien järjestäminen Y-suunnassa (pyyhkäisyjuovittain) X-suunnassa (kunkin juovan sisällä) P-suunnassa (prioriteetti eli "syvyys") saa aikaan sen, että joudutaan kulloinkin vertailemaan vain pienelläaktiivisella alueella olevia objekteja keskenään. Primitiivien toteutus / 39 Primitiivien toteutus / 40 Päällekkäisyys (jatkuu) Eri tekijöiden (XYP) käyttöjärjestys tuottaa eri algoritmeja, vaikuttaen tietorakenteeseen ohjelman tehokkuuteen / monimutkaisuuteen tulosten havainnollisuuteen (kasvaako kuva ylhäältä alas vai takaa eteenpäin) Näitä piilopinta-algoritmeja käsitellään kirjan luvussa 13 ja myöhemmällä luennolla. Rekursiivinen 4-naapurusto ja 8-naapurusto Reunojen määrittely? Mustetippa-algoritmi void boundaryfill(int x, int y, int fill, int boundary) { int current; } current = getpixel(x, y); if ((current!= boundary) && (current!= fill)) { setcolor(fill); setpixel(x, y); boundaryfill(x+1, y, fill, boundary); boundaryfill(x-1, y, fill, boundary); boundaryfill(x, y+1, fill, boundary); boundaryfill(x, y-1, fill, boundary); } Primitiivien toteutus / 41 Primitiivien toteutus / 42 7

Pisteen sijainti alueen suhteen Usein tarvitaan tietoa siitä, kuuluuko annettu piste mallin määrittämään alueeseen. Eri esitystavoille voidaan käyttää erilaisia menetelmiä: suoraan sijoittamalla koordinaatit epäyhtälöön esim. piste (2, 3) on 10-säteisen ympyrän sisällä: 2 2 2 + 3 < 2 10 vertaamalla avaruusjakoon ja luetteloon alueen soluista tutkimalla ovatko pisteen parametrit rajatuilla väleillä edellyttää parametrikuvauksen käänteismuunnosta 1 f : ( x, y, z) ( u, v) tutkimalla geometrisesti, onko piste reunan sisä- vai ulkopuolella Point-in-polygon Odd-even rule, scan-line Asetetaan ääretön puolisuora tutkittavast pisteestä lähtien ja lasketaan sen leikkauspisteet alueen reunaviivan (tai pinnan) kanssa. Koska äärettämän kaukana oleva puolisuoran pää on alueen ulkopuolella ja reunan ylitys merkitsee aina siirtymistä joko ulkoa sisään tai sisältä ulos, niin pariton määrä leikkauksia merkitsee pisteen olevan alueen sisällä n=1 n=3 n=4 Primitiivien toteutus / 43 Primitiivien toteutus / 44 Point-in-polygon Normaalivektorit ristituloilla, vektorien suunnat Ongelmatapaukset itseään leikkaavat tai sulkeutumattomat reunat Primitiivien toteutus / 45 8