@@ -81,17 +81,15 @@ Here is a sample, direct implementation of the algorithm, with comments explaini
81
81
Simple point/vector and half-plane structs:
82
82
83
83
``` cpp
84
- // Redefine epsilon and infinity as necessary. Be mindful of precision errors.
85
- const long double eps = 1e-9 , inf = 1e9 ;
84
+ const long double eps = 1e-8 ;
85
+ const long double inf = 1e6 ; // Modify as needed based on input scale.
86
86
87
87
// Basic point/vector struct.
88
- struct Point {
89
-
88
+ struct Point {
90
89
long double x, y;
91
90
explicit Point(long double x = 0, long double y = 0) : x(x), y(y) {}
92
91
93
- // Addition, substraction, multiply by constant, dot product, cross product.
94
-
92
+ // Addition, subtraction, multiply by constant, dot product, cross product.
95
93
friend Point operator + (const Point& p, const Point& q) {
96
94
return Point(p.x + q.x, p.y + q.y);
97
95
}
@@ -102,10 +100,10 @@ struct Point {
102
100
103
101
friend Point operator * (const Point& p, const long double& k) {
104
102
return Point(p.x * k, p.y * k);
105
- }
106
-
103
+ }
104
+
107
105
friend long double dot(const Point& p, const Point& q) {
108
- return p.x * q.x + p.y * q.y;
106
+ return p.x * q.x + p.y * q.y;
109
107
}
110
108
111
109
friend long double cross(const Point& p, const Point& q) {
@@ -114,10 +112,8 @@ struct Point {
114
112
};
115
113
116
114
// Basic half-plane struct.
117
- struct Halfplane {
118
-
119
- // 'p' is a passing point of the line and 'pq' is the direction vector of the line.
120
- Point p, pq;
115
+ struct Halfplane {
116
+ Point p, pq; // 'p' is a passing point of the line, 'pq' is the direction vector of the line.
121
117
long double angle;
122
118
123
119
Halfplane() {}
@@ -131,23 +127,42 @@ struct Halfplane {
131
127
return cross(pq, r - p) < -eps;
132
128
}
133
129
134
- // Comparator for sorting.
130
+ // Comparator for sorting.
135
131
bool operator < (const Halfplane& e) const {
136
132
return angle < e.angle;
137
- }
133
+ }
138
134
139
135
// Intersection point of the lines of two half-planes. It is assumed they're never parallel.
140
136
friend Point inter(const Halfplane& s, const Halfplane& t) {
141
137
long double alpha = cross((t.p - s.p), t.pq) / cross(s.pq, t.pq);
142
138
return s.p + (s.pq * alpha);
143
139
}
144
140
};
141
+
142
+ // Function to calculate a dynamic bounding box based on input points.
143
+ Point calculate_bounding_box(const std::vector<Point >& points) {
144
+ long double maxX = -inf, maxY = -inf;
145
+ long double minX = inf, minY = inf;
146
+
147
+ // Traverse all points to find the bounding box
148
+ for (const Point& pt : points) {
149
+ if (pt.x > maxX) maxX = pt.x;
150
+ if (pt.x < minX) minX = pt.x;
151
+ if (pt.y > maxY) maxY = pt.y;
152
+ if (pt.y < minY) minY = pt.y;
153
+ }
154
+
155
+ // Use the most extreme points to define the bounding box
156
+ Point bbox((maxX - minX) * 2, (maxY - minY) * 2); // Making the box larger for stability
157
+ return bbox;
158
+ }
159
+
145
160
```
146
161
147
162
Algorithm:
148
163
149
164
```cpp
150
- // Actual algorithm
165
+ // Actual Algorithm
151
166
vector<Point> hp_intersect(vector<Halfplane>& H) {
152
167
153
168
Point box[4] = { // Bounding box in CCW order
@@ -157,7 +172,7 @@ vector<Point> hp_intersect(vector<Halfplane>& H) {
157
172
Point(inf, -inf)
158
173
};
159
174
160
- for(int i = 0; i< 4; i++) { // Add bounding box half-planes.
175
+ for(int i = 0; i < 4; i++) { // Add bounding box half-planes.
161
176
Halfplane aux(box[i], box[(i+1) % 4]);
162
177
H.push_back(aux);
163
178
}
@@ -166,40 +181,41 @@ vector<Point> hp_intersect(vector<Halfplane>& H) {
166
181
sort(H.begin(), H.end());
167
182
deque<Halfplane> dq;
168
183
int len = 0;
184
+
169
185
for(int i = 0; i < int(H.size()); i++) {
170
186
171
- // Remove from the back of the deque while last half-plane is redundant
187
+ // Remove from the back of the deque while the last half-plane is redundant
172
188
while (len > 1 && H[i].out(inter(dq[len-1], dq[len-2]))) {
173
189
dq.pop_back();
174
190
--len;
175
191
}
176
192
177
- // Remove from the front of the deque while first half-plane is redundant
193
+ // Remove from the front of the deque while the first half-plane is redundant
178
194
while (len > 1 && H[i].out(inter(dq[0], dq[1]))) {
179
195
dq.pop_front();
180
196
--len;
181
197
}
182
-
183
- // Special case check: Parallel half-planes
198
+
199
+ // Special case: Check for parallel half-planes
184
200
if (len > 0 && fabsl(cross(H[i].pq, dq[len-1].pq)) < eps) {
185
- // Opposite parallel half-planes that ended up checked against each other.
186
- if (dot(H[i].pq, dq[len-1].pq) < 0.0)
187
- return vector<Point>();
188
-
189
- // Same direction half-plane: keep only the leftmost half-plane.
190
- if (H[i].out(dq[len-1].p)) {
191
- dq.pop_back();
192
- --len;
193
- }
194
- else continue;
201
+ // Opposite parallel half-planes
202
+ if (dot(H[i].pq, dq[len-1].pq) < 0.0)
203
+ return vector<Point>();
204
+
205
+ // Keep only the leftmost half-plane for same direction
206
+ if (H[i].out(dq[len-1].p)) {
207
+ dq.pop_back();
208
+ --len;
209
+ }
210
+ else continue;
195
211
}
196
-
197
- // Add new half-plane
212
+
213
+ // Add the new half-plane
198
214
dq.push_back(H[i]);
199
215
++len;
200
216
}
201
217
202
- // Final cleanup: Check half-planes at the front against the back and vice-versa
218
+ // Final cleanup: Check half-planes at the front and back
203
219
while (len > 2 && dq[0].out(inter(dq[len-1], dq[len-2]))) {
204
220
dq.pop_back();
205
221
--len;
@@ -210,12 +226,12 @@ vector<Point> hp_intersect(vector<Halfplane>& H) {
210
226
--len;
211
227
}
212
228
213
- // Report empty intersection if necessary
229
+ // If less than 3 planes, report empty intersection
214
230
if (len < 3) return vector<Point>();
215
231
216
- // Reconstruct the convex polygon from the remaining half-planes.
232
+ // Reconstruct the convex polygon from the remaining half-planes
217
233
vector<Point> ret(len);
218
- for(int i = 0; i+1 < len; i++) {
234
+ for (int i = 0; i+1 < len; i++) {
219
235
ret[i] = inter(dq[i], dq[i+1]);
220
236
}
221
237
ret.back() = inter(dq[len-1], dq[0]);
0 commit comments