/// <summary> /// Return a position that is both on the line and in the polygon. /// </summary> /// <param name="testProjectile"></param> /// <param name="part"></param> /// <returns></returns> internal static CCPoint CollisionPosLinePoly(CollisionTypeLine cTypeLine, ICollidible polyCollidible) { // for performance reasons first check the bounding box (skip for now because we assume a collision is present if (CollideBoundingBoxLine(polyCollidible, cTypeLine)) { // transform the polygon to match the positioning, rotation and scale of the node Polygon transformedPolygon = ((Polygon)((CollisionTypePolygon)polyCollidible.CollisionType).collisionPolygon.Clone()); transformedPolygon.TransformAccordingToGameObject(polyCollidible); // first check if the polygon contains some of the two line points if (transformedPolygon.ContainsPoint(cTypeLine.StartPoint)) { return(cTypeLine.StartPoint); } else if (transformedPolygon.ContainsPoint(cTypeLine.EndPoint)) { return(cTypeLine.EndPoint); } // solve exactly: check for line intersections var polyPoints = transformedPolygon.Points; int i, j; for (i = 0, j = polyPoints.Length - 1; i < polyPoints.Length; j = i++) { if (CCPoint.SegmentIntersect(cTypeLine.StartPoint, cTypeLine.EndPoint, polyPoints[i], polyPoints[j])) { return(CCPoint.IntersectPoint(cTypeLine.StartPoint, cTypeLine.EndPoint, polyPoints[i], polyPoints[j])); } } } return(CCPoint.Zero); }
internal static bool CollideBoundingBoxLine(ICollidible boxCollidible, CollisionTypeLine cTypeLine) { CCRect box = ((CCNode)boxCollidible).BoundingBoxTransformedToWorld; float sx = cTypeLine.StartPoint.X; float sy = cTypeLine.StartPoint.Y; float ex = cTypeLine.EndPoint.X; float ey = cTypeLine.EndPoint.Y; // for performance first check whether both points of the line are outside and on one side of the box if ((sx < box.MinX && ex < box.MinX) || (sx > box.MaxX && ex > box.MaxX) || (sy < box.MinY && ey < box.MinY) || (sy > box.MaxY && ey > box.MaxY)) { return(false); } // check whether the start or end point is contained in the box if (box.ContainsPoint(cTypeLine.StartPoint) || box.ContainsPoint(cTypeLine.EndPoint)) { return(true); } // check for intersections of the line and the box boundaries CCPoint[] boxPoints = Constants.CCRectPoints(box); for (int i = 0; i < 3; i++) { if (CCPoint.SegmentIntersect(cTypeLine.StartPoint, cTypeLine.EndPoint, boxPoints[i], boxPoints[i + 1])) { return(true); } } return(false); }
/// <summary> /// Check whether a bullet shot now would hit any parts of the TargetAircraft (if the TargetAircraft wouldn't move). /// </summary> /// <param name="partsInRange"></param> /// <returns>whether the bullet would hit</returns> internal bool WouldHit() { Constants.CCDegreesToDxDy(MyPart.TotalRotation, out float dx, out float dy); CollisionTypeLine cTypeReachLine = new CollisionTypeLine(MyPart.PositionWorldspace, MyPart.PositionWorldspace + new CCPoint(dx * Reach, dy * Reach)); foreach (Part part in TargetAircraft.TotalParts) { if (Collisions.CollidePolygonLine(part, ((CollisionTypePolygon)part.CollisionType), cTypeReachLine)) return true; } return false; }
private void Init() { CollisionType = new CollisionTypeLine(CCPoint.Zero, CCPoint.Zero); }
internal static bool CollidePolygonLine(ICollidible polyCollidible, CollisionTypePolygon cTypePoly, CollisionTypeLine cTypeLine) { // for performance reasons first check the bounding box if (CollideBoundingBoxLine(polyCollidible, cTypeLine)) { // transform the polygon to match the positioning, rotation and scale of the node Polygon transformedPolygon = ((Polygon)cTypePoly.collisionPolygon.Clone()); transformedPolygon.TransformAccordingToGameObject(polyCollidible); // first check if the polygon contains some of the two line points if (transformedPolygon.ContainsPoint(cTypeLine.StartPoint) || transformedPolygon.ContainsPoint(cTypeLine.EndPoint)) { return(true); } // solve exactly: check for line intersections var polyPoints = transformedPolygon.Points; int i, j; for (i = 0, j = polyPoints.Length - 1; i < polyPoints.Length; j = i++) { if (CCPoint.SegmentIntersect(cTypeLine.StartPoint, cTypeLine.EndPoint, polyPoints[i], polyPoints[j])) { return(true); } } } return(false); }
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 CollidePositionLine(ICollidible posCollidible, CollisionTypeLine cTypeLine) { CCPoint pos = ((CCNode)posCollidible).PositionWorldspace; return(pos.Equals(cTypeLine.StartPoint) || pos.Equals(cTypeLine.EndPoint)); }