Zeichnen einer Topographischen Karte

Habe ich gearbeitet, auf eine Visualisierung Projekt für 2-dimensionale kontinuierliche Daten. Es ist die Art von Sache, die Sie benutzen konnte, um die Studie, Erhebung von Daten oder der Temperatur Muster auf einer 2D-Karte. In seinem Kern ist es wirklich eine Art Abflachung 3-Dimensionen in zwei Dimensionen-plus-Farbe. In meinem speziellen Bereich der Studie, ich bin eigentlich nicht die Arbeit mit geografischen Höhendaten, aber es ist eine gute Metapher, also werde ich dabei bleiben, in diesem post.

Jedenfalls, an diesem Punkt, ich habe einen "continuous color" - renderer, ich bin sehr zufrieden mit:

Zeichnen einer Topographischen Karte

Den Verlauf ist die standard-Farbe-Rad, wo rot-Pixel angeben, die Koordinaten mit hohen Werten und Violett Pixel zeigen niedrige Werte.

Den zugrunde liegenden Daten-Struktur verwendet einige sehr kluge (wenn ich so sagen selbst) - interpolation-algorithmen zu ermöglichen beliebig tiefes Zoomen in die details der Karte.

Ich an dieser Stelle zeichnen möchten, einige topographische Höhenlinien (mit quadratischen bezier-Kurven), aber ich habe nicht in der Lage zu finden, eine gute Literatur beschriebene effiziente algorithmen für die Suche nach Kurven.

Um Ihnen eine Idee für das, was ich denken werde, ist hier ein Arme-Leute-Umsetzung (wo die renderer gerade verwendet eine schwarz RGB-Wert immer dann, wenn es auf einen pixel, schneidet eine Kontur-Linie):

Zeichnen einer Topographischen Karte

Gibt es mehrere Probleme mit diesem Ansatz, aber:

  • Bereiche des Diagramms mit einer steileren Steigung Ergebnis in dünner (und oft kaputt) topo-Linien. Im Idealfall sind alle topo-Linien sollte kontinuierlich sein.

  • Bereiche des Diagramms mit einer flacheren Steigung Ergebnis in breiter topo-Linien (und oft ganze Regionen der Schwärze, vor allem am äußeren Umfang der rendering-region).

So, ich bin auf der Suche auf eine Vektor-Zeichnung Ansatz zum Erhalt dieser schönen, perfekten 1-pixel-dicken Kurven. Die grundlegende Struktur des Algorithmus enthalten die folgenden Schritte:

  1. In jedem diskreten Höhe, wo ich zeichnen möchte eine topo-Linie, finden Sie eine Reihe von Koordinaten, wo die Erhebung auf die Koordinate ist ganz in der Nähe (gegeben eine beliebige epsilon-Wert) auf die gewünschte Höhe.

  2. Redundante Punkte. Zum Beispiel, wenn es drei Punkte werden in eine perfekt gerade Linie, dann der Mittelpunkt ist redundant, da es beseitigt werden kann, ohne änderung der Form der Kurve. Auch mit Bézier-Kurven ist es oft möglich, Sie zu beseitigen cetain Ankerpunkte durch anpassen der position der benachbarten Punkte.

  3. Montieren Sie die restlichen Punkte in eine Reihenfolge, so dass jedes segment zwischen zwei Punkten entspricht einer Höhe-neutralen Flugbahn, und so, dass keine zwei Liniensegmente, die jemals über den Weg läuft. Jeder Punkt-Folge muss entweder ein geschlossenes polygon, oder muss den Schnittpunkt mit der bounding box des rendering-region.

  4. Für jeden vertex, finden Sie ein paar Kontroll Punkte, so dass die resultierende Kurve besitzt eine minimale Fehler in Bezug auf die überflüssige Punkte eliminiert, die in Schritt #2.

  5. Sicherzustellen, dass alle Merkmale der Topographie sichtbar an der derzeitigen rendering-Skala vertreten sind, durch entsprechende topo-Linien. Zum Beispiel, wenn die Daten enthält einen spike mit großer Höhe, aber mit extrem kleinen Durchmesser, die topo-Linien sollte noch gezogen werden. Vertikale Funktionen sollten nur ignoriert werden, wenn Ihre feature-Durchmesser ist kleiner als die Gesamt-rendering-Granularität des Bildes.

Aber selbst unter diesen Einschränkungen kann ich immer noch denke, der verschiedene Heuristiken für das finden der Linien:

  • Finden Sie die high-point innerhalb der rendering-bounding-box. Von diesem hohen Punkt, Reise bergab auf verschiedenen Flugbahnen. Jedes mal, wenn der traversal-line crossest einer Höhe Schwelle, fügen Sie diesen Punkt, um eine Erhöhung-spezifischen Eimer. Wenn der Verfahrweg erreicht ein lokales minimum, ändern Sie den Kurs und die Reise bergauf.

  • Eine high-resolution-Traversierung entlang der rechteckigen bounding-box-und rendering-region. Bei jeder Erhöhung Schwelle (und an Wendepunkte, wo die Steigung kehrt die Richtung), müssen Sie diese Punkte auf einer Höhe-spezifischen Eimer. Nach Abschluss der boundary traversal, starten Sie die Ablaufverfolgung nach innen von der Grenzpunkte in die Eimer.

  • Scannen der gesamten rendering-region, wobei eine Erhöhung der Messung mit einer lichten regelmäßigen Intervall. Für jede Messung, verwenden Sie die Nähe zu einer Erhöhung Schwelle als ein Mechanismus, um zu entscheiden, ob oder nicht, um eine interpolierte Messung seiner Nachbarn. Mit dieser Technik würde besser garantiert der Berichterstattung über die gesamte rendering-region, aber es wäre schwierig zu montieren die daraus resultierenden Punkte in eine sinnvolle Reihenfolge für den Bau von wegen.

So, dass sind einige meiner Gedanken...

Bevor Sie Tauchen tief in eine Implementierung, die ich sehen wollte, ob jemand auf StackOverflow hat Erfahrung mit dieser Art von problem und konnte Hinweise für eine zielgenaue und effiziente Umsetzung.

Edit:

Ich bin besonders daran interessiert, die "Gradient" Anregung ellisbben. Und mein core data structure (ignorieren einige der Optimierung-interpolation-Verknüpfungen), dargestellt werden kann als Summe eines Satzes von 2D-Gauß-Funktionen, welche ist Total differenzierbar.

Ich nehme an, ich benötige eine Datenstruktur zum repräsentieren eines dreidimensionalen Hang, und eine Funktion für die Berechnung, dass die Steigung Vektor für die an beliebiger Stelle. Aus der Spitze von meinem Kopf, ich weiß nicht, wie zu tun, dass (obwohl es scheint, wie es sollte einfach sein), aber wenn Sie haben einen link, der erklärt, die Mathematik, wäre ich sehr dankbar!

UPDATE:

Dank der hervorragenden Beiträge von ellisbben und Azim, ich kann jetzt die Berechnung der Kontur Winkel für jede beliebige Stelle im Feld. Zeichnung der echte topo-Linien Folgen in Kürze!

Hier sind aktualisierte renderings, mit und ohne ghetto-raster-basierte topo-renderer, habe ich mit. Jedes Bild enthält ein tausend Stichproben-Punkte, dargestellt durch rote Punkte. Der Winkel der Kontur an diesem Punkt wird dargestellt durch eine weiße Linie. In bestimmten Fällen, keine Neigung gemessen werden können, die im gegebenen Punkt (basierend auf der Granularität von interpolation), so dass der red dot kommt ohne eine entsprechende Winkel-des-Kontur-Linie.

Genießen!

(HINWEIS: Diese renderings verwenden Sie eine andere Topographie als die vorherigen Darstellungen-da ich zufällig erzeugen der Datenstrukturen, die bei jeder iteration, während ich bin prototyping -- aber die core-rendering-Methode ist die gleiche, so bin ich sicher, Sie bekommen die Idee.)

Zeichnen einer Topographischen Karte

Zeichnen einer Topographischen Karte

Hier ist ein Spaß Tatsache: auf der rechten Seite dieser Darstellungen werden Sie sehen, eine Reihe von seltsamen Höhenlinien perfekt horizontalen und vertikalen Winkel. Dies sind Artefakte der interpolation Prozess, der verwendet ein raster von interpolatoren zur Reduzierung der Anzahl von Berechnungen (etwa 500%) notwendig, führen Sie die core-rendering-Vorgänge. Alle diese seltsam Kontur-Linien auftreten, auf der Grenze zwischen zwei interpolator-raster-Zellen.

Glücklicherweise, diese Artefakte nicht wirklich wichtig sind. Obwohl die Artefakte sind nachweisbar, während der slope-Berechnung, die final renderer nicht bemerken, denn es arbeitet auf einer anderen bit-Tiefe.


WIEDER EIN UPDATE:

Aaaaaaaand, als eine endgültige Nachsicht, bevor ich schlafen gehe, hier noch ein paar renderings, in der alten-Schule "continuous color" - Stil und eine mit 20.000 gradient Proben. In dieser Reihe von Darstellungen, die hab ich beseitigt, der rote Punkt für Punkt-Muster, da es unnötig überfrachtet das Bild.

Hier können Sie wirklich sehen, die Interpolations-Artefakte, die ich soeben erwähnt habe, Dank der grid-Struktur der interpolator Sammlung. Ich sollte betonen, dass diese Artefakte werden völlig unsichtbar auf die endgültige Kontur-rendering (da der Unterschied in der Größe zwischen zwei benachbarten interpolator-Zellen geringer ist als die Bittiefe des gerenderten Bildes).

Bon appetit!!

Zeichnen einer Topographischen Karte

Zeichnen einer Topographischen Karte

  • Warum nutzen Sie nicht die vorhandenen library-tool (wie z.B. gnuplot, tecplot)?
  • Sie sagen, dass die Daten kontinuierlich - bedeutet, dass impliziert, dass Sie in der Lage sind, algorithmisch berechnen Sie die Werte für die inter-Bildpunkt-Koordinaten?
  • Ja, kann ich den Wert berechnen zu jeder Koordinate (mit 64-bit-floating-point-Präzision). Die Datenstruktur ist eigentlich eine Sammlung von 2D-Gauß-Funktionen, jede mit Ihrer eigenen amplitude und die Standardabweichung, und die interpolation verwendet ein Kernel-Dichte-Schätzer zu finden, die Zwischenwerte.
  • Auch: der Kernel-Dichte-Schätzer teilt die rendering-region in einer matrix von "interpolation " Zellen", so dass Sie können vermeiden, ausführen teuer Berechnungen in Fällen, in denen der renderer nicht genügend bit-Tiefe Rendern diese Unterschiede ohnehin.
  • Interessante Anregung über gnuplot. Sieht aus wie es anständige Kontur-rendering für 3D-Funktionen. Ich könnte es versuchen (oder ich könnte Blick auf Ihre source-code, um zu sehen, wie Sie es tun): chem.skku.ac.kr/~wkpark/tutor/gnuplot/gpdocs/contours.htm
  • Ich bin nicht so vertraut mit Bezier-Kurven; nicht das geben, was Sie brauchen, um diese aufzubauen? Können Sie erläutern, wie es ausklingen?
  • Sorry für die verspätete Antwort... Ja, habe ich, was ich zu diesem Zeitpunkt benötigen. Aber ich habe abgelenkt in der letzten Woche mit anderen (Bezugs -) Arbeit und noch nicht abgeschlossen, die Umsetzung. Ich werde aktualisieren, meine Frage mit den letzten details bald mal :o)

Schreibe einen Kommentar