b2_collide_circle.cpp
Go to the documentation of this file.
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #include "box2d/b2_collision.h"
24 #include "box2d/b2_circle_shape.h"
25 #include "box2d/b2_polygon_shape.h"
26 
28  b2Manifold* manifold,
29  const b2CircleShape* circleA, const b2Transform& xfA,
30  const b2CircleShape* circleB, const b2Transform& xfB)
31 {
32  manifold->pointCount = 0;
33 
34  b2Vec2 pA = b2Mul(xfA, circleA->m_p);
35  b2Vec2 pB = b2Mul(xfB, circleB->m_p);
36 
37  b2Vec2 d = pB - pA;
38  float distSqr = b2Dot(d, d);
39  float rA = circleA->m_radius, rB = circleB->m_radius;
40  float radius = rA + rB;
41  if (distSqr > radius * radius)
42  {
43  return;
44  }
45 
46  manifold->type = b2Manifold::e_circles;
47  manifold->localPoint = circleA->m_p;
48  manifold->localNormal.SetZero();
49  manifold->pointCount = 1;
50 
51  manifold->points[0].localPoint = circleB->m_p;
52  manifold->points[0].id.key = 0;
53 }
54 
56  b2Manifold* manifold,
57  const b2PolygonShape* polygonA, const b2Transform& xfA,
58  const b2CircleShape* circleB, const b2Transform& xfB)
59 {
60  manifold->pointCount = 0;
61 
62  // Compute circle position in the frame of the polygon.
63  b2Vec2 c = b2Mul(xfB, circleB->m_p);
64  b2Vec2 cLocal = b2MulT(xfA, c);
65 
66  // Find the min separating edge.
67  int32 normalIndex = 0;
68  float separation = -b2_maxFloat;
69  float radius = polygonA->m_radius + circleB->m_radius;
70  int32 vertexCount = polygonA->m_count;
71  const b2Vec2* vertices = polygonA->m_vertices;
72  const b2Vec2* normals = polygonA->m_normals;
73 
74  for (int32 i = 0; i < vertexCount; ++i)
75  {
76  float s = b2Dot(normals[i], cLocal - vertices[i]);
77 
78  if (s > radius)
79  {
80  // Early out.
81  return;
82  }
83 
84  if (s > separation)
85  {
86  separation = s;
87  normalIndex = i;
88  }
89  }
90 
91  // Vertices that subtend the incident face.
92  int32 vertIndex1 = normalIndex;
93  int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
94  b2Vec2 v1 = vertices[vertIndex1];
95  b2Vec2 v2 = vertices[vertIndex2];
96 
97  // If the center is inside the polygon ...
98  if (separation < b2_epsilon)
99  {
100  manifold->pointCount = 1;
101  manifold->type = b2Manifold::e_faceA;
102  manifold->localNormal = normals[normalIndex];
103  manifold->localPoint = 0.5f * (v1 + v2);
104  manifold->points[0].localPoint = circleB->m_p;
105  manifold->points[0].id.key = 0;
106  return;
107  }
108 
109  // Compute barycentric coordinates
110  float u1 = b2Dot(cLocal - v1, v2 - v1);
111  float u2 = b2Dot(cLocal - v2, v1 - v2);
112  if (u1 <= 0.0f)
113  {
114  if (b2DistanceSquared(cLocal, v1) > radius * radius)
115  {
116  return;
117  }
118 
119  manifold->pointCount = 1;
120  manifold->type = b2Manifold::e_faceA;
121  manifold->localNormal = cLocal - v1;
122  manifold->localNormal.Normalize();
123  manifold->localPoint = v1;
124  manifold->points[0].localPoint = circleB->m_p;
125  manifold->points[0].id.key = 0;
126  }
127  else if (u2 <= 0.0f)
128  {
129  if (b2DistanceSquared(cLocal, v2) > radius * radius)
130  {
131  return;
132  }
133 
134  manifold->pointCount = 1;
135  manifold->type = b2Manifold::e_faceA;
136  manifold->localNormal = cLocal - v2;
137  manifold->localNormal.Normalize();
138  manifold->localPoint = v2;
139  manifold->points[0].localPoint = circleB->m_p;
140  manifold->points[0].id.key = 0;
141  }
142  else
143  {
144  b2Vec2 faceCenter = 0.5f * (v1 + v2);
145  float s = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
146  if (s > radius)
147  {
148  return;
149  }
150 
151  manifold->pointCount = 1;
152  manifold->type = b2Manifold::e_faceA;
153  manifold->localNormal = normals[vertIndex1];
154  manifold->localPoint = faceCenter;
155  manifold->points[0].localPoint = circleB->m_p;
156  manifold->points[0].id.key = 0;
157  }
158 }
d
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.
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2_math.h:422
float b2Dot(const b2Vec2 &a, const b2Vec2 &b)
Perform the dot product on two vectors.
Definition: b2_math.h:395
b2Vec2 localNormal
not use for Type::e_points
Definition: b2_collision.h:109
f
XmlRpcServer s
b2ContactID id
uniquely identifies a contact point between two shapes
Definition: b2_collision.h:80
uint32 key
Used to quickly compare contact ids.
Definition: b2_collision.h:62
void SetZero()
Set this vector to all zeros.
Definition: b2_math.h:50
A solid circle shape.
A 2D column vector.
Definition: b2_math.h:41
signed int int32
Definition: b2_types.h:28
float b2DistanceSquared(const b2Vec2 &a, const b2Vec2 &b)
Definition: b2_math.h:467
b2Vec2 m_p
Position.
float m_radius
Definition: b2_shape.h:102
b2Vec2 m_vertices[b2_maxPolygonVertices]
int32 pointCount
the number of manifold points
Definition: b2_collision.h:112
b2Vec2 localPoint
usage depends on manifold type
Definition: b2_collision.h:77
b2Vec2 localPoint
usage depends on manifold type
Definition: b2_collision.h:110
b2ManifoldPoint points[b2_maxManifoldPoints]
the points of contact
Definition: b2_collision.h:108
b2Vec2 b2MulT(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2_math.h:429
float Normalize()
Convert this vector into a unit vector. Returns the length.
Definition: b2_math.h:102
#define b2_maxFloat
Definition: b2_common.h:39
void b2CollideCircles(b2Manifold *manifold, const b2CircleShape *circleA, const b2Transform &xfA, const b2CircleShape *circleB, const b2Transform &xfB)
Compute the collision manifold between two circles.
#define b2_epsilon
Definition: b2_common.h:40
b2Vec2 m_normals[b2_maxPolygonVertices]


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:19