Elegant/Reinigen (spezieller Fall) Straight-line Grid-Traversal Algorithmus?

Ich bin abstauben ein altes Projekt von mir. Eines der Dinge, die er tun musste, war-gegeben ein Kartesisches Gitter-system, und zwei Quadrate auf dem Gitter finden Sie eine Liste aller Quadrate, die die Verbindungslinie zwischen der Mitte der beiden Quadrate würde passieren.

Den speziellen Fall hier ist, dass alle start-und end-Punkte sind nur in der exakten Mitte der Quadrate/Zellen.

Hier sind einige Beispiele-mit Paaren von sample-Start-und End-Punkte. Die schattierten Quadrate sind diejenigen, die zurückgegeben werden sollen, indem Sie die entsprechende Funktion aufrufen

entfernt tot ImageShack link - Beispiel

Den Start-und end-Punkte beziehen sich auf den Plätzen, die Sie sind in. Im Bild oben, unter der Annahme, dass die unten Links ist [1,1], die Linie auf der rechten unteren wäre identifiziert als [6,2] zu [9,5].

Ist, aus der (Mitte der) Platz auf die sechste Spalte von Links in der zweiten Reihe von unten auf der (Mitte der) Platz auf die neunte Spalte von Links in der fünften Reihe von unten,

Die nicht wirklich scheinen, dass kompliziert. Allerdings habe ich irgendwie schien gefunden zu haben, der einige komplexe online-Algorithmus und implementiert es.

Ich erinnere mich, dass es war sehr, sehr schnell. Wie optimiert-für-ein-Hunderte-oder Tausende-von-mal-pro-frames fallen.

Grundsätzlich, es sprang von Grenze zu Grenze die Quadrate, die entlang der Linie (die Punkte, wo die Linie überquert die grid-Linien). Er wusste, wo der nächste Grenzübergang war zu sehen, welche Kreuzung war näher -- eine horizontale oder eine vertikale ein-und verschoben, die nächste.

Welche Art von okay in Konzept, aber die tatsächliche Umsetzung entpuppte sich als ziemlich nicht-so-ziemlich, und ich fürchte, dass das Niveau der Optimierung sein könnte viel zu hoch für das, was ich praktisch brauchen (ich nenne diese traversal Algorithmus vielleicht fünf oder sechs mal in der minute).

Ist es ein einfaches, einfach-zu-verstehen, transparent, straight-line grid-traversal Algorithmus?

Programmatisch:

def traverse(start_point,end_point)
  # returns a list of all squares that this line would pass through
end

wo die angegebenen Koordinaten zu identifizieren, die Quadrate selbst.

Einige Beispiele:

traverse([0,0],[0,4])
# => [0,0], [0,1], [0,2], [0,3], [0,4]
traverse([0,0],[3,2])
# => [0,0], [0,1], [1,1], [2,1], [2,2], [3,2]
traverse([0,0],[3,3])
# => [0,0], [1,1], [2,2], [3,3]

Beachten Sie, dass Zeilen, die direkt durch die Kurven sollten nicht zählen Quadrate auf dem "Flügel" der Linie.

(Good ol' Bresenham ' s vielleicht hier arbeiten, aber es ist ein bisschen nach hinten von dem, was ich will. Soweit ich weiß, um es zu benutzen, ich hatte im Grunde haben Sie auf die Linie und dann Scannen Sie jedes einzelne Quadrat auf dem raster für true oder false. Nicht machbar-oder zumindest unelegant -- für große Netze)

(Ich bin wieder auf der Suche in Bresenham, und Bresenham-basierten algorithmen, durch ein Missverständnis von mir)


Zur Verdeutlichung eine mögliche Anwendung dafür wäre, wenn ich speichern Sie alle meine Objekte in einem Spiel innerhalb von Zonen (ein raster), und ich habe einen Strahl, und wollen sehen, welche Objekte der Strahl berührt. Mit diesem Algorithmus, konnte ich testen, der Strahl, um nur die Objekte, die Sie innerhalb des vorgegebenen Zonen, statt jedes Objekt auf der Karte.

Den tatsächlichen Nutzung dieser in meiner Anwendung ist, dass jede Fliese hat eine Wirkung zugeordnet, und ein Objekt bewegt sich durch ein Liniensegment mit jedem Zug. An jeder Ecke, ist es notwendig zu überprüfen, um zu sehen, welche Felder das Objekt durchquert hat, und daher die Effekte auf das Objekt anwenden.

Beachten Sie, dass an diesem Punkt der aktuellen Umsetzung habe ich funktioniert. Diese Frage ist vor allem für die Neugier Zweck. Gibt es eine einfachere Möglichkeit...irgendwie...für so ein einfaches problem.


Was Suche ich genau? Etwas konzeptionell/ordentlich und sauber. Außerdem habe ich gemerkt, dass durch das, was ich genau angeben, alle start-und end-Punkte sind immer in der Mitte der Quadrate/Zellen; so vielleicht etwas nutzt, das wäre nett als gut.

  • Wo wollen Sie die enden der Linie zu sein - die Ecken der Quadrate (wenn ja, welche) oder in den Zentren?
  • danke für den Hinweis auf die Mehrdeutigkeit; ich habe ein Bild zur Verdeutlichung. Ich meine den Zentren.
  • danke für die Aufklärung und das Bild - das macht es etwas klarer
InformationsquelleAutor Justin L. | 2010-07-13
Schreibe einen Kommentar