Verstaendnisfrage Java2D, Affine Transformation, Rendering

sirbender

Top Contributor
Hi,

Ich habe viele zufaellige Shapes. x/y Werte von 0-10000. Ich zeichne diese Shapes auf ein Image (800x600 pixel). Eigentlich "passen" die Rechtecke gar nicht auf das Bild. Bisher mache ich das so, dass ich das Graphics2D des Image so transformiere dass ich die Rechtecke normal zeichnen kann und sie dann auf das Bild "passen".

Meine Frage ist, was passiert bei der Transformation? Das Bild wird so transformiert, dass es praktisch groesser ist. Werden dann beim Rendern mehr Pixel gezeichnet und dauert es dadurch laenger Eigentlich hat das Bild nicht mehr Pixel durch die Transformation - das ist mir klar - aber gibt es beim Zeichnen der Rechtecke irgendeinen Overhead? Oder wird unter der Haube beim Zeichnen jedes Shapes dieser transformiert?
Vielleicht kann jemand auch den Rendering-Prozess genau erklaeren. Wie werden die Shapes eigentlich gezeichnet? Der Renderer geht ueber die Pixel des Bildes und faerbt die dort weiss wo sich der Shape befindet. Und wie wird das gemacht? Der Shape besteht doch aus Splines. Wird der Shape jedesmal zu Pixeln gerastert wenn ich ihn zeichne? Oder gibt es einen Cache fuer die Shapes der diese als Pixel haelt?

Waere das Zeichnen genauso schnell wenn keine Transformation noetig waere da die Shapes schon von Beginn an innerhalb des Images liegen wuerden?


vielen Dank,
sb
 

Marco13

Top Contributor
"Wissen" wäre übertrieben, oder οἶδα οὐκ εἰδώς, oîda ouk eidōs im Platonischen Sinn: Das ist unter der Haube SEHR kompliziert. Ich hatte mir mal ein bißchem vom Sun-Code angeschaut, weil ich auch wissen, wollte, wie denn ein Shape zu Pixeln wird, und das geht sher schnell zu Strukturen über, die schwer nachvollziehbare Mischungen aus Rendering-Tricks und auch nativen Methoden enthalten.

Man kann wohl pauschal sagen: Ein skaliertes Shape zu zeichnen dauert länger, als ein nicht-skaliertes zu zeichnen.

Oder wird unter der Haube beim Zeichnen jedes Shapes dieser transformiert?

Ja, das kann man GROB so sagen, aber intern ist das ziemlich kompliziert, weil sehr viele Dinge zu berücksichtigen sind. Insbesondere, ob das Shape gefüllt wird, oder ob seine Außenlinie gezeichnet wird. Das sind ja zwei völlig verschiedene Dinge.

Wenn es um die Außenlinie geht, muss man auch berücksichtigen, welcher Stroke verwendet wird: Der Stroke wird ja mit transformiert! D.h. wenn man eine Skalierung von (0.1, 10) hat, und dann eine senkrechte und eine waagerechte Linie mit einem Stroke der Dicke 1 zeichnet, ist eine Linie 0.1 und die andere 10 Pixel dick.

Der Renderer geht ueber die Pixel des Bildes und faerbt die dort weiss wo sich der Shape befindet. Und wie wird das gemacht?

Nun, er geht nicht über die Pixel des Bildes... also es ist NICHT sowas wie
[c]for (all pixels) if (shape.contains(pixel)) setColor(pixel,c)[/c] // Das NICHT!
Die Richtung ist die andere: Er schaut sich das Shape an und berechnet daraus, welche Pixel des Bildes gefüllt werden müssen. Da wird intern früher oder später GROB eine Form von Rasterung von Polygonen ? Wikipedia durchgeführt, aber die Darstellung dort suggeriert eine Einfachheit, die bei der echten Implementierung so nicht gegeben ist (allein schon durch Antialiasing wird das um Größenordnungen aufwändiger...)
 

sirbender

Top Contributor
Vielen Dank. Schoen zu wissen, dass keiner wirklich durchsteigt, was da passiert. Wenn immer ich die extremen Details in der JRE schauen - vor allem natives Zeug - wird einem schwindlig. Ein Wunder dass das so gut laeuft. Ich denke mal, diese speziellen Teile der JRE wir seit Jahrzehnten von den selben Leuten gepflegt.

Ich fuelle die Shapes und transformiere die Zeichenflaeche. Mittlerweile glaub ich, dass passiert was Du andeutest. Die Zeichenflaeche wird nicht transformiert, sondern jeder Shape. Ich nehme an beim Transformieren des Shape wird dann eine Kopie erstellt und jeder Punkt des Shape durch die Transformationsmatrix gejagt. Das waere natuerlich bei 30 frame/sec und bis zu 1000 Shapes sehr schlecht. Vielleicht waere das EINMALIGE Transformieren aller Shapes besser VOR dem Zeichnen. Dann muesste man beim Zeichnen die Zeichenflaeche nicht mehr transformieren da die neuen, transformierten Shapes bereits reinpassen.

Da ich aber echt keinen Durchblick habe was passiert kann ich wohl nichts weiter machen als mit den Performanceproblemen zu leben :D
 

Marco13

Top Contributor
Hmja, ob da, wie du angedeutet hast, eine Kopie erstellt und die transformiert wird, ist schwer zu sagen - im speziellen "löst sich das ganze ja auf". Also, es wird da sicher kein "neues Shape-Objekt" im Java-Sinn erzeugt, aber natürlich werden die Punkte irgendwo transformiert (Oder anders: Für einen Mathematiker passiert dort etwas anderes als für einen Informatiker ;) ).

Es ist aber tatsächlich so, dass man (speziell um das Transformieren der Strokes zu vermeiden - das kann wirklich häßliche Effekte haben...) häufiger mal AffineTransform (Java Platform SE 6) verwenden sollte/muss. Vielleicht passt das in deinem Fall auch, das ist auf Basis des bisher beschriebenen schwer zu sagen (Lapidar formuliert: Es hängt auch davon ab, wie oft sich die Skalierung ändert...)
 

Ähnliche Java Themen

Neue Themen


Oben