public static bool detectCircleRectangle(scTransform circleTransform, scCircleShape circle, scTransform rectangleTransform, scRectangleShape rectangle) { var transformedRectangleVertices = new List<Vector2>(); foreach (var vertex in rectangle.vertices) { transformedRectangleVertices.Add(scTransformUtils.applyTransform(rectangleTransform, vertex)); } var axes = new List<Vector2>(); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[0], transformedRectangleVertices[1])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[1], transformedRectangleVertices[2])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[2], transformedRectangleVertices[3])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[3], transformedRectangleVertices[0])); var transformedCircleCenter = scTransformUtils.applyTransform(circleTransform, circle.localPosition); //get nearest edge vertex to circle center var distancesToVertices = new List<Vector2>(); distancesToVertices.Add(transformedRectangleVertices[0] - transformedCircleCenter); distancesToVertices.Add(transformedRectangleVertices[1] - transformedCircleCenter); distancesToVertices.Add(transformedRectangleVertices[2] - transformedCircleCenter); distancesToVertices.Add(transformedRectangleVertices[3] - transformedCircleCenter); var circleAxis = distancesToVertices[0]; foreach (var distance in distancesToVertices) { if (distance.Length() < circleAxis.Length()) { circleAxis = distance; } } circleAxis.Normalize(); axes.Add(circleAxis); foreach (var axis in axes) { var lineSegmentRectangleA = scCollisionHelpers.projectCircleOnAxis(transformedCircleCenter, circle.radius, axis); var lineSegmentRectangleB = scCollisionHelpers.projectShapeOnAxis(transformedRectangleVertices, axis); if (!scCollisionHelpers.overlapsOnSameAxis(lineSegmentRectangleA, lineSegmentRectangleB)) { return false; } } return true; }
public static scRectangleShape fromLocalPositionAndHalfExtents(Vector2 localPosition, Vector2 halfExtents) { var rectangleShape = new scRectangleShape(); rectangleShape.vertices[0].X = localPosition.X - halfExtents.X; rectangleShape.vertices[0].Y = localPosition.Y - halfExtents.Y; rectangleShape.vertices[1].X = localPosition.X + halfExtents.X; rectangleShape.vertices[1].Y = localPosition.Y - halfExtents.Y; rectangleShape.vertices[2].X = localPosition.X + halfExtents.X; rectangleShape.vertices[2].Y = localPosition.Y + halfExtents.Y; rectangleShape.vertices[3].X = localPosition.X - halfExtents.X; rectangleShape.vertices[3].Y = localPosition.Y + halfExtents.Y; return rectangleShape; }
public static bool detectRectangleRectangle(scTransform aTransform, scRectangleShape aShape, scTransform bTransform, scRectangleShape bShape) { var transformedRectangleVerticesA = new List<Vector2>(); var transformedRectangleVerticesB = new List<Vector2>(); foreach (var vertex in aShape.vertices) { transformedRectangleVerticesA.Add(scTransformUtils.applyTransform(aTransform, vertex)); } foreach (var vertex in bShape.vertices) { transformedRectangleVerticesB.Add(scTransformUtils.applyTransform(bTransform, vertex)); } var axes = new List<Vector2>(); // add axes of aShape axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesA[0], transformedRectangleVerticesA[1])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesA[1], transformedRectangleVerticesA[2])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesA[2], transformedRectangleVerticesA[3])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesA[3], transformedRectangleVerticesA[0])); // add axes of bShape axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesB[0], transformedRectangleVerticesB[1])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesB[1], transformedRectangleVerticesB[2])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesB[2], transformedRectangleVerticesB[3])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVerticesB[3], transformedRectangleVerticesB[0])); foreach (var axis in axes) { var lineSegmentRectangleA = scCollisionHelpers.projectShapeOnAxis(transformedRectangleVerticesA, axis); var lineSegmentRectangleB = scCollisionHelpers.projectShapeOnAxis(transformedRectangleVerticesB, axis); if (!scCollisionHelpers.overlapsOnSameAxis(lineSegmentRectangleA, lineSegmentRectangleB)) { return false; } } return true; }
public static bool detectRectangleEdge(scTransform rectangleTransform, scRectangleShape rectangle, scTransform edgeTransform, scEdgeShape edge) { var transformedRectangleVertices = new List<Vector2>(); foreach (var vertex in rectangle.vertices) { transformedRectangleVertices.Add(scTransformUtils.applyTransform(rectangleTransform, vertex)); } var edgeStart = scTransformUtils.applyTransform(edgeTransform, edge.start); var edgeEnd = scTransformUtils.applyTransform(edgeTransform, edge.end); var transformedEdgeVertices = new List<Vector2>(); transformedEdgeVertices.Add(edgeStart); transformedEdgeVertices.Add(edgeEnd); var axes = new List<Vector2>(); axes.Add(scCollisionHelpers.getNormal(edgeStart, edgeEnd)); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[0], transformedRectangleVertices[1])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[1], transformedRectangleVertices[2])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[2], transformedRectangleVertices[3])); axes.Add(scCollisionHelpers.getNormal(transformedRectangleVertices[3], transformedRectangleVertices[0])); foreach (var axis in axes) { var lineSegmentRectangle = scCollisionHelpers.projectShapeOnAxis(transformedRectangleVertices, axis); var lineSegmentEdge = scCollisionHelpers.projectShapeOnAxis(transformedEdgeVertices, axis); if (!scCollisionHelpers.overlapsOnSameAxis(lineSegmentRectangle, lineSegmentEdge)) { return false; } } return true; }