Eli, der von dir festgelegte Code ist falsch. Ein Punkt in der Nähe der Linie, auf der das Segment liegt, aber weit weg von einem Ende des Segments würde fälschlicherweise in der Nähe des Segments beurteilt werden. Aktualisierung: Die falsche Antwort, die erwähnt wurde, wird nicht mehr akzeptiert.
Hier ist etwas korrekter Code, in C++. Er setzt einen 2D-Vektor class vec2 {float x, y;}
voraus, im Wesentlichen mit Operatoren zum Addieren, Subtrahieren, Skalieren usw. und einer Funktion zur Entfernung und zum Skalarprodukt (d.h. x1 x2 + y1 y2
).
float minimum_distance(vec2 v, vec2 w, vec2 p) {
// Gib den minimalen Abstand zwischen dem Linienabschnitt vw und dem Punkt p zurück
const float l2 = length_squared(v, w); // d.h. |w-v|^2 - ein Wurzel vermeiden
if (l2 == 0.0) return distance(p, v); // Fall v == w
// Betrachte die Linie, die den Abschnitt erweitert, parametrisiert als v + t (w - v).
// Wir finden die Projektion des Punktes p auf die Linie.
// Sie fällt dort, wo t = [(p-v) . (w-v)] / |w-v|^2
// Wir begrenzen t auf [0,1], um mit Punkten außerhalb des Abschnitts vw umzugehen.
const float t = max(0, min(1, dot(p - v, w - v) / l2));
const vec2 projection = v + t * (w - v); // Die Projektion fällt auf den Abschnitt
return distance(p, projection);
}
EDIT: Ich brauchte eine Javascript-Implementierung, also hier ist sie, ohne Abhängigkeiten (oder Kommentare, aber es ist eine direkte Umsetzung des oben Genannten). Punkte werden als Objekte mit den Attributen x
und y
dargestellt.
function sqr(x) { return x * x }
function dist2(v, w) { return sqr(v.x - w.x) + sqr(v.y - w.y) }
function distToSegmentSquared(p, v, w) {
var l2 = dist2(v, w);
if (l2 == 0) return dist2(p, v);
var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
t = Math.max(0, Math.min(1, t));
return dist2(p, { x: v.x + t * (w.x - v.x),
y: v.y + t * (w.y - v.y) });
}
function distToSegment(p, v, w) { return Math.sqrt(distToSegmentSquared(p, v, w)); }
EDIT 2: Ich brauchte eine Java-Version, aber noch wichtiger, ich brauchte sie in 3D anstelle von 2D.
float dist_to_segment_squared(float px, float py, float pz, float lx1, float ly1, float lz1, float lx2, float ly2, float lz2) {
float line_dist = dist_sq(lx1, ly1, lz1, lx2, ly2, lz2);
if (line_dist == 0) return dist_sq(px, py, pz, lx1, ly1, lz1);
float t = ((px - lx1) * (lx2 - lx1) + (py - ly1) * (ly2 - ly1) + (pz - lz1) * (lz2 - lz1)) / line_dist;
t = constrain(t, 0, 1);
return dist_sq(px, py, pz, lx1 + t * (lx2 - lx1), ly1 + t * (ly2 - ly1), lz1 + t * (lz2 - lz1));
}
Hier sind in den Funktionsparametern der betreffende Punkt und der Linienabschnitt hat die Endpunkte und . Die Funktion dist_sq
(die angenommen wird) findet das Quadrat des Abstands zwischen zwei Punkten.
0 Stimmen
Ich weiß nicht, wie du Linien und Punkte darstellst, aber hier findest du die gesamte Mathematik, die du benötigst, um anzufangen. Es sollte nicht allzu schwer sein, herauszufinden, was du tun musst.
0 Stimmen
Kann die Antwort auf diese Frage behoben/geändert werden? Derzeit bezieht sie sich nicht auf die Frage (den Abschnitt), sondern auf eine Zeile.
4 Stimmen
@ArthurKalliokoski: Dieser Link ist tot, aber ich habe eine Kopie gefunden: paulbourke.net/geometry/pointline
0 Stimmen
Muss das selbst suchen und bin zufällig auf dies von Google gestoßen - wenn jemand nach einer Implementierung sucht und mit Python gehen kann, hat Shapely dies. Du suchst nach der
LineString
Klasse für den Pfad.12 Stimmen
@GuntherStruyf: Dieser Link ist auch tot, aber dieser ähnliche Link funktioniert: paulbourke.net/geometry/pointlineplane
1 Stimmen
Wenn jemand nach dem Abstand zwischen einem Punkt und einer Linie sucht, nicht zwischen einem Punkt und einem Liniensegment, sehen Sie sich diesen Link an: gist.github.com/rhyolight/2846020
1 Stimmen
Der obige Link ist tot. Hier ist Pseudocode und ein C++ Beispiel, erklärt und so ausführlich wie in einem Lehrbuch abgeleitet, geomalgorithms.com/a02-_lines.html
0 Stimmen
brilliant.org/wiki/…