b2CollideCircle.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 
22 
24  b2Manifold* manifold,
25  const b2CircleShape* circleA, const b2Transform& xfA,
26  const b2CircleShape* circleB, const b2Transform& xfB)
27 {
28  manifold->pointCount = 0;
29 
30  b2Vec2 pA = b2Mul(xfA, circleA->m_p);
31  b2Vec2 pB = b2Mul(xfB, circleB->m_p);
32 
33  b2Vec2 d = pB - pA;
34  float32 distSqr = b2Dot(d, d);
35  float32 rA = circleA->m_radius, rB = circleB->m_radius;
36  float32 radius = rA + rB;
37  if (distSqr > radius * radius)
38  {
39  return;
40  }
41 
42  manifold->type = b2Manifold::e_circles;
43  manifold->localPoint = circleA->m_p;
44  manifold->localNormal.SetZero();
45  manifold->pointCount = 1;
46 
47  manifold->points[0].localPoint = circleB->m_p;
48  manifold->points[0].id.key = 0;
49 }
50 
52  b2Manifold* manifold,
53  const b2PolygonShape* polygonA, const b2Transform& xfA,
54  const b2CircleShape* circleB, const b2Transform& xfB)
55 {
56  manifold->pointCount = 0;
57 
58  // Compute circle position in the frame of the polygon.
59  b2Vec2 c = b2Mul(xfB, circleB->m_p);
60  b2Vec2 cLocal = b2MulT(xfA, c);
61 
62  // Find the min separating edge.
63  int32 normalIndex = 0;
64  float32 separation = -b2_maxFloat;
65  float32 radius = polygonA->m_radius + circleB->m_radius;
66  int32 vertexCount = polygonA->m_count;
67  const b2Vec2* vertices = polygonA->m_vertices;
68  const b2Vec2* normals = polygonA->m_normals;
69 
70  for (int32 i = 0; i < vertexCount; ++i)
71  {
72  float32 s = b2Dot(normals[i], cLocal - vertices[i]);
73 
74  if (s > radius)
75  {
76  // Early out.
77  return;
78  }
79 
80  if (s > separation)
81  {
82  separation = s;
83  normalIndex = i;
84  }
85  }
86 
87  // Vertices that subtend the incident face.
88  int32 vertIndex1 = normalIndex;
89  int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
90  b2Vec2 v1 = vertices[vertIndex1];
91  b2Vec2 v2 = vertices[vertIndex2];
92 
93  // If the center is inside the polygon ...
94  if (separation < b2_epsilon)
95  {
96  manifold->pointCount = 1;
97  manifold->type = b2Manifold::e_faceA;
98  manifold->localNormal = normals[normalIndex];
99  manifold->localPoint = 0.5f * (v1 + v2);
100  manifold->points[0].localPoint = circleB->m_p;
101  manifold->points[0].id.key = 0;
102  return;
103  }
104 
105  // Compute barycentric coordinates
106  float32 u1 = b2Dot(cLocal - v1, v2 - v1);
107  float32 u2 = b2Dot(cLocal - v2, v1 - v2);
108  if (u1 <= 0.0f)
109  {
110  if (b2DistanceSquared(cLocal, v1) > radius * radius)
111  {
112  return;
113  }
114 
115  manifold->pointCount = 1;
116  manifold->type = b2Manifold::e_faceA;
117  manifold->localNormal = cLocal - v1;
118  manifold->localNormal.Normalize();
119  manifold->localPoint = v1;
120  manifold->points[0].localPoint = circleB->m_p;
121  manifold->points[0].id.key = 0;
122  }
123  else if (u2 <= 0.0f)
124  {
125  if (b2DistanceSquared(cLocal, v2) > radius * radius)
126  {
127  return;
128  }
129 
130  manifold->pointCount = 1;
131  manifold->type = b2Manifold::e_faceA;
132  manifold->localNormal = cLocal - v2;
133  manifold->localNormal.Normalize();
134  manifold->localPoint = v2;
135  manifold->points[0].localPoint = circleB->m_p;
136  manifold->points[0].id.key = 0;
137  }
138  else
139  {
140  b2Vec2 faceCenter = 0.5f * (v1 + v2);
141  float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
142  if (separation > radius)
143  {
144  return;
145  }
146 
147  manifold->pointCount = 1;
148  manifold->type = b2Manifold::e_faceA;
149  manifold->localNormal = normals[vertIndex1];
150  manifold->localPoint = faceCenter;
151  manifold->points[0].localPoint = circleB->m_p;
152  manifold->points[0].id.key = 0;
153  }
154 }
d
float32 b2Dot(const b2Vec2 &a, const b2Vec2 &b)
Perform the dot product on two vectors.
Definition: b2Math.h:406
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2Math.h:433
b2Vec2 localNormal
not use for Type::e_points
Definition: b2Collision.h:103
f
void b2CollideCircles(b2Manifold *manifold, const b2CircleShape *circleA, const b2Transform &xfA, const b2CircleShape *circleB, const b2Transform &xfB)
Compute the collision manifold between two circles.
XmlRpcServer s
b2ContactID id
uniquely identifies a contact point between two shapes
Definition: b2Collision.h:74
#define b2_epsilon
Definition: b2Settings.h:39
uint32 key
Used to quickly compare contact ids.
Definition: b2Collision.h:56
float32 m_radius
Definition: b2Shape.h:93
void SetZero()
Set this vector to all zeros.
Definition: b2Math.h:62
A circle shape.
Definition: b2CircleShape.h:25
A 2D column vector.
Definition: b2Math.h:53
b2Vec2 m_p
Position.
Definition: b2CircleShape.h:62
signed int int32
Definition: b2Settings.h:31
float32 b2DistanceSquared(const b2Vec2 &a, const b2Vec2 &b)
Definition: b2Math.h:473
b2Vec2 m_vertices[b2_maxPolygonVertices]
int32 pointCount
the number of manifold points
Definition: b2Collision.h:106
b2Vec2 localPoint
usage depends on manifold type
Definition: b2Collision.h:71
b2Vec2 b2MulT(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2Math.h:440
b2Vec2 localPoint
usage depends on manifold type
Definition: b2Collision.h:104
void b2CollidePolygonAndCircle(b2Manifold *manifold, const b2PolygonShape *polygonA, const b2Transform &xfA, const b2CircleShape *circleB, const b2Transform &xfB)
Compute the collision manifold between a polygon and a circle.
b2ManifoldPoint points[b2_maxManifoldPoints]
the points of contact
Definition: b2Collision.h:102
#define b2_maxFloat
Definition: b2Settings.h:38
float32 Normalize()
Convert this vector into a unit vector. Returns the length.
Definition: b2Math.h:114
b2Vec2 m_normals[b2_maxPolygonVertices]
float float32
Definition: b2Settings.h:35


mvsim
Author(s):
autogenerated on Thu Jun 6 2019 19:36:39