internal static bool CollideCircleLine(ICollidible circleCollidible1, CollisionTypeCircle cTypeCircle1, CollisionTypeLine cTypeLine) { // calculate the length of the perpendicular line from the line to the center of the circle CCPoint vectorPerpToLine = CCPoint.PerpendicularCCW((cTypeLine.EndPoint - cTypeLine.StartPoint)); CCPoint vectorLineStartToCircle = ((CCNode)circleCollidible1).PositionWorldspace - cTypeLine.StartPoint; float perpLength = (float)Math.Abs(CCPoint.Dot(vectorPerpToLine, vectorLineStartToCircle) / vectorPerpToLine.Length); return(perpLength <= CorrectRadius(circleCollidible1, cTypeCircle1)); }
internal static bool CollideCircleCircle(ICollidible circleCollidible1, CollisionTypeCircle cTypeCircle1, ICollidible circleCollidible2, CollisionTypeCircle cTypeCircle2) { CCPoint pos1 = ((CCNode)circleCollidible1).PositionWorldspace; CCPoint pos2 = ((CCNode)circleCollidible2).PositionWorldspace; float radius1 = CorrectRadius(circleCollidible1, cTypeCircle1); float radius2 = CorrectRadius(circleCollidible2, cTypeCircle2); return(pos1.IsNear(pos2, radius1 + radius2)); }
// is dirty, as it only checks whether polygon points are contained in the circle, not whether polygon lines are crossed by it internal static bool CollideCirclePolygon(ICollidible circleCollidible, CollisionTypeCircle cTypeCircle, ICollidible polyCollidible, CollisionTypePolygon cTypePoly) { float radius = CorrectRadius(circleCollidible, cTypeCircle); CCPoint pos = ((CCNode)circleCollidible).PositionWorldspace; // transform the polygon to match the positioning, rotation and scale of the node Polygon transformedPolygon = ((Polygon)cTypePoly.collisionPolygon.Clone()); transformedPolygon.TransformAccordingToGameObject(polyCollidible); // for each point of the polygon check whether its contained in the circle foreach (var point in transformedPolygon.Points) { if (point.IsNear(pos, radius)) { return(true); } } return(false); }
// exact internal static bool CollideDiamondCircle(ICollidible collidibleDiamond, ICollidible collidibleCircle, CollisionTypeCircle cTypeCircle) { var circlePos = ((CCNode)collidibleCircle).PositionWorldspace; var radius = CorrectRadius(collidibleCircle, cTypeCircle); // for performance first check whether they are too far to collide anyway var diamondBox = ((CCNode)collidibleDiamond).BoundingBoxTransformedToWorld; float maxSizeBox = diamondBox.Size.Width > diamondBox.Size.Height ? diamondBox.Size.Width : diamondBox.Size.Height; if (Math.Abs(circlePos.X - diamondBox.Center.X) > radius + diamondBox.Size.Width / 2 || Math.Abs(circlePos.Y - diamondBox.Center.Y) > radius + diamondBox.Size.Height / 2) { return(false); } var diamond = BoxToDiamond(diamondBox); int i, j; for (i = 0, j = diamond.Length - 1; i < diamond.Length; j = i++) { if (CollideCircleLine(circlePos, radius, diamond[i], diamond[j])) { return(true); } } return(false); }
internal static bool CollideBoundingBoxCircle(ICollidible boxCollidible, ICollidible circleCollidible, CollisionTypeCircle cTypeCircle) { return(CollideBoundingBoxCircle(((CCNode)boxCollidible).BoundingBoxTransformedToWorld, ((CCNode)circleCollidible).PositionWorldspace, CorrectRadius(circleCollidible, cTypeCircle))); }
internal static bool CollidePositionCircle(ICollidible posCollidible, ICollidible circleCollidible, CollisionTypeCircle cTypeCircle) { return(((CCNode)circleCollidible).PositionWorldspace.IsNear(((CCNode)posCollidible).PositionWorldspace, CorrectRadius(circleCollidible, cTypeCircle))); }
internal static float CorrectRadius(ICollidible circleCollidible, CollisionTypeCircle cTypeCircle) { return((cTypeCircle.useScale ? circleCollidible.GetTotalScale() : 1f) * cTypeCircle.radius); }