|
| 1 | +#include <bits/stdc++.h> |
| 2 | +using namespace std; |
| 3 | + |
| 4 | +#define rep(i, a, b) for(int i = a; i < int(b); ++i) |
| 5 | +#define trav(a, v) for(auto& a : v) |
| 6 | +#define all(x) x.begin(), x.end() |
| 7 | +#define sz(x) (int)(x).size() |
| 8 | + |
| 9 | +typedef long long ll; |
| 10 | +typedef pair<int, int> pii; |
| 11 | +typedef vector<int> vi; |
| 12 | + |
| 13 | + |
| 14 | +#include "../content/geometry/SegmentIntersection.h" |
| 15 | +namespace oldImpl { |
| 16 | +template<class P> |
| 17 | +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; |
| 42 | +} |
| 43 | +} |
| 44 | +typedef Point<double> P; |
| 45 | +ostream &operator<<(ostream &os, P p) { return cout << "(" << p.x << "," << p.y << ")"; } |
| 46 | +bool eq(P a, P b) { |
| 47 | + return (a-b).dist()<1e-8; |
| 48 | +} |
| 49 | +int main() { |
| 50 | + rep(t,0,1000000) { |
| 51 | + const int GRID=6; |
| 52 | + P a(rand()%GRID, rand()%GRID), b(rand()%GRID, rand()%GRID), c(rand()%GRID, rand()%GRID), d(rand()%GRID, rand()%GRID); |
| 53 | + P tmp1, tmp2; |
| 54 | + auto res = oldImpl::segmentIntersection(a,b,c,d, tmp1, tmp2); |
| 55 | + auto res2 = segInter(a,b,c,d); |
| 56 | + if (res != sz(res2)) { |
| 57 | + cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl; |
| 58 | + cout<<"old: "<<res<<" new: "<<sz(res2)<<endl; |
| 59 | + } |
| 60 | + assert(res==sz(res2)); |
| 61 | + if (res==1) { |
| 62 | + assert(eq(*res2.begin(), tmp1)); |
| 63 | + } else if (res==2) { |
| 64 | + vector<P> a(res2.begin(), res2.end()); |
| 65 | + vector<P> b({tmp1, tmp2}); |
| 66 | + sort(all(b)); |
| 67 | + assert(eq(a[0], b[0]) && eq(a[1],b[1])); |
| 68 | + } |
| 69 | + } |
| 70 | + cout<<"Tests passed!"<<endl; |
| 71 | +} |
0 commit comments