@@ -135,11 +135,13 @@ void ContactPatchSolver::computePatch(const ShapeType1& s1,
135
135
// Segment-Segment case
136
136
// We compute the determinant; if it is non-zero, the intersection
137
137
// has already been computed: it's `Contact::pos`.
138
- const Vec2f& a = this ->support_set_shape1 .points ()[0 ];
139
- const Vec2f& b = this ->support_set_shape1 .points ()[1 ];
138
+ const SupportSet::Polygon& pts1 = this ->support_set_shape1 .points ();
139
+ const Vec2f& a = pts1[0 ];
140
+ const Vec2f& b = pts1[1 ];
140
141
141
- const Vec2f& c = this ->support_set_shape2 .points ()[0 ];
142
- const Vec2f& d = this ->support_set_shape2 .points ()[1 ];
142
+ const SupportSet::Polygon& pts2 = this ->support_set_shape2 .points ();
143
+ const Vec2f& c = pts1[0 ];
144
+ const Vec2f& d = pts2[1 ];
143
145
144
146
const FCL_REAL det =
145
147
(b (0 ) - a (0 )) * (d (1 ) - c (1 )) >= (b (1 ) - a (1 )) * (c (0 ) - d (0 ));
@@ -153,19 +155,20 @@ void ContactPatchSolver::computePatch(const ShapeType1& s1,
153
155
154
156
const Vec2f cd = (d - c);
155
157
const FCL_REAL l = cd.squaredNorm ();
158
+ ContactPatch::Polygon& patch = contact_patch.points ();
156
159
157
160
// Project a onto [c, d]
158
161
FCL_REAL t1 = (a - c).dot (cd);
159
162
t1 = (t1 >= l) ? 1.0 : ((t1 <= 0 ) ? 0.0 : (t1 / l));
160
163
const Vec2f p1 = c + t1 * cd;
161
- contact_patch. points () .emplace_back (p1);
164
+ patch .emplace_back (p1);
162
165
163
166
// Project b onto [c, d]
164
167
FCL_REAL t2 = (b - c).dot (cd);
165
168
t2 = (t2 >= l) ? 1.0 : ((t2 <= 0 ) ? 0.0 : (t2 / l));
166
169
const Vec2f p2 = c + t2 * cd;
167
170
if ((p1 - p2).squaredNorm () >= eps) {
168
- contact_patch. points () .emplace_back (p2);
171
+ patch .emplace_back (p2);
169
172
}
170
173
return ;
171
174
}
@@ -180,70 +183,77 @@ void ContactPatchSolver::computePatch(const ShapeType1& s1,
180
183
//
181
184
// The Sutherland-Hodgman algorithm needs the clipper to be at least a
182
185
// triangle.
183
- SupportSet* clipper = nullptr ;
184
- SupportSet* current = nullptr ;
185
- SupportSet* previous = &(this ->support_set_buffer );
186
+ SupportSet::Polygon* clipper_ptr = nullptr ;
187
+ SupportSet::Polygon* current_ptr = nullptr ;
188
+ SupportSet::Polygon* previous_ptr = &(this ->support_set_buffer . points () );
186
189
if (support_set_shape2.size () == 2 ) {
187
190
// Use the first shape as clipper, second as clipped.
188
- clipper = &(this ->support_set_shape1 );
189
- current = &(this ->support_set_shape2 );
191
+ clipper_ptr = &(this ->support_set_shape1 . points () );
192
+ current_ptr = &(this ->support_set_shape2 . points () );
190
193
} else {
191
194
// Use the second shape as clipper, first as clipped.
192
- clipper = &(this ->support_set_shape2 );
193
- current = &(this ->support_set_shape1 );
195
+ clipper_ptr = &(this ->support_set_shape2 . points () );
196
+ current_ptr = &(this ->support_set_shape1 . points () );
194
197
}
195
198
196
- const size_t clipper_size = clipper->points ().size ();
199
+ const SupportSet::Polygon& clipper = *(clipper_ptr);
200
+ const size_t clipper_size = clipper.size ();
197
201
198
202
for (size_t i = 0 ; i < clipper_size; ++i) {
199
- const Vec2f a = clipper-> point (i) ;
200
- const Vec2f b = clipper-> point (( i + 1 ) % clipper_size) ;
203
+ const Vec2f a = clipper[i] ;
204
+ const Vec2f b = clipper[( i + 1 ) % clipper_size] ;
201
205
202
206
// Swap current/previous
203
- SupportSet* tmp = previous;
204
- previous = current;
205
- current = tmp;
206
-
207
- current->points ().clear ();
208
- const size_t previous_size = previous->size ();
207
+ SupportSet::Polygon* tmp_ptr = previous_ptr;
208
+ previous_ptr = current_ptr;
209
+ current_ptr = tmp_ptr;
210
+
211
+ const SupportSet::Polygon& previous = *(previous_ptr);
212
+ SupportSet::Polygon& current = *(current_ptr);
213
+ current.clear ();
214
+ const size_t previous_size = previous.size ();
209
215
for (size_t j = 0 ; j < previous_size; ++j) {
210
- const Vec2f vcurrent = previous-> point (j) ;
211
- const Vec2f vnext = previous-> point (( j + 1 ) % previous_size) ;
216
+ const Vec2f vcurrent = previous[j] ;
217
+ const Vec2f vnext = previous[( j + 1 ) % previous_size] ;
212
218
if (pointIsInsideClippingRegion (vcurrent, a, b)) {
213
- current-> points () .emplace_back (vcurrent);
219
+ current.emplace_back (vcurrent);
214
220
if (!pointIsInsideClippingRegion (vnext, a, b)) {
215
221
const Vec2f p = computeLineSegmentIntersection (a, b, vcurrent, vnext);
216
- current-> points () .emplace_back (p);
222
+ current.emplace_back (p);
217
223
}
218
224
} else if (pointIsInsideClippingRegion (vnext, a, b)) {
219
225
const Vec2f p = computeLineSegmentIntersection (a, b, vcurrent, vnext);
220
- current-> points () .emplace_back (p);
226
+ current.emplace_back (p);
221
227
}
222
228
}
223
- if (current-> size () == 0 ) {
229
+ if (current. size () == 0 ) {
224
230
// No intersection found, the algo can early stop.
225
231
break ;
226
232
}
227
233
}
228
234
229
- if (current ->size () <= 1 ) {
235
+ if (current_ptr ->size () <= 1 ) {
230
236
contact_patch.addPoint (contact.pos );
231
237
return ;
232
238
}
233
239
234
- this ->getResult (current , contact_patch);
240
+ this ->getResult (current_ptr , contact_patch);
235
241
}
236
242
237
243
// ============================================================================
238
- inline void ContactPatchSolver::getResult (const ContactPatch* result,
239
- ContactPatch& contact_patch) const {
244
+ inline void ContactPatchSolver::getResult (
245
+ const ContactPatch::Polygon* result_ptr,
246
+ ContactPatch& contact_patch) const {
240
247
assert (this ->max_patch_size > 3 );
241
- if (result->size () <= this ->max_patch_size ) {
242
- contact_patch.points ().emplace_back (result->points ()[0 ]);
243
- for (size_t i = 1 ; i < result->size (); ++i) {
244
- if ((contact_patch.points ().back () - result->points ()[i]).squaredNorm () >
248
+ const ContactPatch::Polygon& result = *(result_ptr);
249
+ ContactPatch::Polygon& patch = contact_patch.points ();
250
+
251
+ if (result.size () <= this ->max_patch_size ) {
252
+ patch.emplace_back (result[0 ]);
253
+ for (size_t i = 1 ; i < result.size (); ++i) {
254
+ if ((patch.back () - result[i]).squaredNorm () >
245
255
Eigen::NumTraits<FCL_REAL>::dummy_precision ()) {
246
- contact_patch. points (). emplace_back (result-> points () [i]);
256
+ patch. emplace_back (result[i]);
247
257
}
248
258
}
249
259
return ;
@@ -253,29 +263,28 @@ inline void ContactPatchSolver::getResult(const ContactPatch* result,
253
263
// contact patch.
254
264
// We simply select `max_patch_size` points of the patch by sampling the
255
265
// 2d support function of the patch along the unit circle.
256
- this ->added_to_patch .assign (result-> size (), false );
266
+ this ->added_to_patch .assign (result. size (), false );
257
267
const FCL_REAL angle_increment =
258
268
2.0 * (FCL_REAL)(EIGEN_PI) / ((FCL_REAL)(this ->max_patch_size ));
259
269
for (size_t i = 0 ; i < this ->max_patch_size ; ++i) {
260
270
const FCL_REAL theta = (FCL_REAL)(i)*angle_increment;
261
271
const Vec2f dir (std::cos (theta), std::sin (theta));
262
- FCL_REAL support_val = result-> points () [0 ].dot (dir);
272
+ FCL_REAL support_val = result[0 ].dot (dir);
263
273
size_t support_idx = 0 ;
264
- for (size_t j = 1 ; j < result-> size (); ++j) {
265
- const FCL_REAL val = result-> points () [j].dot (dir);
274
+ for (size_t j = 1 ; j < result. size (); ++j) {
275
+ const FCL_REAL val = result[j].dot (dir);
266
276
if (val > support_val) {
267
277
support_val = val;
268
278
support_idx = j;
269
279
}
270
280
}
271
281
if (!this ->added_to_patch [support_idx]) {
272
- if (contact_patch. points () .empty ()) {
273
- contact_patch. points (). emplace_back (result-> points () [support_idx]);
282
+ if (patch .empty ()) {
283
+ patch. emplace_back (result[support_idx]);
274
284
} else {
275
- if ((contact_patch.points ().back () - result->points ()[support_idx])
276
- .squaredNorm () >
285
+ if ((patch.back () - result[support_idx]).squaredNorm () >
277
286
Eigen::NumTraits<FCL_REAL>::dummy_precision ()) {
278
- contact_patch. points (). emplace_back (result-> points () [support_idx]);
287
+ patch. emplace_back (result[support_idx]);
279
288
}
280
289
}
281
290
this ->added_to_patch [support_idx] = true ;
0 commit comments