Skip to content

Commit e5b85b7

Browse files
committed
Add failure example for MIT's halfplane code
1 parent 8571390 commit e5b85b7

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

content/geometry/PolygonArea.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include "Point.h"
1313

1414
template<class T>
15-
T polygonArea2(vector<Point<T>>& v) {
15+
T polygonArea2(vector<Point<T>> v) {
16+
if (sz(v) < 3) return 0;
1617
T a = v.back().cross(v[0]);
1718
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]);
1819
return a;

fuzz-tests/geometry/HalfPlane.cpp

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ double Intersection_Area(vector <Line> b) {
9292
vector <P> s;
9393
for (i = q; i <= h; i++) s.push_back(ca[i].intpo(ca[i + 1]));
9494
s.push_back(s[0]);
95+
// for (auto i: s) cout<<i<<' ';
96+
// cout<<endl;
9597
double ans = 0;
9698
for (i = 0; i < (int) s.size() - 1; i++) ans += s[i].cross(s[i + 1]);
9799
return ans / 2;
@@ -104,16 +106,19 @@ vector<MIT::Line> convert(vector<Line> x) {
104106
return res;
105107
}
106108

107-
const double INF = 1e9;
108-
void addInf(vector<Line> &res) {
109+
const double INF = 1e1;
110+
const double EPS = 1e-8;
111+
void addInf(vector<Line> &res, double INF=INF) {
109112
vector<P> infPts({P(INF, INF), P(-INF, INF), P(-INF, -INF), P(INF, -INF)});
110113
for (int i=0; i<4; i++)
111114
res.push_back({infPts[i], infPts[(i+1)%4]});
112115
}
116+
P randPt(int lim = INF) {
117+
return P(rand() % lim, rand() % lim);
118+
}
113119
void test1() {
114120
vector<Line> t({{P(0,0),P(5,0)}, {P(5,-2), P(5,2)}, {P(5,2),P(2,2)}, {P(0,3),P(0,-3)}});
115121
auto res = halfPlaneIntersection(t);
116-
cout<<MIT::Intersection_Area(convert(t))<<endl;
117122
assert(polygonArea2(res) == 20);
118123
addInf(t);
119124
res = halfPlaneIntersection(t);
@@ -123,11 +128,11 @@ void testInf() {
123128
vector<Line> t({{P(0,0), P(5,0)}});
124129
addInf(t);
125130
auto res = halfPlaneIntersection(t);
126-
assert(polygonArea2(res)/4e18);
131+
assert(polygonArea2(res)/(4*INF*INF) == 1);
127132
t = vector<Line>({{P(0,0), P(5,0)}, {P(0,0), P(0,5)}});
128133
addInf(t);
129134
res = halfPlaneIntersection(t);
130-
assert(polygonArea2(res)/2e18 == 1);
135+
assert(polygonArea2(res)/(2*INF*INF) == 1);
131136
}
132137
void testLine() {
133138
vector<Line> t({{P(0,0), P(5,0)}, {P(5,0), P(0,0)}});
@@ -150,11 +155,40 @@ void testEmpty() {
150155
auto res = halfPlaneIntersection(t);
151156
assert(sz(res) == 0);
152157
}
158+
void testRandom() {
159+
for (int i=0; i<1000; i++) {
160+
vector<Line> t;
161+
for (int i=0; i<3; i++){
162+
Line cand{P(0,0), P(0,0)};
163+
while (cand[0] == cand[1])
164+
cand = {randPt(), randPt()};
165+
t.push_back(cand);
166+
}
167+
addInf(t);
168+
auto res = halfPlaneIntersection(t);
169+
double area = MIT::Intersection_Area(convert(t));
170+
double diff = abs(2*area - polygonArea2(res));
171+
if (diff > EPS) {
172+
cout<<diff<<' '<<area<<' '<<endl;
173+
for (auto i: t) cout<<i[0]<<"->"<<i[1]<<' ';
174+
cout<<endl;
175+
for (auto i: res) cout<<i<<',';
176+
cout<<endl;
177+
}
178+
assert(diff < EPS);
179+
}
180+
}
153181

154182
int main() {
155-
test1();
156-
testInf();
157-
testLine();
158-
testPoint();
159-
testEmpty();
183+
// test1();
184+
// testInf();
185+
// testLine();
186+
// testPoint();
187+
// testEmpty();
188+
// testRandom();
189+
vector<Line> t({{P(9,8), P(9,1)}, {P(3,3),P(3,5)},{P(7,6),P(0,8)}});
190+
addInf(t);
191+
cout<<polygonArea2(halfPlaneIntersection(t))<<endl;
192+
cout<<MIT::Intersection_Area(convert(t))<<endl;
193+
cout<<"Tests passed!"<<endl;
160194
}

0 commit comments

Comments
 (0)