Dr. O. Hoffmann
Ordnung ist die Tochter der Überlegung.
Georg Christoph Lichtenberg
In SVG bestimmt die Zeichenreihenfolge
der Elemente im Quelltext, welches Element unten
und welches oben ist. Was zuletzt im Quelltext steht, ist oben und verdeckt bei einer
Überlappung weiter vorne im Quelltext stehende Elemente. Leider ist der aus
CSS bekannte z-index
nicht in
SVG übernommen worden, so daß der
Autor selbst die Reihenfolge im Quelltext sortieren muß. Das ist einige Arbeit und
erfordert eine gewisse Überlegung, beinhaltet aber solange kein technisches Problem,
wie es nicht mindestens zwei Objekte gibt, die jeweils nur teilweise vor dem jeweils anderen
zu malen sind, der andere Teil aber dahinter liegen soll. Da sind Tricks, Handarbeit und
noch mehr Überlegung gefordert. Einfache Beispiele sollen hier angegangen werden.
Viel problematischer ist das Fehlen eines Werkzeuges wie z-index
allerdings auf den Inhalt bezogen. Der Autor ist gezwungen, sich bei der Reihenfolge der Anordnung danach
zu richten, wie die Dinge nachher visuell erscheinen sollen, nicht wie sie inhaltlich sinnvoll
zusammenpassen. Das kann ganz praktisch eine deutliche Qualitätseinbuße
hinsichtlich der Barrierefreiheit und Zugänglichkeit des Dokumentes sein. In der
Hinsicht kann allenfalls optimiert werden, wenn der Inhalt innerhalb eines defs
-Bereiches
in einer inhaltlich sinnvollen Reihenfolge definiert wird und anschließend mit
dem Element use
in der notwendigen Zeichenreihenfolge referenziert wird.
In einfachen Situationen kann es auch helfen, ein im Quelltext früher auftretendes Element als Maske oder Ausschnitt für spätere Elemente zu verwenden, damit es nicht verdeckt wird.
SVG 1.1 bietet nicht direkt die Möglichkeit, die Reihenfolge von
stroke
und fill
zu tauschen.
Um dies zu erreichen, ist einfach die gleiche Form zweimal zu verwenden,
einmal nur mit Füllung und ohne Strich und einmal mit Strich und ohne Füllung,
wobei dann jeweils die Variante mit Füllung hinter die mit Strich gesetzt wird.
Füllung und Strich tauschen
(Quelltext zu Füllung und Strich tauschen).
Links sieht man den Effekt ohne Opazität, in der Mitte und rechts mit Opazität.
Rechts wird zudem das Element per use wiederverwendet,
was insbesondere bei komplizierteren Pfaden sinnvoll ist
oder wenn die Reihenfolge per Animation geändert werden soll
(wozu man dann am einfachsten diese use
-Elemente mit weiteren,
animierten use
-Elementen
zeitabhängig referenziert.
SVG 1.1 bietet nicht direkt die Möglichkeit, verschiedene Elemente zu
einer Form zu vereinen, was hinsichtlich der Zeichenreihenfolge unerwünschte
Effekte haben kann.
Um dieses vorzutäuschen, bietet es sich an, die zu vereinenden Elemente zu gruppieren und
diese Gruppe per use
zu referenzieren.
Formen scheinbar vereinen
(Quelltext zu Formen scheinbar vereinen).
Um dieses vorzutäuschen, bietet es sich an, die zu vereinenden Elemente zu gruppieren und
diese Gruppe per use
zu referenzieren.
Statt fill
und stroke
beide zu setzen (links),
ist es vorteilhafter, die Gruppe zweimal zu referenzieren und dann
einmal nur mit Füllung und Opazität zu nutzen und einmal nur mit Strich und Opazität.
Die Reihenfolge der beiden Kopien im Quelltext entscheidet dann darüber,
ob die Füllung der Vereinigung vor dem Strich dargestellt wird oder dahinter
(Mitte und rechts).
Bei der Verwendung von mehreren Farben kann man immerhin mit einem ähnlichen Trick immer noch
Füllung und Strich tauschen, diese untereinander bei unterschiedlichen Farben zu tauschen, ist natürlich
nicht so einfach.
Formen scheinbar vereinen (unterschiedliche Füllungen)
(Quelltext zu Formen scheinbar vereinen (unterschiedliche Füllungen)).
Formen scheinbar vereinen (unterschiedliche Striche)
(Quelltext zu Formen scheinbar vereinen (unterschiedliche Striche)).
Formen scheinbar vereinen (unterschiedliche Füllungen und Striche)
(Quelltext zu Formen scheinbar vereinen (unterschiedliche Füllungen und Striche)).
Das Thema kann man natürlich noch weiter variieren und verfeinern. Weitergehende Möglichkeiten gibt es natürlich durch die Kombination mit Masken.
Als erstes Beispiel gucken wir uns eine Gerade an, die die Zeichenebene
zu schneiden scheint, ein Teil befindet sich über der teiltransparenten
Zeichenebene, ein Teil darunter. Sei a ein Punkt der Geraden und
b ein anderer auf der anderen Seite der Zeichenebene.
Die Zeichenebene sei bei z = 0. Ein Punkt des zu zeichnenden
Geradestückes ist offenbar mit t aus [0, 1]
G = (1 - t) a + t b
Der Schnittpunkt liegt bei
t = az / (az - bz)
Zuerst wird der Teil der Gerade unter der Zeichenebene gemalt, dann das teiltransparente
Stück der Zeichenebene und dann der Teil der Gerade über der Zeichenebene.
Schnittpunkt Gerade und Ebene 1
(Quelltext zum
Schnittpunkt Gerade und Ebene 1).
Ist hingegen der Schnittpunkt bekannt, nehmen wir an, es ist der Nullpunkt und a
ein Punkt außerhalb der Ebene, so ist mit einem Faktor f größer Null:
b = -f a
Schnittpunkt Gerade und Ebene 2
(Quelltext zum
Schnittpunkt Gerade und Ebene 2).
Es ist nur das farbige Stück der Zeichenebene teiltransparent, der Rest ist komplett
transparent. Schneidet die Gerade also den teiltransparenten Teil nicht, so liegt natürlich
wieder die Originalfarbe vor.
Nun wollen wir vier Rechtecke verkeilen. Vier teiltransparente
symmetrisch angeordnete Rechtecke liegen
so, daß eine Ecke eines Rechtecks jeweils eine
Ecke eines anderen Rechtecks verdeckt.
Das passiert reihum, bis es beim letzten
Rechteck zu einem Problem der Zeichenreihenfolge
kommt. Daher wird dieses in zwei Teile zerlegt und
die eine Hälfte wird vor den anderen
Rechtecken gemalt, die andere danach:
verkeilte Rechtecke 1
(Quelltext zu den
verkeilten Rechtecken 1).
verkeilte Rechtecke 2
(Quelltext zu den
verkeilten Rechtecken 2).
Wie man bei einigen Darstellungsprogrammen bemerken kann, sind hier offenbar Rundungsfehler
dieser Programme die natürlichen Feinde des Autors - es kann passieren, daß wegen
eindeutiger Darstellungsfehler ein dünner Strich des Rechtecks doppelt oder gar nicht
gezeichnet wird. Und solche Fehler sind nicht mehr leicht auszubügeln. Daß es sich
eindeutig um Darstellungsfehler handelt, kann man daran erkennen, daß ja die Werte
für die Trennung in zwei Teile eindeutig zusammenpassen. Auch wenn man die Figur
erst komplett malt, dann den nicht zu zeichnenden Teil mit einem Pfad in Hintergrundfarbe
überdeckt und denselben Pfad mit Farbe zum Schluß nutzt, um die Figur
zuende zu malen, bleibt manchmal ein solch dünner fehlerhafter Strich (beobachtet bei Opera 8)
Solche Fehler legen es nahe, in diesem Zusamenhang besser auf Teiltransparenz zu verzichten,
dann treten solche subtilen Probleme nicht auf.
Als nächstes Betrachten wir zwei Ringe oder Kreise, die ineinander verkettet sind.
Ohne Tricks ist das nicht darstellbar, auch nicht mit Teiltransparenz:
Problemstellung
(Quelltext zur
Problemstellung).
Der Lösungsansatz nutzt nun gerade die Zeichenreihenfolge aus und trennt
wie zuvor bei den Vierecken eine Figur in zwei Teile.
Generell können die Bilder in drei Regionen aufgeteilt werden:
dort wo Element 1 vor Element 2 liegt, wo Element 2 vor
Element 1 liegt und dort, wo sie sich nicht überschneiden. Die zweite Figur
wird nun in dieser dritten Region in zwei Segmente aufgeteilt, eines davon im
Quelltext vor das erste Element gesetzt:
Ringe verkettet
(Quelltext zu
den verketteten Ringen).
Alternativ könnte man auch nur genau den Bereich flicken, wo das eigentliche
Problem besteht und nicht wie hier einen Kreis in zwei Halbkreise zerlegen, aber
dafür ist es dann erforderlich, genau zu berechnen, wo der kritische
Schnittbereich ist, was wir uns so ersparen konnten.
Entsprechend lassen sich auch Olympische Ringe
improvisieren (wobei aus Rechtsbehelfsgründen erwähnt
werden soll, daß wir damit keinerlei kommerzielle Zwecke verfolgen,
sonst gibt es da Probleme mit den kommerziellen
Verwertungsgesellschaften IOC und
NOK):
Olympische Ringe
(Quelltext zu
den Olympischen Ringen).
Beim Opera 8 zumindest habe ich da allerdings einen kleinen Malfehler gesehen,
wo die Teilellipsen zusammenstoßen, was nicht so schön ist.
Bei nicht teiltransparenten Objekten wie bei diesem Beispiel kann man das mit
der stroke-linecap
kompensieren.
Alternativ kann man bei diesem Beispiel
natürlich auch die Schnittstellen in die weißen Bereiche legen,
wofür man allerdings ein bißchen mehr rechnen muß
(Übung für den Leser).
Tatsächlich ist die Vorstellung, die viele Leute von Schatten haben, etwas verwirrend. Ein Schatten ist eigentlich nichts, was existiert, es zeichnet sich vielmehr dadurch aus, daß für einen bestimmten Blickwinkel unser Auge etwas weniger sieht als für dem Blickwinkel daneben: Licht. Da kommen wir zu einem alten Physiker-Witz:
Gut, nun kennen wir die Geschwindigkeit des Lichtes - doch wie schnell ist die Dunkelheit?
Bei genauerer Sicht gibt es Lichtquellen und Objekte, die für das Licht nicht
transparent sind, es reflektieren oder absorbieren und wieder emittieren. Eigentlich
sind alle Objekte Lichtquellen, weil sie Licht emittieren, zudem absorbieren sie
auch alle Licht, allerdings jeweils bei unterschiedlichen Energien oder Farben.
Transparenz und Reflektion sind oftmals nützliche Vereinfachungen.
Licht wird besser beschrieben durch quantenmechanische Wellenpakete, einmal
ist es günstiger, es als Teilchen zu beschreiben, mal als Welle, was dann
jeweils wieder vereinfachte Konzepte sind. Bei letzterem kommt Beugung und Interferenz
ins Spiel, bei ersterem die Zählbarkeit der Lichtteilchen unter bestimmten
Umständen. Das kann alles sehr kompliziert werden - für den Menschen,
nicht für die Objekte und das Licht, die beherrschen das alles spielend.
Ein sehr simples Modell ist die klassische Optik. Da bewegt sich das Licht wie ein
Teilchen auf einer Bahn oder einem Strahl, aber die Teilchen sind nicht zählbar,
man kann es in beliebige Portionen aufteilen.
Der Schattenwurf wiederum ist ebenfalls ein sehr
einfaches Konzept um ganz grob den Eindruck zu erwecken, man
hätte etwas verstanden. In der virtuellen
Welt der Graphik verwendet man gern solch einfache Konzepte, die zwar ziemlich
leicht als Unfug zu überführen sind, aber für den flüchtigen
Blick doch überzeugend genug wirken, um Eindruck zu machen. Da ergibt
sich eine gewisse Übereinstimmung mit der Werbung.
Unter den einfachen Konzepten des Schattenwurfes wählen wir wiederum
das einfachste, eine Punktlichtquelle,
die es ebensowenig gibt wie den Schatten.
Noch einfacher ist vielleicht allenfalls die Annahme, alles sende gleich Licht aus
und habe eine Farbe an sich und absorbiere alle anderen Farben.
Nun kann die Punktquelle unendlich weit weg sein oder bei
endlicher Weite.
Zuerst betrachten wir den Fall, die Punktlichtquelle sei unendlich weit weg,
irgendwo über der Zeichenebene.
Auf der Zeichenebene sei ein Muster gemalt und über
der Zeichenebene schwebe ein Objekt als Fläche in einem bestimmten
Abstand z über der Fläche, welche überall gleich sein soll.
Da die Lichtquelle unendlich weit weg ist, bleibt uns nur,
den Einfallswinkel
relativ zur Senkrechten auf unserer Zeichenebene anzugeben. Der Einfachheit
halber geben wir zwei Einfallswinkel an, einen in x-Richtung ξ und
einen in y-Richtung ζ. Die Verschiebung des Schattens relativ zum
Objekt ist dann:
dx= - z * tan(ξ)
und
dy= - z * tan(ζ)
Der Schatten hat also den gleichen Umriß wie das Objekt, ist nur
parallel verschoben.
Zuerst ist das Muster auf der Zeichenebene zu malen, dann der Schatten,
am besten schwarz mit einer gewissen Teiltransparenz und dann das
schwebende Objekt. Durch einen dünnen teiltransparenten Rand
kann zudem der Übergang vom Schatten ins Licht etwas aufgeweicht
werden, was nicht die Beugung an einer Kante widerspiegelt, aber zumindest
eine etwas ausgedehnte Lichtquelle vortäuscht:
Schatten, Lichtquelle
unendlich weit weg
(Quelltext zu
Schatten, Lichtquelle unendlich weit weg).
Per Zufallsgenerator gibt es immer ein neues Objekt, einen neuen Abstand zur
Zeichenebene und neue Einfallswinkel, also ruhig öfter ausprobieren.
Die Teiltransparenz entspricht dann einer zusätzlichen diffusen
Beleuchtung, die auch Objekte im Schatten noch sichtbar werden läßt.
Sei nun die Zeichenebene bei z = h und die Lichtquelle habe den Ortsvektor
L. Sei ferner P ein Punkt eines ebenen Objektes und es gelte
h < Pz < Lz
für alle Punkte des Objektes. Mittels des Strahlensatzes
oder etwas Vektorrechnung berechnet sich leicht die Position des Schattens
S.
Sei die Hilfsgröße
f = (Lz - h)/(Lz - Pz)
dann ist
S = L + f (P - L)
Ist speziell Pz für alle Punkte eines Objektes gleich, ist offenbar f der
Faktor, um den der Schatten größer als das Objekt ist.
Jetzt interessiert uns noch die Verschiebung des Schattens in x- und y-Richtung.
Dazu gucken wir einfach, wohin der Nullpunkt verschoben wird, der
Schattenpunkt des Nullpunktes liegt offenbar bei
Si = Li (1-f) mit i = x, y
Statt wie in den folgenden Beispielen jeden Punkt einzeln auszurechnen, ist
es unter den Umständen möglich, mit dem use
-Element und
einer Transformation einen Schatten zu erzeugen, bei komplizierteren
Objekten spart das viel Rechenzeit und die Datei bleibt kleiner.
Der Schatten behält also die Form des Objektes, wird aber skaliert und
parallel verschoben:
Schatten von
punktförmiger Lichtquelle
(Quelltext zum
Schatten von punktförmiger Lichtquelle).
Sofern mehrere Objekte nur Schatten auf die Zeichenebene werfen und nicht
auf andere Objekte, bleibt die Situation einfach:
Schatten von
punktförmiger Lichtquelle, mehrere Objekte
(Quelltext zum
Schatten von punktförmiger Lichtquelle, mehrere Objekte).
Wenn die Objekte Schatten auf andere Objekte werfen, so handhabt man
das am einfachsten mit dem clipPath
-Element und
clip-path
-Attribut, die den Zeichenbereich
auf das Objekt eingrenzen. Von der Reihenfolge her wird erst die Zeichenebene
gezeichnet, dann die darauf befindlichen Schatten, dann das niedrigste Objekt
mit den darauf fallenden Schatten, danach das nächste Objekt und so weiter.
SVG bietet auch Filter an, mit etwas Geschick kann man damit diffuse Schatten
erstellen lassen, die recht realistisch aussehen, vor allem auch deshalb, weil der
normale Betrachter keine so detaillierten Kenntnisse von Schattenwürfen hat,
so daß er recht einfach zu täuschen ist.
Beugung und Interferenz lassen sich hingegen mit solch einfachen Filtern
ohne weitere Kenntnisse nicht einfach umsetzen.
Recht einfach ist aber die Faltung des harten Schattens mit einer Gaußfunktion
mit definierter Standardabweichung in x- und y-Richtung. Einfacher gesagt werden
damit Ränder des Schattens etwas aufgeweicht, was dann grob eine
ausgedehnte Lichtquelle simuliert. Mit den SVG-Filtern kann man zwar auch
aus dem Original einen Schatten als Maske erzeugen und verschieben, verwendet
man aber den einfachen Schatten aus dem vorherigen Abschnitt, so kann man
detaillierter arbeiten und auch solche Nutzer sehen zumindest noch den scharfen
Schatten, bei denen SVG-Filter im Darstellungsprogramm noch nicht funktionieren.
Gucken wir uns dazu ein leicht modifiziertes Beispiel von oben an. Das Objekt ist
nunmehr teiltransparent und der Schatten wird mit einem Filter etwas aufgeweicht:
Gefilterter Schatten von
ausgedehnter Lichtquelle
(Quelltext zum
gefilterten Schatten von ausgedehnter Lichtquelle).
Wo viel Licht, ist auch viel Schatten...
Gut, den Schatten haben wir ja nun schon eingehend behandelt, mit SVG-Filtern kann
jedenfalls auch die Oberflächenstruktur des Objektes hervorgehoben werden,
so daß etwa die Lichtquelle harte oder diffuse Glanzlichter auf der Oberfläche
erzeugen kann.
Gefilterter Schatten von
ausgedehnter Lichtquelle, die Glanzlichter auf der Oberfläche erzeugt
(Quelltext zum
gefilterten Schatten von ausgedehnter Lichtquelle mit Glanzlichtern).
Der kleine gelbe Kreis gibt die Position der Lichtquelle an - was bislang fehlt ist eine
Korrelation zwischen der Ausdehnung der Lichtquelle, dem Abstand zum Objekt und
der Diffusität des Schattens. Das kommt allerdings erst zum Tragen, wenn man
zum Beispiel mehrere Objekte unterschiedlich hoch über der Zeichenebene hat
oder die Lichtquelle animiert wird.
Was bei dem Beispiel genau angezeigt wird, ist je nach Darstellungsprogramm recht unterschiedlich.
Sofern Filter für Lichteffekte überhaupt berücksichtigt werden,
wird es interessant, wer was anzeigt. Opera 9 (Technologievorschau 1) schlägt
sich schon ganz passabel, positioniert aber die Lichtquelle falsch - relativ zum Darstellungsbereich,
nicht zu den viewBox
-Koordinaten. Zudem wird wohl der
gefilterte Schatten am Rande des Bildes falsch berechnet, sofern dieser dort übersteht.
Spätere Versionen von Opera beherrschen Filter deutlich besser, die Fehler sind dort
beseitigt.
Das alles bekommt auch das adobe-plugin richtig hin, gleichwohl
wirkt der Effekt beim firefox 1.0.4 (entsprechend Gecko 1.7.10)
mit der librsvg-Bibliothek 2.8.1 eindrucksvoller, beim
firefox1.5 oder 1.6a1 wird keine Bibliothek mehr angegeben und Filter für
Lichteffekte werden ignoriert, Gecko 1.7.8 (und Galeon, Epiphany) zeigen auch mit der
librsvg-Bibliothek 2.8.1 gar keine Filtereffekte an - wird man sich gedulden müssen,
bis sich die Geckos da auf eine hoffentlich korrekte Anzeige eingependelt haben.
Jedenfalls ist da mit Iceweasel 3 (entsprechend firefox 3, Gecko 1.9) immer noch kein
Effekt zu sehen.
Kompliziertere Objekte sind natürlich auch einfach zu filtern und sogar animierte
Objekte, wie auch die meisten Filtereigenschaften selbst animierbar sind. Die Kombination
von Filtern und Animation erfordert beim Darstellungsprogramm jedoch große
Rechenleistungen.
Animierte Gruppe mit
Licht und Schatten
(Quelltext zur
animierten Gruppe mit Licht und Schatten),
Gruppe mit
animierter Lichtquelle und Schatten
(Quelltext zur
Gruppe mit animierter Lichtquelle und Schatten).
Weitere Ideen ohne Beispiele:
Wenn wir von einer weißen Lichtquelle ausgehen, können wir bei
einem teiltransparenten Objekt festlegen, wieviel Licht transmittiert, reflektiert
und absorbiert wird. Ein Objekt, welches selbst rot erscheint, wird vermutlich bei
grün und blau entweder viel transmittieren oder viel absorbieren, entsprechend
fehlen im Schatten beim verbleibenden Licht mehr die Rotanteile als die anderen
Farben.
Ausgedehnte Lichtquellen komplizierterer Form lassen sich auch berücksichtigen,
indem nahezu transparente Schatten über ihre Ausdehnung gerastert werden. Oft wird
es sich lohnen, die Form des Schattens analytisch auf dem Papier auszurechnen.
Schiefe oder gar gekrümmte Zeichenebenen oder Objekte, auch Objekte
mit Volumen werfen natürlich kompliziertere Schatten, die die Form des
Objektes nicht mehr erhalten. Das kann zu sehr aufwendigen Berechnungen
führen, die insofern zweifelhaft sind, als solche Schatten ja ohnehin nur
grobe Näherungen sind, die nie zu realistischen Eindrücken
führen werden. Der Reiz der Computergraphik liegt ja gerade in der
Vereinfachung, die dem Auge des Betrachters von der Komplexität des
Alltags etwas entlastet. Wer wirklich Realistisches sehen will, sollte vielleicht
einfach mal Rechner und Fernsehen ausschalten und spazierengehen -
wenn man sich da mal die Gegend bis in die Details ansieht, wird man feststellen,
wie künstlich auch die besten
Pixelgraphik-ray-tracing-Bilder
aussehen und an Skalierbarkeit hat ein echtes Gänseblümchen sicher immer mehr
zu bieten als die beste SVG-Graphik ;o)
Bei Animationen treten ganz besondere Probleme mit der Zeichenreihenfolge
auf, denn manchmal wird einfach der Wunsch bestehen, per Animation die
Zeichenreihenfolge zu ändern, was bei SVG 1.1 aber noch nicht
möglich ist. Es muß wieder getrickst werden.
Prinzipiell ist es aber ein ähnlicher Trick wie zuvor. Man nimmt zwei
identische Animationen her, eine vor dem zu umrundenden Objekt im
Quelltext stehend, eine dahinter. An zwei unkritischen Stellen wird per
diskreter Animation die Transparenz oder die Sichtbarkeit von 0 auf 1
beziehungsweise von unsichtbar auf sichtbar geschaltet - oder umgekehrt.
Alternativ kann an den beiden unkritischen Stellen auch von einer
Animation zu anderen gewechselt werden mit dem Attribut
begin="id.end"
wie im Bereich Animation bereits am Beispiel gezeigt.
Umrunden eines
Objektes
(Quelltext zum
umrunden eines Objektes).
In diesem Falle wäre es natürlich einfacher gewesen, nur die Transparenz
des umrundeten Objektes diskret zu animieren, dabei hätten wir aber weniger
gelernt. Statt die Transparenz kann auch display
oder
visibility
animiert werden. Sogar
fill
kann diskret zwischen none und einer
Farbe gewechselt werden. Recht elegant ist auch die Methode, mittels defs
und use
und einer Animation von xlink:href
die Zeichenreihenfolge zu ändern, wie im nächsten
Abschnitt beschrieben.
Im Abschnitt Animation hatten wir schon gelernt, wie das Attribut
xlink:href
animiert wird. Dies kann auch genutzt werden, um die Zeichenreihenfolge zu
tauschen. Alle zu tauschenden Objekte kommen in den defs
-Bereich und erhalten
eine id
. Sichtbar gemacht werden die Objekte mit dem
Element use
und von diesem
wird das Attribut xlink:href
diskret animiert -
die Objekte werden zeitlich getauscht,
so daß zum passenden Zeitpunkt das passende Objekt vorne ist und alle
Objekte passend hintereinander weg gestaffelt sind. Leider gibt es dabei zwei
Haken: Obwohl es sich um einen Bestandteil von SVG-tiny handelt,
ist es mit Opera 8 nicht nachvollziehbar.
Das adobe-plugin neigt bei dieser Animation noch mehr
zu Abstürzen als ohnehin schon. Naja, manchmal hält es auch durch -
ist schon ein lustiges Teil. Erinnert ein wenig an die alten Tage, als man Netscape 3 oder
Netscape 4 noch mit aktiviertem java-script benutzt hat.
Opera 9 zeigt alles wie beabsichtigt an - ist also kein prinzipielles Problem:
Zyklisches Tauschen von
Objekten
(Quelltext zum
zyklischen Tauschen von Objekten).
Als Anwendung wurde das auch bereits im Abschnitt über Transformationen verwendet, um bei der Flächendarstellung animierter dreidimensionaler Objekte die Reihenfolge richtig hinzubekommen, zum Beispiel beim Sterntetraeder.