Eine Antwort in C# mit einer Vector2D-Klasse
public static bool IsOnSegment(this Segment2D @this, Point2D c, double tolerance)
{
var distanceSquared = tolerance*tolerance;
// Start of segment to test point vector
var v = new Vector2D( @this.P0, c ).To3D();
// Segment vector
var s = new Vector2D( @this.P0, @this.P1 ).To3D();
// Dot product of s
var ss = s*s;
// k is the scalar we multiply s by to get the projection of c onto s
// where we assume s is an infinte line
var k = v*s/ss;
// Convert our tolerance to the units of the scalar quanity k
var kd = tolerance / Math.Sqrt( ss );
// Check that the projection is within the bounds
if (k <= -kd || k >= (1+kd))
{
return false;
}
// Find the projection point
var p = k*s;
// Find the vector between test point and it's projection
var vp = (v - p);
// Check the distance is within tolerance.
return vp * vp < distanceSquared;
}
Beachten Sie, dass
s * s
ist das Punktprodukt des Segmentvektors über Operatorüberladung in C#
Der Schlüssel liegt darin, die Projektion des Punktes auf die unendliche Linie zu nutzen und zu beobachten, dass die Skalarmenge der Projektion uns trivialerweise sagt, ob die Projektion auf dem Segment liegt oder nicht. Wir können die Grenzen der skalaren Größe anpassen, um eine unscharfe Toleranz zu verwenden.
Wenn die Projektion innerhalb der Grenzen liegt, testen wir einfach, ob der Abstand zwischen dem Punkt und der Projektion innerhalb der Grenzen liegt.
Der Vorteil gegenüber dem Kreuzproduktansatz ist, dass die Toleranz einen sinnvollen Wert hat.
4 Stimmen
Ich sehe in diesen Antworten sehr viel Länge = sqrt(x); das mag funktionieren, aber es ist nicht schnell. Erwägen Sie die Verwendung von length-squared; wenn Sie nur quadrierte Längenwerte miteinander vergleichen, gibt es keinen Genauigkeitsverlust, und Sie sparen langsame Aufrufe von sqrt().
1 Stimmen
Wird der Punkt c auch durch 2 ganze Zahlen dargestellt? Wenn ja, wollen Sie dann wissen, ob c genau auf einer echten Geraden zwischen a und b liegt oder auf der Rasterannäherung der Geraden zwischen a und b? Dies ist eine wichtige Klarstellung.
0 Stimmen
Eine ähnliche Frage wurde hier gestellt: stackoverflow.com/q/31346862/1914034 mit einer Lösung, wenn ein Pufferabstand zur Linie erforderlich ist
0 Stimmen
Verwandt: Ermitteln, ob der Shapely-Punkt innerhalb eines LineString/MultiLineString liegt
2 Stimmen
Warnung an zukünftige Leser: Eine ganze Reihe von Antworten sind falsch oder unvollständig. Ein paar Randfälle, die häufig nicht funktionieren, sind horizontale und vertikale Linien.