Frage

Ich habe einen Weg aus einer Liste von 2D-Punkten gemacht. Ich möchte diese in einen Streifen der Dreiecke drehen, um eine strukturierte Linie mit einer bestimmten Dicke (und andere solche Dinge) zu machen. So im Wesentlichen die Liste der 2D-Punkte müssen eine Liste von Scheitelpunkten werden die Umrisse eines Polygons angeben, die gemacht, wenn würde die Linie machen. Das Problem ist der Umgang mit den Eckverbindungen, Gehrungen, Mützen usw. Das resultierende Polygon muss „perfekt“ im Sinne von nicht Overdraw sein, sauber beitritt, etc., so dass es machbar extrudiert werden konnte oder sonst spielte mit.

Gibt es einfache Ressourcen um, dass Algorithmus Einsicht zur Verfügung stellen können, Code oder mehr Informationen zu diesem Thema effizient zu tun?

ich absolut nicht wollen, ein vollwertiges 2D-Vektor-Bibliothek (kairo, antigrain, OpenVG, etc.) mit Kurven, Bögen, Bindestriche und allen Glocken und Trillerpfeifen. Ich habe in mehreren Quellbäumen für OpenVG-Implementierungen und andere Dinge zu graben einen kleinen Einblick zu finden, aber es ist alles furchtbar verworren.

Ich bin auf jeden Fall bereit, es selbst zu kodieren, aber es gibt viele degenerierten Fälle (kleine Segmente + dicke Breiten + scharfe Ecken), die alle Arten von Join Fragen erstellen. Sogar eine kleine Hilfe mir Stunden zu versuchen, speichern würde mit ihnen umgehen alle.

EDIT: Hier ist ein Beispiel für eine diese degenerierten Fälle, die Hässlichkeit verursacht, wenn man einfach von Vertex Vertex zu gehen ist. Rot ist der ursprüngliche Pfad. Die orangefarbenen Blöcke sind Rechtecke mit einer spezifizierten Breite an jedem Segment ausgerichtet und zentriert gezeichnet.

War es hilfreich?

Lösung

Na ja - ich habe versucht, das Problem selbst zu lösen. Ich verschwendete 2 Monate an einer Lösung, die das Null Overdraw Problem zu lösen versucht. Wie Sie bereits herausgefunden haben, kann man nicht mit allen degenerierten Fällen behandeln und Null Overdraw zur gleichen Zeit hast.

Sie können jedoch einen hybriden Ansatz verwenden:

Schreiben Sie sich eine Routine, die bei der Kontrolle schließt sich aus einfacher Geometrie problemlos aufgebaut werden. Um dies zu tun Sie überprüfen müssen, um den Join-Winkel, die Breite der Linie und die Länge der verbundenen Liniensegmente (line-Segmente, die kürzer sind als ihre Breite ist ein PITA). Bei einigen Heuristik sollten Sie in der Lage sein, alle triviale Fälle auszusortieren.

Ich weiß nicht, wie Ihre durchschnittlichen Line-Daten wie folgt aussehen, aber in meinem Fall mehr als 90% der breiten Linien hatte keine degenerierten Fälle.

Für alle anderen Zeilen:

Sie haben wahrscheinlich bereits herausgefunden, dass, wenn Sie overdraw tolerieren, die Erzeugung der Geometrie viel einfacher ist. Tun Sie dies und lassen Sie ein Polygon CSG-Algorithmus und ein tesselation Algorithmus die harte Arbeit zu tun.

Ich habe die meisten der verfügbaren tesselation Pakete ausgewertet, und ich mit der GLU Tesselator endete. Es war schnell, robust, nie abgestürzt (im Gegensatz zu den meisten anderen Algorithmen). Es war frei und die Lizenz erlaubt mir, es in einem kommerziellen Programm aufzunehmen. Die Qualität und die Geschwindigkeit des Tesselation ist in Ordnung. Sie werden nicht Delaunay-Triangulation Qualität, bekommen aber da Sie nur die Dreiecke müssen für das Rendering, das ist kein Problem.

Da ich den Tesselator API nicht mochte ich den Tesselation Code aus der freien SGI OpenGL Referenzimplementierung angehoben, schrieb das gesamte Front-End und zusätzliche Speicher-Pools, die Anzahl der Zuweisungen nach unten zu bekommen. Es dauerte zwei Tage, dies zu tun, aber es war es wert (wie Faktor fünf Leistungsverbesserung). Die Lösung endete btw in einer kommerziellen OpenVG Umsetzung bis: -)

Wenn Sie mit OpenGL auf einem PC rendern, sollten Sie die Tesselation / CSG-Job von der CPU auf die GPU und benutzen Schablone-Puffer oder Z-Puffer-Tricks bewegen, um die Überzeichnungs zu entfernen. Das ist viel einfacher und kann sogar noch schneller als CPU Tesselation.

Andere Tipps

Eine einfache Methode aus der Spitze von meinem Kopf.

Halbiere den Winkel jeden 2d Vertex, wird dies eine schöne Mitra Linie erstellen. Bewegen Sie dann entlang dieser Linie, die beide nach innen und außen, die Höhe Ihrer „Dicke“ (oder Dicke geteilt durch zwei?), haben Sie jetzt Ihre inneren und äußeren Polygonpunkte. Gehen Sie zum nächsten Punkt, wiederholen Sie den Vorgang, den Aufbau Ihre neue Polygonpunkte auf dem Weg. Dann eine triangualtion gilt für Ihren Render-ready Eckpunkten zu erhalten.

Ich habe gerade diese erstaunliche Arbeit:

http://www.codeproject.com/Articles/226569/ Zeichnung-Polylinien-by-Tessellation

Es scheint genau das zu tun, was Sie wollen, und seine Lizenz erlaubt es auch in kommerziellen Anwendungen zu nutzen. Außerdem hat der Autor einen wirklich tollen Job zum Detail seiner Methode. Ich werde es wohl irgendwann einen Schuss auf meine eigene nicht-fast-as-perfekte Umsetzung zu ersetzen.

I endete mit bis zu meinen Hände schmutzig zu machen und einen kleinen ribbonizer schreibt ein ähnliches Problem zu lösen.

Für mich war das Problem, dass ich Fett Linien in OpenGL, die nicht haben, die Arten von Artefakten, die ich sah mit OpenGL auf dem iPhone wollte. Nachdem an verschiedenen Lösungen zu suchen; Bezier-Kurven und dergleichen - beschloss ich, es war wahrscheinlich am einfachsten nur meine eigenen. Es gibt ein paar verschiedene Ansätze.

Ein Ansatz ist es, den Schnittwinkel zwischen zwei Segmenten zu finden und dann entlang dieser Schnittlinie in einem gewissen Abstand von der Oberfläche weg und behandeln, dass als Band Eckpunkt zu bewegen. Ich habe versucht, dass und es sah nicht so aus intuitiv; die Bandbreite variieren würde.

Ein weiterer Ansatz besteht darin, zu berechnen, tatsächlich eine normal zu der Oberfläche der Liniensegmente und verwenden, dass die ideale Bandkante für dieses Segment zu berechnen und die tatsächlichen Schnitttests zwischen ribbon Segmenten zu tun. Dies funktioniert gut, außer dass für scharfe Ecken die Bandliniensegment Kreuzungen zu weit weg sind (wenn der Winkel zwischen den Segmenten 180' genähert).

Ich arbeitete um den spitzen Winkel Problem mit zwei Ansätzen. Der Paul Bourke Leitungsschnittalgorithmus (die ich in einer nicht optimierten Art und Weise verwendet wird) vorgeschlagen, Erfassen, ob der Schnittpunkt innerhalb der Segmente war. Da beide Segmente identisch sind nur I benötigt eines der Segmente für die Kreuzung zu testen. Ich konnte dann entscheiden, wie diese zu lösen; entweder durch einen besten Punkt zwischen den beiden Enden Frisieren oder an einer Endkappe setzen - beiden Ansätze gut aussehen - die Endkappe Ansatz das Polygon Front abwerfen kann / zurück für opengl Bestellung gegenüber

.

Siehe http://paulbourke.net/geometry/lineline2d/

Sehen Sie meinen Quellcode hier: https://gist.github.com/1474156

Ich bin interessiert auch in diesem, da ich meine Mapping-Anwendung perfektionieren will die ( Kosmos ) Zeichnung von Straßen. Eine Abhilfe, die ich verwenden, um die Polylinie zweimal zu ziehen, einmal mit einer dickeren Linie und einmal mit einem dünneren, mit einer anderen Farbe. Aber das ist nicht wirklich ein Polygon, es ist nur eine schnelle Möglichkeit, eine zu simulieren. Hier ein paar Beispiele hier: http://wiki.openstreetmap.org/wiki/Kosmos_Rendering_Help#Rendering_Options

Ich bin mir nicht sicher, ob dies ist, was Sie brauchen.

Ich glaube, ich für einen Tessellation-Algorithmus erreichen würde. Es stimmt, dass in den meisten Fällen, wo diese verwendet werden, das Ziel, die Anzahl von Vertices zu reduzieren, ist Rendering zu optimieren, aber in Ihrem Fall könnten Sie parametrisieren alle Details behalten -. Und die Möglichkeit der Optimierung kommen kann nützlich

Es gibt zahlreiche Tessellation Algorithmen und Code um auf dem Netz - ich ein reines C eingewickelt auf in einer DLL vor ein paar Jahren für die Verwendung mit einer Delphi-Landschaft Renderer, und sie sind kein ungewöhnliches Thema für erweiterte Grafik Codierung Tutorials und dgl.

Sehen Sie, wenn Delaunay-Triangulation helfen kann.

In meinem Fall konnte ich overdraw leisten. Ich habe gerade Drow Kreise mit einem Radius = Breite / 2 zentriert auf jedem der Scheitelpunkte der Polylinie.

Artefakte werden auf diese Weise maskiert, und es ist sehr einfach zu implementieren, wenn Sie mit „abgerundeten“ Ecken und einige Überzeichnung leben können.

Von Ihrem Bild sieht es so aus, dass Sie Feld zeichnen um Liniensegmente mit FILL auf und mit orange Farbe. so tut gehen schlecht Overdraws sicher zu erstellen. Also erste, was zu tun wäre, schwarzen Rand und Füllfarbe nicht machen können undurchsichtig sein.

Warum können Sie nicht verwenden GL_LINES primitiv zu tun, was Sie Absicht zu tun? Sie können Breite, Filterung, Glätte, Struktur etwas spezifizieren. Sie können alle Ecken mit glDrawArrays machen (). Ich weiß, das ist nicht etwas, was Sie im Kopf haben, aber wie Sie auf 2D-Zeichnung konzentrieren, könnte dies einfacher Ansatz. (Suche nach Strukturierter Linien etc.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top