Ich weiß, dass es viele Seiten gibt, die erklären, wie man nach einer Schnittmenge von zwei Zeilen sucht, aber ich finde es absolut langweilig, einfach Code für solch eine einfache mathematische Aufgabe zu kopieren und einzufügen. Je mehr es mich frustriert, dass ich meinen Code nicht zur Arbeit bekommen kann. Ich kenne Fragen mit "Was ist falsch in meinem Code?" sind dumm, aber ich weiß nicht, was zur Hölle ist falsch mit meiner Mathematik/Code, auch mein Code ist schön dokumentiert (außer der zugegebenermaßen schlechten Variablennamen), also denke ich, es sollte jemand sein, der an der Mathematik dahinter interessiert ist :Was ist falsch an meinem Schnittpunktprüfalgorithmus?
bool segment::checkforIntersection(QPointF a, QPointF b) { //line 1: a+bx, line 2: c+dx, note that a and c are called offset and bx and dx are called gradients in this code
QPointF bx = b-a;
double firstGradient = bx.y()/bx.x(); //gradient of line 1
//now we have to calculate the offset of line 1: we have b from a+bx. Since QPointF a is on that line, it is:
//a + b * a.x = a.y with a as free variable, which yields a = a.y - b*a.x.
//One could also use the second point b for this calculation.
double firstOffset = a.y() - firstGradient * a.x();
double secondGradient, secondOffset;
for (int i = 0; i < poscount-3; i++) { //we dont check with the last line, because that could be the same line, as the one that emited intersection checking
QPointF c = pos[i];
QPointF d = pos[i+1];
QPointF dx = d-c;
secondGradient = dx.y()/dx.x(); //same formula as above
secondOffset = c.y() - secondGradient * c.x();
//a+bx=c+dx <=> a-c = (d-b)x <=> (a-c)/(d-b) = x
double x = (firstOffset - secondOffset)/(secondGradient - firstGradient);
//we have to check, if those lines intersect with a x \in [a.x,b.x] and x \in [c.x,d.x]. If this is the case, we have a collision
if (x >= a.x() && x <= b.x() && x >= c.x() && x <= d.x()) {
return true;
}
}
return false;
}
Was dies tut, hat es 4 Punkte a, b, c, d (Zeile 1: a - b, Zeile 2: c - d) haben (die for-Schleife ignorieren), die ein absoluter x- und y-Wert. Zuerst berechnet es die Steigung der Linien durch Berechnung von Delta/Delta. Dann berechnet er den Offset, indem er den Punkt a (bzw. c) auf den Linien verwendet. Auf diese Weise transformierten wir die 4 Punkte in eine mathematische Darstellung dieser Linien als Gleichung a + bx, während ax von 0 bedeutet, dass wir am ersten Punkt (a/c) sind und ax von 1 bedeutet, dass wir uns am zweiten Punkt befinden (b/d). Als nächstes berechnen wir den Schnittpunkt dieser beiden Linien (Grundalgebra). Danach überprüfen wir, ob der X-Wert der Kreuzung gültig ist. Nach meinem Verständnis ist das alles korrekt. Sieht jemand den Fehler?
Dies wurde empirisch als inkorrekt überprüft. Der Code gibt keine falschen Positive (sagt, es gibt einen Schnittpunkt, wenn es nicht gibt), aber es gibt falsche Negative (sagt, es gibt keinen Schnittpunkt, wenn es tatsächlich ist). Wenn es heißt, dass es eine Kreuzung gibt, ist es richtig, aber wenn es sagt, dass es keine Kreuzung gibt, kann man meinem Algorithmus nicht immer glauben.
Auch hier habe ich online nachgesehen, aber die Algorithmen sind anders (mit ein paar Orientierungstricks und etwas), ich wollte nur meinen eigenen Algorithmus erstellen, ich wäre so froh, wenn jemand helfen könnte. :)
Edit: Hier ist ein minimal reproduzierbar nicht funktionierendes Beispiel, diesmal ohne Qt aber mit nur C++:
#include <iostream>
#include <math.h>
using namespace std;
class Point {
private:
double xval, yval;
public:
// Constructor uses default arguments to allow calling with zero, one,
// or two values.
Point(double x = 0.0, double y = 0.0) {
xval = x;
yval = y;
}
// Extractors.
double x() { return xval; }
double y() { return yval; }
Point sub(Point b)
{
return Point(xval - b.xval, yval - b.yval);
}
};
bool checkforIntersection(Point a, Point b, Point c, Point d) { //line 1: a+bx, line 2: c+dx, note that a and c are called offset and bx and dx are called gradients in this code
Point bx = b.sub(a);
double firstGradient = bx.y()/bx.x(); //gradient of line 1
//now we have to calculate the offset of line 1: we have b from a+bx. Since Point a is on that line, it is:
//a + b * a.x = a.y with a as free variable, which yields a = a.y - b*a.x.
//One could also use the second point b for this calculation.
double firstOffset = a.y() - firstGradient * a.x();
double secondGradient, secondOffset;
Point dx = d.sub(c);
secondGradient = dx.y()/dx.x(); //same formula as above
secondOffset = c.y() - secondGradient * c.x();
//a+bx=c+dx <=> a-c = (d-b)x <=> (a-c)/(d-b) = x
double x = (firstOffset - secondOffset)/(secondGradient - firstGradient);
//we have to check, if those lines intersect with a x \in [a.x,b.x] and x \in [c.x,d.x]. If this is the case, we have a collision
if (x >= a.x() && x <= b.x() && x >= c.x() && x <= d.x()) {
return true;
}
return false;
}
int main(int argc, char const *argv[]) {
if (checkforIntersection(Point(310.374,835.171),Point(290.434,802.354), Point(333.847,807.232), Point(301.03,827.172)) == true) {
cout << "These lines do intersect so I should be printed out\n";
} else {
cout << "The algorithm does not work, so instead I do get printed out\n";
}
return 0;
}
So wie zB ich die Punkte nahmen ~ (310.835) - (290.802), und (333,807) - (301,827). Diese Linien schneiden sich:
\documentclass[crop,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[x=.1cm,y=.1cm]
\draw (310,835) -- (290,802);
\draw (333,807) -- (301,827);
\end{tikzpicture}
\end{document}
Proof of intersection jedoch, wenn die oben C++ Code ausgeführt wird, heißt es, dass sie sich nicht schneiden
Das richtige Werkzeug, solche Probleme ist Ihr Debugger zu lösen. Sie sollten Schritt für Schritt durch Ihren Code * gehen, bevor Sie auf Stack Overflow nachfragen. Für weitere Hilfe lesen Sie bitte [Wie kleine Programme zu debuggen (von Eric Lippert)] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Zumindest sollten Sie Ihre Frage bearbeiten, um ein [minimales, vollständiges und verifizierbares] (http://stackoverflow.com/help/mcve) Beispiel einzufügen, das Ihr Problem zusammen mit den Beobachtungen, die Sie in der Debugger. –
Es ist nicht so, als hätte ich nicht versucht, es selbst zu debuggen. Ich habe versucht, zu debuggen, aber nach einer halben Stunde keine Ahnung mehr zu haben, was falsch ist, gab ich schließlich auf. Vielleicht habe ich nur etwas Mathe falsch verstanden und das ist das Problem. Was ist das Problem zu fragen, nachdem Sie wirklich versucht haben, es selbst zu lösen? – Magnus2552
'Was ist das Problem zu fragen, nachdem Sie wirklich versucht haben, es selbst zu lösen?' Sie vermissen noch die [mcve] –