Hier ist ein anderer Weg, um dies zu erreichen, mit Code in C++. Bei zwei Punkten, l1 und l2, ist es trivial, das Liniensegment zwischen ihnen wie folgt auszudrücken
l1 + A(l2 - l1)
wobei 0 <= A <= 1. Dies ist die so genannte Vektordarstellung einer Geraden, falls Sie mehr daran interessiert sind, als sie nur für dieses Problem zu verwenden. Wir können die x- und y-Komponenten davon aufspalten, was ergibt:
x = l1.x + A(l2.x - l1.x)
y = l1.y + A(l2.y - l1.y)
Man nehme einen Punkt (x, y) und setze seine x- und y-Komponenten in diese beiden Ausdrücke ein, um A zu lösen. Der Punkt liegt auf der Linie, wenn die Lösungen für A in beiden Ausdrücken gleich sind und 0 <= A <= 1. Da das Lösen von A eine Division erfordert, gibt es spezielle Fälle, die behandelt werden müssen, um die Division durch Null zu verhindern, wenn das Liniensegment horizontal oder vertikal ist. Die endgültige Lösung lautet wie folgt:
// Vec2 is a simple x/y struct - it could very well be named Point for this use
bool isBetween(double a, double b, double c) {
// return if c is between a and b
double larger = (a >= b) ? a : b;
double smaller = (a != larger) ? a : b;
return c <= larger && c >= smaller;
}
bool pointOnLine(Vec2<double> p, Vec2<double> l1, Vec2<double> l2) {
if(l2.x - l1.x == 0) return isBetween(l1.y, l2.y, p.y); // vertical line
if(l2.y - l1.y == 0) return isBetween(l1.x, l2.x, p.x); // horizontal line
double Ax = (p.x - l1.x) / (l2.x - l1.x);
double Ay = (p.y - l1.y) / (l2.y - l1.y);
// We want Ax == Ay, so check if the difference is very small (floating
// point comparison is fun!)
return fabs(Ax - Ay) < 0.000001 && Ax >= 0.0 && Ax <= 1.0;
}
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.