(manifold *B2Manifold, polygonA *B2PolygonShape, xfA B2Transform, circleB *B2CircleShape, xfB B2Transform)
| 26 | } |
| 27 | |
| 28 | func B2CollidePolygonAndCircle(manifold *B2Manifold, polygonA *B2PolygonShape, xfA B2Transform, circleB *B2CircleShape, xfB B2Transform) { |
| 29 | |
| 30 | manifold.PointCount = 0 |
| 31 | |
| 32 | // Compute circle position in the frame of the polygon. |
| 33 | c := B2TransformVec2Mul(xfB, circleB.M_p) |
| 34 | cLocal := B2TransformVec2MulT(xfA, c) |
| 35 | |
| 36 | // Find the min separating edge. |
| 37 | normalIndex := 0 |
| 38 | separation := -B2_maxFloat |
| 39 | radius := polygonA.M_radius + circleB.M_radius |
| 40 | vertexCount := polygonA.M_count |
| 41 | vertices := polygonA.M_vertices |
| 42 | normals := polygonA.M_normals |
| 43 | |
| 44 | for i := 0; i < vertexCount; i++ { |
| 45 | s := B2Vec2Dot(normals[i], B2Vec2Sub(cLocal, vertices[i])) |
| 46 | |
| 47 | if s > radius { |
| 48 | // Early out. |
| 49 | return |
| 50 | } |
| 51 | |
| 52 | if s > separation { |
| 53 | separation = s |
| 54 | normalIndex = i |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | // Vertices that subtend the incident face. |
| 59 | vertIndex1 := normalIndex |
| 60 | vertIndex2 := 0 |
| 61 | if vertIndex1+1 < vertexCount { |
| 62 | vertIndex2 = vertIndex1 + 1 |
| 63 | } |
| 64 | |
| 65 | v1 := vertices[vertIndex1] |
| 66 | v2 := vertices[vertIndex2] |
| 67 | |
| 68 | // If the center is inside the polygon ... |
| 69 | if separation < B2_epsilon { |
| 70 | manifold.PointCount = 1 |
| 71 | manifold.Type = B2Manifold_Type.E_faceA |
| 72 | manifold.LocalNormal = normals[normalIndex] |
| 73 | manifold.LocalPoint = B2Vec2MulScalar(0.5, B2Vec2Add(v1, v2)) |
| 74 | manifold.Points[0].LocalPoint = circleB.M_p |
| 75 | manifold.Points[0].Id.SetKey(0) |
| 76 | return |
| 77 | } |
| 78 | |
| 79 | // Compute barycentric coordinates |
| 80 | u1 := B2Vec2Dot(B2Vec2Sub(cLocal, v1), B2Vec2Sub(v2, v1)) |
| 81 | u2 := B2Vec2Dot(B2Vec2Sub(cLocal, v2), B2Vec2Sub(v1, v2)) |
| 82 | if u1 <= 0.0 { |
| 83 | if B2Vec2DistanceSquared(cLocal, v1) > radius*radius { |
| 84 | return |
| 85 | } |
no test coverage detected