summaryrefslogtreecommitdiff
path: root/geometry/formulars.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'geometry/formulars.cpp')
-rw-r--r--geometry/formulars.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/geometry/formulars.cpp b/geometry/formulars.cpp
index 1ab57f4..2e7b023 100644
--- a/geometry/formulars.cpp
+++ b/geometry/formulars.cpp
@@ -50,7 +50,7 @@ double orientation(pt a, pt b, pt c) {
return orien < 0 ? -1 : 1;
}
-// Streckenschnitt zwischen a-b und c-d.
+// Test auf Streckenschnitt zwischen a-b und c-d.
bool lineSegmentIntersection(pt a, pt b, pt c, pt d) {
if (orientation(a, b, c) == 0 && orientation(a, b, d) == 0) { // Falls kollinear.
double dist = abs(a - b);
@@ -59,6 +59,32 @@ bool lineSegmentIntersection(pt a, pt b, pt c, pt d) {
return orientation(a, b, c) * orientation(a, b, d) <= 0 && orientation(c, d, a) * orientation(c, d, b) <= 0;
}
+// Berechnet die Schnittpunkte der Strecken a-b und c-d.
+// Enthält entweder keinen Punkt, den einzigen Schnittpunkt oder die Endpunkte der Schnittstrecke.
+// Achtung: operator<, min, max müssen selbst geschrieben werden!
+vector<pt> lineSegmentIntersection(pt a, pt b, pt c, pt d) {
+ vector<pt> result;
+ if (orientation(a, b, c) == 0 && orientation(a, b, d) == 0 &&
+ orientation(c, d, a) == 0 && orientation(c, d, b) == 0) {
+ pt minAB = min(a, b), maxAB = max(a, b), minCD = min(c, d), maxCD = max(c, d);
+ if (minAB < minCD && maxAB < minCD) return result;
+ if (minCD < minAB && maxCD < minAB) return result;
+ pt start = max(minAB, minCD), end = min(maxAB, maxCD);
+ result.push_back(start);
+ if (start != end) result.push_back(end);
+ return result;
+ }
+ double x1 = real(b) - real(a), y1 = imag(b) - imag(a);
+ double x2 = real(d) - real(c), y2 = imag(d) - imag(c);
+ double u1 = (-y1 * (real(a) - real(c)) + x1 * (imag(a) - imag(c))) / (-x2 * y1 + x1 * y2);
+ double u2 = (x2 * (imag(a) - imag(c)) - y2 * (real(a) - real(c))) / (-x2 * y1 + x1 * y2);
+ if (u1 >= 0 && u1 <= 1 && u2 >= 0 && u2 <= 1) {
+ double x = real(a) + u2 * x1, y = imag(a) + u2 * y1;
+ result.push_back(pt(x, y));
+ }
+ return result;
+}
+
// Entfernung von Punkt p zur Gearden durch a-b.
double distToLine(pt a, pt b, pt p) {
return abs(cross(p - a, b - a)) / abs(b - a);