Ich muss die kürzeste Entfernungsrichtung von einem Punkt in meiner 2D-Welt zu einem anderen Punkt finden, an dem die Kanten gewickelt sind (wie Asteroiden usw.). Ich weiß, wie man die kürzeste Entfernung findet, aber ich habe Mühe herauszufinden, in welche Richtung es geht.
Die kürzeste Entfernung ergibt sich aus:
int rows = MapY;
int cols = MapX;
int d1 = abs(S.Y - T.Y);
int d2 = abs(S.X - T.X);
int dr = min(d1, rows-d1);
int dc = min(d2, cols-d2);
double dist = sqrt((double)(dr*dr + dc*dc));
Beispiel der Welt
:
: T
:
:--------------:---------
: :
: S :
: :
: :
: T :
: :
:--------------:
Im Diagramm sind die Kanten mit: und - dargestellt. Ich habe oben rechts auch eine verpackte Wiederholung der Welt gezeigt. Ich möchte die Richtung in Grad von S nach T finden. Der kürzeste Abstand ist also die Wiederholung von T oben rechts. Aber wie berechne ich die Richtung in Grad von S nach der Wiederholung von T oben rechts?
Ich kenne die Positionen von S und T, aber ich nehme an, ich muss die Position des wiederholten T finden, aber dort mehr als 1.
Das Weltkoordinatensystem beginnt bei 0,0 oben links und 0 Grad für die Richtung könnten bei West beginnen.
Es scheint, dass dies nicht zu schwierig sein sollte, aber ich konnte keine Lösung finden. Ich hoffe jemand kann helfen? Alle Websites würden geschätzt.
Antworten:
Sie müssen Ihren Algorithmus ein wenig optimieren, um den Winkel zu berechnen. Derzeit erfassen Sie nur den absoluten Positionsunterschied, aber Sie benötigen den relativen Unterschied (dh er kann je nach Positionierung positiv oder negativ sein).
quelle
MapX
100,T.X
90 undS.X
10.dx
sollten eindeutig 20 sein, aber dieser Algorithmus gibt 30 zurück!In einer solchen Welt gibt es unendlich viele Wege von S nach T. Wir bezeichnen die Koordinaten von T by
(Tx, Ty)
, die Koordinaten von S by(Sx, Sy)
und die Größe der Welt by(Wx, Wy)
. Die umbrochenen Koordinaten von T sind(Tx + i * Wx, Ty + j * Wy)
, woi
undj
sind ganze Zahlen, das heißt, Elemente der Menge{..., -2, -1, 0, 1, 2, ...}
. Die Vektoren, die S mit T verbinden, sind(Dx, Dy) := (Tx + i * Wx - Sx, Ty + j * Wy - Sy)
. Für ein bestimmtes(i, j)
Paar ist der Abstand die Länge des Vektorssqrt(Dx * Dx + Dy * Dy)
und die Richtung im Bogenmaßatan(Dy / Dx)
. Der kürzeste Weg ist einer der 9 Wege, auf deneni
undj
in denen{-1, 0, 1}
:Die
i
undj
Werte für den kürzesten Weg können direkt ermittelt werden:Vielen Dank, @IlmariKaronen, @SamHocevar und @romkyns für Ihre Hilfe!
quelle
abs(Tx-Sx) < Wx/2
, danni=0
ist es optimal; ansonsten ist die optimale Wahli=-1
oderi=1
, je nach VorzeichenTx-Sx
. Gleiches gilt fürTy-Sy
undj
.Berechnen Sie einen möglichen Richtungsvektor, auch wenn er nicht der kürzeste ist, und wickeln Sie seine X-Koordinate so um, dass er sich im
[-MapX/2,MapX/2]
Bereich befindet. Dies gilt auch für Y:Das ist es! Sie erhalten die Entfernung auch ohne weitere Berechnungen:
quelle
vec2 toroidalNearestWay (vec2 from, vec2 to, vec2 mapSize) { return (mod((to - from + 3.0 * mapSize / 2.0), mapSize)) - mapSize / 2.0; }
Ich denke, es gibt eine Reihe von Möglichkeiten, dies zu tun. Hier sind 2, die mir auf den ersten Blick einfallen:
# 1: Fälle manuell behandeln
Es gibt genau 10 Fälle, die auftreten können:
S
Für jede der umgebenden Kacheln handelt es sich jedoch um Permutationen verschiedener Berechnungen für die X- oder Y-Entfernungskomponente. Da es sich nur um eine begrenzte Anzahl von Fällen handelt, können Sie die Berechnung der Fälle einfach fest programmieren und den kürzesten Abstand zwischen allen Fällen ermitteln.
Hier ist eine Illustration von 2 Fällen zum Auffinden
dx
. Fall 1,T
in dem sich die gleiche Kachel wie befindetS
, ist dx gerechtS.x - T.x
. Für die Kacheln rechtsdx
wird berechnet alsTileWidth - S.x + T.x
.Bestimmen Sie als kleine Optimierung den Mindestabstand, bevor Sie eine Quadratwurzel ziehen. Dann sparen Sie sich bis zu 7
sqrt
Anrufe.# 2: Zählen Sie die Koordinaten auf
Wenn Sie räumlich etwas "Fließenderes" tun möchten, wie einen Pfadfindungsalgorithmus, abstrahieren Sie einfach die Koordinaten, damit Ihr Pfadfindungsalgorithmus nicht einmal erkennt, dass die Welt aus sich wiederholenden Kacheln besteht. Der Pfadfindungsalgorithmus könnte theoretisch unendlich in jede Richtung gehen (ok, Sie werden durch numerische Grenzen begrenzt sein, aber Sie verstehen den Punkt).
Machen Sie sich für eine einfache Entfernungsberechnung nicht die Mühe.
quelle
Kümmere dich nicht um die "9 Richtungen". Der Grund ist, dass es 5 entartete Fälle unter diesen 9 gibt: "gerader Norden", "gerader Westen", "gerader Süden", "gerader Osten" und "identisch". Zum Beispiel ist der gerade Norden degeneriert, weil Nordwesten und Nordosten sich vereinigen und dasselbe Ergebnis erzielen.
Sie müssen also 4 Richtungen berechnen und können einfach das Minimum auswählen.
quelle
Vielen Dank für all die Antworten, die ich am Ende mit Toomai von Scott Chamberlain erhalten habe. Ich musste auch ein paar Änderungen vornehmen, da mein Koordinatensystem oben links mit y beginnt und sich erhöht, wenn Sie sich nach unten bewegen (im Vergleich zu normalen Diagrammkoordinaten für y grundsätzlich invertiert).
Ich habe geschrieben, falls jemand diese Seite findet und dasselbe umgekehrte System hat.
quelle
y
. Es ist , weil das gewünschte Verhalten angeblich wickeln Koordinaten auf der Welt Rand, während der Code , den Sie erneut verwendet werden gespiegelt die Koordinaten an jeder Grenze.