Eigenes Koordinatensystem

antimon

Mitglied
Hallo,

irgendwie fehlt mir ein vernünftiger Lösungsansatz, deswegen wende ich mich hilfesuchend an Euch:

Auf einem Panel brauche ich ein Koordinatensystem, auf das Symbole plaziert werden (siehe dazu auch meinen anderen Thread) - allerdings sind die Einheiten nicht Pixel, sondern interne (z.B. mm), des weiteren ist der Ursprung des Koordinatensystems nicht wie bei den Panels üblich, links oben, sondern links unten.

Die Umrechnung der internen Koordinaten auf Bildschirmpixel ist auch nicht so das Problem, da müssen die Faktoren Zoom, Offset vom internen Ursprung und die Höhe des Panels berücksichtigt werden... allerdings scheitert es an der Umsetzung.

Ich hätte mehrere Ansätze, wie ich die Berechnung angehen könnte, beispielsweise nach folgendem:
Jedes dargestellte Symbol enthält in internen Variablen die Informationen über den aktuellen Zoomfaktor, Panelhöhe etc. und kann daraus direkt die Bildschirmkoordinaten berechnen. Beim Verschieben werden für jeden Schritt die Koordinaten neu berechnet, was recht rechenintensiv ist wenn viele Symbole gleichzeitig verschoben werden sollen. Ausserdem müssen alle Symbole über Listener informiert werden, wenn sich Zoom oder der Bildausschnitt ändert etc.

Ein anderer Ansatz wäre folgender: Es gibt ein zentral erreichbares Objekt, das die Informationen zu Zoom, Bildausschnitt etc. enthält, bei jeder Verschiebe-Aktion werden die Daten von den Symbolen angefragt und zur Berechnung rangezogen. Allerdings würde ich vermuten dass die Performance da ziemlich zu wünschen übrig lässt.

Die dritte Möglichkeit, die mir einfällt, wäre, das JPanel zu überlagern und beim Aufruf von Methoden wie setLocation() die internen Koordinaten in Bildschirmkoordinaten umzurechnen. Vorteil: Das Panel kennt schon seine Höhe und muss daher nicht erst groß irgendwas abfragen.

Aber irgendwie gefällt mir das alles nicht so 100%ig - gibts da intelligentere Ansätze oder evtl. schon ein fertiges Framework für verschiebbare Symbole (so ähnlich wie Icons auf dem Desktop verschoben werden können, also auch mit Markieren und Verschieben von mehreren Symbolen gleichzeitig etc.)?
 
hi antimon,
Also ich habe solches ca wi folgt angegangen.
Es gibt einmal ein physiches Koordinatensystem, das vom JPanel, und es gibt ein logisches Koordinatensystem. Die Symbole (figuren Polygone oder was auch immer) beinhalten grundsätzlich die logischen Koordinatenwerte.
Die Darstellung wird dann immer vom logischen zum physichen Koordinatensystem berechnet (einfach ein Dreisazt). Wenn der Anwender seine Figuren verschieben möchte ist es genau umgekehrt also physisch nach logisch.
Bezogen auf Bildschirmausschnitte brauchst Du Dir eigetnlich keine Sorge machen, dass übernehmen schon die Swing-Komponenten, so du mit Swing arbeitest.
Immer wenn die Mousekoordinate also abgefragt wird, berechnest Du diese ins logische Koordinatensystem um, fragst ab, ob sich darunter Dein Symbol befindet . Daher sollten die Symbole in einer Collection z.B. ArrayList gespeichert sein.
Ich weiß nicht wie Du Deine Symbole darstellst, empfehlenswert, wären da aus meiner Sicht Polygone. Jedoch sind die Polygone von Java mit einem kleinen Manko behaftet, denn sie erkennen nicht genau ob ein gegebener Punkt (z.B. der Mouszeiger) in ihnen liegt, da sie lediglich die Box (das Rechteck, was sie umschließt) als ihre Fläche ansehen.
Ich habe da voro ein paar jarhen eine Polygon-Klasse gegoogelt, welche genau dieses Problem behebt. (Falls Interesse besteht sag einfach bescheid).
Von der Performacne ist mit dieser Strategie Java nach meinen Erfahrungen schnell genug.
 
Hmm das hört sich recht gut an, dann gingen meine Überlegungen in die richtige Richtung :)

Zuerst mal ja: ich nutze Swing, ich zeichne auf ein JPanel, das in einer ScrollPane liegt

Speicherst du dann im logischen Koordinatensystem Double-Werte? Das habe ich jetzt vorgesehen, zwar kann es dann passieren, dass beim Umrechnen in Bildschirmkoordinaten mal gerundet wird und etwas pixelig erscheinen könnte, aber dazu gibts ja Kantenglättung etc.

Die Polygonklasse würde mich interessieren, wär nett wenn du mir nen Link geben könntest. Du empfängst also die MouseEvents für das Panel und ratterst die Liste mit den Symbolen des Panels ab und schaust ob eins davon angeklickt wurde (sprich die Mauskoordinaten befinden innerhalb der Symbolkoordinaten), richtig?

Und dann beim Verschieben wird jeweils für die alte sowie die neue Position des Symbols, bzw. die Box darum die repaint-Methode aufgerufen?
 
Hmm das hört sich recht gut an, dann gingen meine Überlegungen in die richtige Richtung :)
Speicherst du dann im logischen Koordinatensystem Double-Werte? Das habe ich jetzt vorgesehen, zwar kann es dann passieren, dass beim Umrechnen in Bildschirmkoordinaten mal gerundet wird und etwas pixelig erscheinen könnte, aber dazu gibts ja Kantenglättung etc.
Ja, unbedingt im internen Koordinatensystem mit double arbeiten, sonst wird es spätestens beim Zoom ungenau!

Die Polygonklasse würde mich interessieren, wär nett wenn du mir nen Link geben könntest. Du empfängst also die MouseEvents für das Panel und ratterst die Liste mit den Symbolen des Panels ab und schaust ob eins davon angeklickt wurde (sprich die Mauskoordinaten befinden innerhalb der Symbolkoordinaten), richtig?
Vom prinzip ist das richtig, aber ich benutze halt die Polygonklasse, die genau soetwas berechnet. Da ich kein Mahtematiker bin und die Java-Polygone aus dem Swing oder AWT dies nicht richtig machen (sondern nur die Box verwenden) hatte ich damals Glück diese Klasse, und zwar in einem 2D-Roboterspiel eines Dozenten in Übersee zu finden.
Damals hatte ich einen anderen Link, der nicht mehr aktuell ist.
Aber glücklicherweise ist hier das, von dem ich spreche:
http://www.lucubratio.org/software/index.html

Und dann beim Verschieben wird jeweils für die alte sowie die neue Position des Symbols, bzw. die Box darum die repaint-Methode aufgerufen?

Fast, ich zeichne die Polygone innerhalb der paintComponent-Routine. deswegen verwende ich keine Boxen, da ich genaue Polygon-Kollision bzw. eine absolut genaue Aussage brauch(te), ob ein Punkt, z.B. der Mousezeiger, innerhalb oder außerhalb eines Polygons liegt.
 
Ah super, danke für den Link, werde ich mir gleich anschauen.

Was ich mit der Box meinte war auf die repaint-Methode bezogen. Oder hab ich da was falsch verstanden?

Also wenn ein Polygon, nehmen wir einfach mal ein Dreieck, verschoben wird - dann muss das Polygon ja an der neuen Position gezeichnet werden, allerdings ist es ja auch wichtig, dass die alte Position neu gezeichnet wird. Denn sonst hat man ja zwei Polygone. Und damit ned das ganze Panel neu gezeichnet werden muss, kann man der repaint-Methode ja die Koordinaten eines rechteckigen Bereiches mitteilen, der neu aufgebaut werden soll - das wäre bei einem Dreieck ja die umhüllende Box. Oder habe ich da irgendwo ein Verständnisproblem bzw. denke zu kompliziert?
 
Wenn ich Dich richtig verstanden hatte, verwendest Du pro gezeichnetes Objekt eine JPanel. Da hast du natürlich so etwas wie eine Box, nämlich das JPanel, da es im Grunde ein Rechteck ist. Wenn Du direkt Polygone zeichnest würdest Du beispielsweise beim Verschieben lediglich die polygonbeschreibenden Punkte allesammt transformieren. Also eine Box bräuchtest Du streng genommen nicht, Du musst nur wissen welches polygon der Answender wählte (ss. liegt Mouse Zeiger innerhalb eines Polygons, und wenn ja welches) und addierst x und y Werte eines jeden Punktes mit der logische Kordinate, die Du aus der physischen endkoordinate der Mousebewegung des Nutzers ermittlest (quasi Dreisatz).
Ähnliches tust Du es beim Zoomen, nur dass Du dann alle Polygone dann entsrepchend auf das physische Koordinatensystem umrechnest, aber halt dann nur in der paintcomponent-Routine, die logischen Koordinaten bleiben identisch ;-).
 

Neue Beiträge

Zurück