Skip to content

Commit dcd29eb

Browse files
committed
Updated headers
1 parent fafb601 commit dcd29eb

File tree

5 files changed

+56
-72
lines changed

5 files changed

+56
-72
lines changed
Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,45 @@
11
/**
2-
* Author: Ulf Lundstrom
3-
* Date: 2009-03-21
2+
* Author: Victor Lecomte, chilli
3+
* Date: 2019-04-27
44
* License: CC0
5-
* Source:
5+
* Source: https://vlecomte.github.io/cp-geo.pdf
66
* Description:\\
77
\begin{minipage}{75mm}
8-
If a unique intersetion point between the line segments going from s1 to e1 and from s2 to e2 exists r1 is set to this point and 1 is returned.
9-
If no intersection point exists 0 is returned and if infinitely many exists 2 is returned and r1 and r2 are set to the two ends of the common line.
8+
If a unique intersetion point between the line segments going from s1 to e1 and from s2 to e2 exists then it is returned.
9+
If no intersection point exists an empty vector is returned. If infinitely many exist a vector with 2 elements is returned.
1010
The wrong position will be returned if P is Point<int> and the intersection point does not have integer coordinates.
1111
Products of three coordinates are used in intermediate steps so watch out for overflow if using int or long long.
12-
Use segmentIntersectionQ to get just a true/false answer.
1312
\end{minipage}
1413
\begin{minipage}{15mm}
1514
\includegraphics[width=\textwidth]{../content/geometry/SegmentIntersection}
1615
\end{minipage}
17-
* Status: Well tested with unitTest and with Kattis problem intersection.
16+
* Status: Well tested with fuzz-test and with Kattis problem intersection.
1817
* Usage:
19-
* Point<double> intersection, dummy;
20-
* if (segmentIntersection(s1,e1,s2,e2,intersection,dummy)==1)
21-
* cout << "segments intersect at " << intersection << endl;
18+
* vector<P> inter = segInter(s1,e1,s2,e2);
19+
* if (inter.size()==1)
20+
* cout << "segments intersect at " << inter[0] << endl;
2221
*/
2322
#pragma once
2423

2524
#include "Point.h"
2625
#include "onSegment.h"
27-
#include "SegmentIntersectionProper.h"
2826

29-
template<class P> set<P> segInter(P a, P b, P c, P d) {
30-
P out;
31-
if (segInterProper(a, b, c, d, out)) return {out};
32-
set<P> s;
33-
if (onSegment(c, d, a)) s.insert(a);
34-
if (onSegment(c, d, b)) s.insert(b);
35-
if (onSegment(a, b, c)) s.insert(c);
36-
if (onSegment(a, b, d)) s.insert(d);
37-
return s;
27+
template <class P> bool segInterProper(P a, P b, P c, P d, P &out) {
28+
double oa = c.cross(d, a), ob = c.cross(d, b),
29+
oc = a.cross(b, c), od = a.cross(b, d);
30+
if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0) {
31+
out = (a * ob - b * oa) / (ob - oa);
32+
return true;
33+
}
34+
return false;
35+
}
36+
template<class P> vector<P> segInter(P a, P b, P c, P d) {
37+
P out;
38+
if (segInterProper(a, b, c, d, out)) return {out};
39+
set<P> s;
40+
if (onSegment(c, d, a)) s.insert(a);
41+
if (onSegment(c, d, b)) s.insert(b);
42+
if (onSegment(a, b, c)) s.insert(c);
43+
if (onSegment(a, b, d)) s.insert(d);
44+
return vector<P>(all(s));
3845
}

content/geometry/SegmentIntersectionProper.h

Lines changed: 0 additions & 23 deletions
This file was deleted.

content/geometry/chapter.tex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ \section{Geometric primitives}
66
\kactlimport{SegmentDistance.h}
77
\columnbreak
88
\kactlimport{SegmentIntersection.h}
9-
\kactlimport{SegmentIntersectionProper.h}
109
\columnbreak
1110
\kactlimport{lineIntersection.h}
1211
\kactlimport{sideOf.h}

content/geometry/onSegment.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/**
2-
* Author: Ulf Lundstrom
3-
* Date: 2009-04-09
2+
* Author: Victor Lecomte, chilli
3+
* Date: 2019-04-26
44
* License: CC0
5-
* Source: Basic geometry
6-
* Description: Returns true iff p lies on the line segment from s to e. Intended for use with e.g. Point<long long> where overflow is an issue. Use (segDist(s,e,p)<=epsilon) instead when using Point<double>.
5+
* Source: https://vlecomte.github.io/cp-geo.pdf
6+
* Description: Returns true iff p lies on the line segment from s to e. Intended for use with e.g. Point<long long> where overflow is an issue.
77
* Status:
88
*/
99
#pragma once

fuzz-tests/segmentIntersection.cpp

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,30 @@ typedef vector<int> vi;
1515
namespace oldImpl {
1616
template<class P>
1717
int segmentIntersection(const P& s1, const P& e1,
18-
const P& s2, const P& e2, P& r1, P& r2) {
19-
if (e1==s1) {
20-
if (e2==s2) {
21-
if (e1==e2) { r1 = e1; return 1; } //all equal
22-
else return 0; //different point segments
23-
} else return segmentIntersection(s2,e2,s1,e1,r1,r2);//swap
24-
}
25-
//segment directions and separation
26-
P v1 = e1-s1, v2 = e2-s2, d = s2-s1;
27-
auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d);
28-
if (a == 0) { //if parallel
29-
auto b1=s1.dot(v1), c1=e1.dot(v1),
30-
b2=s2.dot(v1), c2=e2.dot(v1);
31-
if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
32-
return 0;
33-
r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
34-
r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
35-
return 2-(r1==r2);
36-
}
37-
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
38-
if (0<a1 || a<-a1 || 0<a2 || a<-a2)
39-
return 0;
40-
r1 = s1-v1*a2/a;
41-
return 1;
18+
const P& s2, const P& e2, P& r1, P& r2) {
19+
if (e1==s1) {
20+
if (e2==s2) {
21+
if (e1==e2) { r1 = e1; return 1; } //all equal
22+
else return 0; //different point segments
23+
} else return segmentIntersection(s2,e2,s1,e1,r1,r2);//swap
24+
}
25+
//segment directions and separation
26+
P v1 = e1-s1, v2 = e2-s2, d = s2-s1;
27+
auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d);
28+
if (a == 0) { //if parallel
29+
auto b1=s1.dot(v1), c1=e1.dot(v1),
30+
b2=s2.dot(v1), c2=e2.dot(v1);
31+
if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
32+
return 0;
33+
r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
34+
r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
35+
return 2-(r1==r2);
36+
}
37+
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
38+
if (0<a1 || a<-a1 || 0<a2 || a<-a2)
39+
return 0;
40+
r1 = s1-v1*a2/a;
41+
return 1;
4242
}
4343
}
4444
typedef Point<double> P;
@@ -67,4 +67,5 @@ int main() {
6767
assert(eq(a[0], b[0]) && eq(a[1],b[1]));
6868
}
6969
}
70+
cout<<"Tests passed!"<<endl;
7071
}

0 commit comments

Comments
 (0)