Implementierung von Polygon2D in Java 2D

9

Ich erstelle ein 2D-Spiel in Java, indem ich die Java2D-Bibliothek zum Zeichnen verwende, und ich brauche wirklich ein Gleitkomma-Präzisions-Polygon-Objekt, mit dem ich sowohl Spielobjekte zeichnen als auch Kollisionen erkennen kann. Unglücklicherweise kommt das Polygon-Objekt von Java nur in der Int-Genauigkeit vor, und es gibt kein äquivalentes Polygon2D, wie es bei Rectangle und Rectangle2D der Fall ist. Ich habe bereits genug Forschung betrieben, um zu sehen, dass ich ein paar Optionen habe, aber keine scheint sehr gut zu sein.

  1. Verwenden Sie Path2D . Laut einem Java-Entwickler, der dieses in Forum veröffentlichte, war das Fehlen von Polygon2D ein Versehen, aber sein vorgeschlagener Ersatz ist Path2D. Unglücklicherweise bietet Path2D keine Möglichkeit, auf seine einzelnen Scheitelpunkte oder Kanten zuzugreifen, die ich benötige, um eine Kollisionserkennung durchzuführen (speziell muss ich einen Vektor orthogonal zu jeder Kante erhalten).

  2. Implementiere mein eigenes Polygon2D , das das Shape-Interface implementiert, sodass ich es weiterhin an Graphics2D.draw(Shape) übergeben kann. Das sieht so aus, als wäre es ziemlich schwierig. Das Shape-Interface erfordert trickreich zu implementierende Methoden wie contains(Rectangle2D) und getPathIterator(AffineTransform) . Für getPathIterator im Besonderen scheint es, dass ich, um es zu implementieren, ein Objekt vom Typ PathIterator zurückgeben müsste, aber es gibt keine konkreten Implementierungen der PathIterator-Schnittstelle, die in den öffentlichen AWT-Paketen verfügbar sind.

  3. Wrap Path2D in einem Objekt, das sich die einzelnen Scheitelpunkte "merkt" und sie dem Client zur Verfügung stellt. Dies funktionierte für mich, wenn ich einen Bereich brauchte, der sich an seine Komponenten-Formen erinnerte: Ich verpackte ihn in eine CompoundShape-Klasse, die das Shape-Interface implementierte und alle Shape-Methoden an Area's Umsetzung weitergab, während jeder Shape, der dem hinzugefügt wurde, verfolgt wurde Bereich in einer ArrayList. Das Problem dabei ist, dass, wenn ich die einzelnen Scheitelpunkte in zwei Arrays von float s verfolge, es keine Möglichkeit gibt, sie dem Benutzer zugänglich zu machen, ohne dass der Benutzer die Scheitelpunkte ändern könnte - und das würde direkt passieren Array-Zugriff, wird das interne Path2D nicht über die Änderungen informiert.

  4. Kopieren Sie Polygon.java . Der eigentliche Quellcode der Java-Polygon-Klasse ist auf grepcode.com verfügbar, und ich könnte einfach die scheitelpunktbezogene int s durch float s ersetzen, um ein Polygon2D zu erhalten. Leider, als ich das versuchte, warf die Zeile import sun.awt.geom.Crossings; einen Compilerfehler auf, der sagte: "Der Typ Crossings ist aufgrund der Beschränkung auf die erforderliche Bibliothek C: \ Programme \ Java \ jre7 \ lib \ rt.jar nicht zugänglich." Laut diese Frage Das passiert, weil die Lizenzvereinbarung von Sun Sie daran hindert, Core-Java-Klassen durch Ihre eigenen zu ersetzen, aber Polygon versucht das nicht - es erstellt einfach ein Objekt vom Typ sun.awt.geom.Crossings, es treten keine Ersetzungen oder Erweiterungen auf, und ich Stellen Sie sicher, meine Kopie von Polygon in ein Paket, das nicht "Java" genannt wird, zu legen.

Was ist der beste Weg, um damit fortzufahren? Ich würde entweder Vorschläge schätzen, wie eine dieser Optionen funktioniert oder eine Idee für eine andere Option, die nicht die Probleme hat, denen diese begegnen.

    
Edward 13.07.2012, 06:36
quelle

3 Antworten

5

Ich würde auch Path2D empfehlen . GeneralPath ist eine Legacy-Klasse. benutze es nicht.

Path2D bietet Zugriff auf die Scheitelpunktwerte, wenn auch auf Umwegen. Sie müssen einen PathIterator verwenden:

%Vor%

Wenn Sie bereit sind, etwas Besonderes zu sein, können Sie else erweitern, um die quadratischen und kubischen Kurven zu unterstützen. Ich nehme an, Sie brauchen diese nicht zu dieser Zeit, da Sie über Polygone sprechen.

Außerdem hat Path2D einige praktische statische Methoden zum Testen, ob der Pfad schneidet ein Rechteck und ob der Pfad enthält ein Rechteck oder einen Punkt. Leider gibt es keine Methoden zum Testen auf einen Pfad, der einen anderen Pfad schneidet oder enthält.

    
Devon_C_Miller 21.08.2012, 21:21
quelle
0

Können Sie eine Bibliothek eines Drittanbieters verwenden? Wenn ja, kann ich vorschlagen, die Klasse Slick 2D Polygon zu verwenden. Was ich intern tun würde, verwende diese Klasse für dein tatsächliches Polygon, um die Schnittmenge mit enthält und dann, wenn Sie zeichnen müssen, einfach die float Werte auf int und zeichnen Sie das Java2D Polygon.

Ich weiß, das ist vielleicht nicht die optimale Lösung, aber es könnte für das funktionieren, was Sie tun.

    
Dan W 21.08.2012 21:29
quelle
0

Vielleicht haben die Interna des Polygons einen anderen Maßstab?

Multiplizieren mit einer großen Zahl und typecast zu int beim Schreiben, dividieren durch die gleiche große Zahl beim Lesen?

    
Chozabu 12.01.2013 06:42
quelle

Tags und Links