Computergraphik Grundlagen
XI. Rasterung – Füllen von Polygonen
Prof. Stefan Schlechtweg Hochschule Anhalt Fachbereich Informatik
Inhalt – Lernziele
1. Zu lösendes Problem 2. Füllen von
Pixelmengen
1. Rekursiver Algorithmus
3. Füllen von Polygonen
1. Einstieg: Füllen von Rechtecken
2. Begriffe und Definitionen 3. Iterativer Algorithmus 4. Zusammenfassung
4. Füllen mit Mustern
Füllen als computergraphisches Grundproblem kennenlernen
Algorithmus zum Füllen auf Pixelbasis kennenlernen
Iterativen Algorithmus zum Füllen von Polygonen, die durch Kanten gegeben sind, verstehen
Probleme beim Füllen – auch mit Mustern – identifizieren können
lokal → Welt Lokale Koordinaten
Modellierung der Geometrie einzelner Objekte
Weltkoordinaten Plazierung der
Objekte
Plazierung der Lichtquellen Plazierung der
Kamera Beleuchtungs-
berechnung
Kamerakoordinaten Entfernen verdeckter Rückseiten
Normalisierte Projektionskoordinaten
Clipping gegen Sichtkörper
(Normalisierte) Bildschirm- koordinaten
Rasterkoordinaten
Entfernen verdeckter Modellteile
Shading Entfernen verdeckter Modellteile
Transformation in Kamerakoordinaten
Viewing-Transformation
Projektion
Rastertransformation Rasterung
1. Zu lösendes Problem
Polygon gegeben durch
– Geometrische Beschreibung (Ecken, Kanten)
– Pixelmenge (entsteht durch Rasterung der Kanten)
Fragen:
– Welche Pixel bilden das Innere der Fläche und sind daher einzufärben, wenn die Fläche gefüllt werden soll?
– Womit (welche Farbe) sind die Pixel zu füllen?
Füllalgorithmen für:
– Polygone, deren Rand als Pixelmenge gegeben ist, – Polygone, die durch Kanten gegeben sind
2. Füllen von Pixelmengen
Gegeben:
– gerasterte Polygone als Rand-„Pixelmenge“
– „Startpunkt“, der festlegt, wo innen ist
Gesucht: alle Pixel innerhalb des Randes
Begriff: Nachbarschaften
4-Nachbarschaft
(von-Neumann-Nachbarschaft)
8-Nachbarschaft
2. Füllen von Pixelmengen
2.1. Rekursiver Algorithmus
Bestimmung der Zugehörigkeit zum Rand erfolgt über Pixelfarbe, daher einfarbiger Rand
Beginne mit einem Startpixel
Teste, ob das aktuelle Pixel auf dem Rand liegt ( getPixel(x,y) )
– wenn ja, dann ist nichts zu füllen
– wenn nein, dann fülle die {4er, 8er}-Nachbarschaft
void floodFill( int x, int y, int fillColor, int border) {
if ((getPixel(x, y) == border) ||
(getPixel(x, y) == fillColor)) {return;}
setPixel( x, y, fillColor);
// 4-Nachbarschaft
floodFill( x, y+1, fillColor, border);
floodFill( x, y-1, fillColor, border);
floodFill( x+1, y, fillColor, border);
floodFill( x-1, y, fillColor, border);
}
2. Füllen von Pixelmengen
2.1. Rekursiver Algorithmus
Probleme:
Rekursion → hoher Berechnungsaufwand
mehrfaches Testen von Pixeln
„spill-out“ bei Lücken in den Rändern
Rand bei Verwendung der 8-Nachbarschaft muss auch diagonal dicht definiert sein
Vorteile:
Es muss nichts über die Geometrie des zu füllenden Gebietes bekannt sein!
Keine langwierigen Berechnungen
2. Füllen von Pixelmengen
2.1. Rekursiver Algorithmus
3. Füllen von Polygonen
Füllalgorithmen auf Basis einer geometrischen Beschreibung
Füllen von Polygonen, die definiert sind durch
– Liste von Eckpunkten {V} und dazwischen liegenden Kanten {E}
– Kante von vi zu Eckpunkt vi+1 für ∀i: 1 < i < n – Kante von vn nach v1 schließt das Polygon
Konvexe Polygone: Wenn P1 und P2 zum Polygon gehören, gehören auch alle Punkte auf der Verbindung zwischen P1 und P2 zum Inneren des Polygons
Konkave Polygone: ... Auch mit Selbstüberschneidungen
3. Füllen von Polygonen
3.1. Einstieg: Füllen von Rechtecken
Füllen mit einheitlicher Farbe
Rechteck definiert durch zwei Ecken (xmin, ymin) und (xmax, ymax)
Algorithmus:
for (y=y
min; y<=y
max; y++)
for (x=x
min; x<=x
max; x++)
setPixel (x, y, color);
Definition:
– Pixel auf einer Kante gehören nicht zum Primitiv, wenn die durch die Kante definierte Halbebene, die das Primitiv enthält, unter dieser Kante oder links von ihr liegt.
– Pixel auf einer Kante gehören zum Primitiv, wenn die Halbebene, die das Primitiv enthält, oberhalb oder rechts liegt.
gehört zum Primitiv
gehört nicht zum Primitiv
3. Füllen von Polygonen
3.2. Begriffe und Definitionen
Kante: Verbindung zweier Eckpunkte
Scanlinie: horizontale Linie auf Höhe einer Rasterzeile
Spanne: Abschnitt auf einer Scanlinie zwischen zwei
Schnittpunkten mit Polygonkanten
3. Füllen von Polygonen
3.2. Begriffe und Definitionen
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
Abtasten (Scannen) des Polygons Pixelzeile (Scanline) für Pixelzeile von unten nach oben
Suche alle Schnittpunkte der Scanlines mit Polygonkanten
Sortiere die Schnittpunkte nach wachsenden x-Koordinaten
Fülle alle Pixel zwischen Schnittpunkten nach Parität:
Parität ist anfangs 0 und wechselt bei jedem
Schnittpunkt. Gezeichnet wird bei Parität 1.
A
C D
E F
a b c d Scanline
2 3 4 5 6 7 9 8 10 11
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
Überlegungen/Sonderfälle
Wie bestimmt man für einen nicht-ganzzahligen Schnittpunkt, welches der beiden Nachbarpixel innen liegt?
Erreicht man den Schnittpunkt, während man „innen“ ist, wird abgerundet, während man „außen“ ist, wird aufgerundet.
Wie verfährt man mit Schnittpunkten an ganzzahligen Pixelkoordinaten?
Ein ganzzahliger Schnittpunkt wird am Beginn einer Spanne als
„innen“; am Ende einer Spanne als „außen“ betrachtet.
Wie verfährt man mit doppelt belegten Schnittpunkten?
Der ymin-Wert einer Kante wird als zugehörig, der ymax-Wert einer Kante als nicht zugehörig betrachtet.
Wie verfährt man mit horizontalen Kanten?
Untere Kanten werden dargestellt, obere nicht.
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
Voraussetzungen:
– Aufbau einer Kantentabelle (edge table, ET) für alle Kanten – Pro Kante wird notiert:
ymin= unterer y-Wert
xstart= x-Wert an dem Punkt mit ymin (kann größerer x-Wert sein!) ymax= oberer y-Wert
t=dx/dy=horizontaler Versatz zwischen zwei Scanlines (entspricht 1/Anstieg)
Kante ymin xstart ymax dx/dy
AB 1 7 3 -5/2
BC 1 7 5 6/4
FA 3 2 9 0
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 6/4
A
B
C D
E F
11 9 7 5 3 1 y
← (2-7)/(3-1)
←(13-7)/(5-1)
← 0/6
← 0/6
← (2-7)/(9-7)
← (13-7)/11-7)
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
Algorithmus iteriert über Scanlinien und baut eine Aktivkantentabelle (active edge table, AET) auf.
AET enthält nach wachsenden x-Werten sortierte Schnittpunkte von Scanlinien mit Polygonkanten.
Spannen zwischen Paaren von solchen Schnittpunkten (Einträge in der AET) werden gefüllt.
AET wird beim Übergang zur nächsten Scanlinie aktualisiert.
Algorithmus endet, wenn AET leer ist
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
1. Weise y den kleinsten in der ET vorkommenden Wert zu
2. Initialisiere die AET mit dem Anfangszustand „leer“
3. Wiederhole bis ET und AET leer sind
a) Überführe aus der ET diejenigen Einträge in die AET, für die ymin=y ist und sortiere die AET nach x
b) Fülle die Pixel in der Scanlinie y durch Nutzung von Koordinatenpaaren der AET
c) Entferne aus der AET alle die Einträge mit ymax=y d) Inkrementiere y (nächste Scanlinie)
e) Aktualisiere für jede nicht vertikale Kante (dx/dy !=0) der AET
3. Füllen von Polygonen
3.3. Iterativer Algorithmus
Kante ymin xstart ymax dx/dy
AB 1 7 3 -5/2
BC 1 7 5 3/2
FA 3 2 9 0
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
A
B
C D
E F
Kante ymin xstart ymax dx/dy
AB 1 7 3 -5/2
BC 1 7 5 3/2
Beide Male ist 1 der ymin-Wert einer Kante, daher zeichnen
Kante ymin xstart ymax dx/dy AB 1 9/2 3 -5/2
BC 1 17/2 5 3/2
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
Füllen zwischen den beiden Einträgen - (9/2, 2) aufrunden (außen) (5,2) - (17/2, 2) abrunden (innen) (8,2)
Kante ymin xstart ymax dx/dy AB 1 4/2 3 -5/2
BC 1 20/2 5 3/2
2 7 13 x 11
9 7 5 3 1
A
C D
E F
11 9 7 5 3 1
2 7 13 x
Kantentabelle (ET) AET (Scanline 1)
Kantentabelle (ET)
AET (Scanline 3) AET (Scanline 2)
A
C D
E F
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
AB 1 4/2 3 -5/2 BC 1 20/2 5 3/2 - Kante FA in die AET überführen - Füllen zwischen den beiden letzten Einträgen, dabei ist erster Punkt als innen, letzter als außen betrachtet - Kante AB entfernen
Kante ymin xstart ymax dx/dy
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
- Füllen zwischen beiden Einträgen, (23/2) auf (11) abrunden
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
BC 1 23/2 5 3/2
2 7 13 x 11
9 7 5 3 1 y
AET (Scanline 3)
AET (Scanline 4)
A
C D
E F
2 7 13 x 11
9 7 5 3 1 y
A
D
E F
A
C D
E F
Kante ymin xstart ymax dx/dy
CD 5 13 11 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
- Kante CD in die AET überführen - Füllen zwischen den ersten beiden Einträgen, dabei wird (26/2, 5) als außen betrachtet
- Kante BC entfernen
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
BC 1 26/2 5 3/2
CD 5 13 11 0
Kante ymin xstart ymax dx/dy
EF 7 7 9 -5/2
DE 7 7 11 3/2
Füllen zwischen den beiden Einträgen, dabei wird (13, 6) als außen betrachtet
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
CD 5 13 11 0
2 7 13 x 11
9 7 5 3 1 y
AET (Scanline 6) AET (Scanline 5)
A
D
E F
Kante ymin xstart ymax dx/dy
EF 7 7 9 -5/2
DE 7 7 11 3/2
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
EF 7 7 9 -5/2
DE 7 7 11 3/2
CD 5 13 11 0
- Kanten DE und EF in die AET überführen - Füllen zwischen den ersten beiden Ein- trägen. (7, 7) wird als außen betrachtet.
- Füllen zwischen den letzten beiden Ein- trägen. (13, 7) wird als außen betrachtet.
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
EF 7 9/2 9 -5/2 DE 7 17/2 11 3/2
CD 5 13 11 0
2 7 13 x 11
9 7 5 3 1 y
AET (Scanline 7)
AET (Scanline 8)
A
D
E F
2 7 13 x 11
9 7 5 3 1 y
Kante ymin xstart ymax dx/dy
-- -- -- -- --
Kante ymin xstart ymax dx/dy
FA 3 2 9 0
EF 7 4/2 9 -5/2 DE 7 20/2 11 3/2
CD 5 13 11 0
AET (Scanline 9)
A
D
E F
Kante ymin xstart ymax dx/dy
-- -- -- -- --
2 7 13 x 11
9 7 5 3 1 y
- Füllen zwischen den ersten beiden Einträgen, dabei wird (2, 9) nicht gesetzt, da er ymax zweier Kanten ist.
- Füllen zwischen den letzten beiden Einträgen, dabei wird (13, 9) als außen betrachtet
- Entfernen von FA und EF
A
D
E
Kante ymin xstart ymax dx/dy DE 7 23/2 11 3/2
CD 5 13 11 0
Kante ymin xstart ymax dx/dy
-- -- -- -- --
- Füllen zwischen beiden Einträgen, dabei wird (23/2, 10) zu (12, 10) aufgerundet und (13, 10) als außen betrachtet
11 9 7 5 3 1 y
2 7 13 x
AET (Scanline 10)
Kante ymin xstart ymax dx/dy DE 7 26/2 11 3/2
CD 5 13 11 0
AET (Scanline 11)
A
D
E
2 7 13 x 11
9 7 5 3 1 y
- Der Pixel (13, 11) wird nicht gesetzt, da er ymax zweier Kanten ist
- Kanten DE und CD entfernen
Kante ymin xstart ymax dx/dy
-- -- -- -- --
Kante ymin xstart ymax dx/dy
Kante ymin xstart ymax dx/dy
AET (Scanline 12)
A
D
E
2 7 13 x 11
9 7 5 3 1 y
A
E
3. Füllen von Polygonen
3.4. Zusammenfassung
Eigenschaften:
Effizienter Algorithmus
Beliebige Polygone (auch konkave)
Vereinfachung für konvexe Polygone möglich (immer nur eine Spanne)
Performance-Gewinn durch
– Schnelles Sortieren
– Integer-Arithmetik (beim Addieren von dx/dy)
Wird häufig angewendet, u.a. beim Shading in der 3D-
4. Füllen mit Mustern
Muster als Bitmap (Textur = 2D Bild) gegeben, soll in das Innere eines Polygons übertragen werden
Keine einheitliche Farbe, daher direkte Zuordnung zu
füllendes Pixel auf Texturpixel notwendig
Verankerung der linken unteren Textur-Ecke in einer Polygonecke
– Muster ist mit Polygon verbunden, bewegt sich bei Animationen mit dem Polygon
Verankerung der Textur auf dem Hintergrund
– Muster nicht mit Polygon verbunden, Polygon bewegt sich „über“
der Textur
– Belegen der Polygonpixel mit dem Wert 1 und logische UND- Verknüpfung mit dem Muster
4. Füllen mit Mustern
Einfache Erweiterung der Füllalgorithmen
– Keine einheitliche Farbe
– stattdessen: Lookup der Pixelfarbe in der Textur
– Verknüpfen der Texturfarbe mit der Hintergrundfarbe in verschiedenen Modi:
• Farben verknüpfen (Interpolation, verschiedene Verfahren)
• Textur-Farbwert für weitere Berechnungen verwenden
Verwendung beim Rendering:
– Shading in Verbindung mit Texturierung – Texture Mapping, Bump Mapping, etc.