@@ -262,43 +262,38 @@ void b2PolygonShape::ComputeDistance(const b2Transform& xf, const b2Vec2& p, flo
262
262
B2_NOT_USED (childIndex);
263
263
264
264
b2Vec2 pLocal = b2MulT (xf.q , p - xf.p );
265
- float32 maxDistance = -FLT_MAX;
266
- b2Vec2 normalForMaxDistance = pLocal;
267
265
266
+ // If the nearest point is a corner, then the dot products of the normals on each of its edges will be positive.
267
+ int32 prevI = m_count - 1 ;
268
268
for (int32 i = 0 ; i < m_count; ++i)
269
269
{
270
- float32 dot = b2Dot (m_normals[i], pLocal - m_vertices[i]);
271
- if (dot > maxDistance)
270
+ const b2Vec2& beforeNorm = m_normals[prevI]; // The normal of point i and the point i-1
271
+ const b2Vec2& afterNorm = m_normals[i]; // The normal of point i and the point i+1
272
+ b2Vec2 dist = pLocal - m_vertices[i];
273
+ if (b2Dot (dist, beforeNorm) > 0 .0f && b2Dot (dist, afterNorm) > 0 .0f )
272
274
{
273
- maxDistance = dot;
274
- normalForMaxDistance = m_normals[i];
275
+ *distance = dist.Length ();
276
+ *normal = b2Mul (xf.q , dist);
277
+ if (*distance > 0 .0f )
278
+ *normal /= *distance;
279
+ return ;
275
280
}
281
+ prevI = i;
276
282
}
277
283
278
- if (maxDistance > 0 )
284
+ float32 maxDistance = -FLT_MAX;
285
+ b2Vec2 normalForMaxDistance = pLocal;
286
+ for (int32 i = 0 ; i < m_count; ++i)
279
287
{
280
- b2Vec2 minDistance = normalForMaxDistance;
281
- float32 minDistance2 = maxDistance * maxDistance;
282
- for (int32 i = 0 ; i < m_count; ++i)
288
+ float32 dot = b2Dot (m_normals[i], pLocal - m_vertices[i]);
289
+ if (dot > maxDistance)
283
290
{
284
- b2Vec2 distance = pLocal - m_vertices[i];
285
- float32 distance2 = distance.LengthSquared ();
286
- if (minDistance2 > distance2)
287
- {
288
- minDistance = distance;
289
- minDistance2 = distance2;
290
- }
291
+ maxDistance = dot;
292
+ normalForMaxDistance = m_normals[i];
291
293
}
292
-
293
- *distance = b2Sqrt (minDistance2);
294
- *normal = b2Mul (xf.q , minDistance);
295
- normal->Normalize ();
296
- }
297
- else
298
- {
299
- *distance = maxDistance;
300
- *normal = b2Mul (xf.q , normalForMaxDistance);
301
294
}
295
+ *distance = maxDistance;
296
+ *normal = b2Mul (xf.q , normalForMaxDistance);
302
297
}
303
298
304
299
bool b2PolygonShape::RayCast (b2RayCastOutput* output, const b2RayCastInput& input,
0 commit comments