/// <summary> /// Use this method to check if two circle bounds are intersecting with each other /// </summary> /// <param name="c1"></param> /// <param name="c2"></param> /// <param name="intersectionPoint"></param> /// <returns></returns> public static bool CircleIntersectCircle(BoundsCircle c1, BoundsCircle c2) { float distanceMax = c1.radius + c2.radius; float distance = Vector2.Distance(c1.center, c2.center); return(distance <= distanceMax); }
/// <summary> /// /// </summary> /// <param name="y"></param> /// <returns></returns> public static Vector2 GetLeftBoundAtYValueCircle(BoundsCircle cBounds, float y) { float adjustedY = y - cBounds.center.y; float angle = Mathf.Asin(adjustedY / cBounds.radius); return(new Vector2(-Mathf.Cos(angle) * cBounds.radius + cBounds.center.x, y)); }
/// <summary> /// Overload method of our line intersect method /// </summary> /// <param name="c"></param> /// <param name="origin"></param> /// <param name="direction"></param> /// <param name="length"></param> /// <returns></returns> public static bool LineIntersectCircle(BoundsCircle c, Vector2 origin, Vector2 direction, float length) { Vector2 pointA = origin; Vector2 pointB = origin + direction * length; return(LineIntersectCircle(c, pointA, pointB)); }
/// <summary> /// Use this method to check if a rect bounds intersects a circle bounds /// </summary> /// <param name="r"></param> /// <param name="c"></param> /// <param name="intersectionPoint"></param> /// <returns></returns> public static bool RectIntersectCircle(BoundsRect r, BoundsCircle c) { Vector2 point = c.center; Vector2 A = r.topLeft; Vector2 B = r.topRight; Vector2 D = r.bottomLeft; float height = r.topLeft.y - r.bottomLeft.y; float width = r.topRight.x - r.topRight.x; float APdotAB = Vector2.Dot(point - A, B - A); float ABdotAB = Vector2.Dot(B - A, B - A); float APdotAD = Vector2.Dot(point - A, D - A); float ADdotAD = Vector2.Dot(D - A, D - A); if (0 <= APdotAB && APdotAB <= ABdotAB && 0 <= APdotAD && APdotAD < ADdotAD) { return(true); } return(LineIntersectCircle(c, r.bottomLeft, r.topRight)); //float rectX = r.bottomLeft.x; //float recty = r.bottomLeft.y; //float nearestX = Mathf.Max(rectX, Mathf.Min(point.x, rectX + width)); //float nearestY = Mathf.Max(recty, Mathf.Min(point.y, recty + height)); //float dX = point.x - nearestX; //float dY = point.y - nearestY; //return (dX * dX + dY * dY) < c.radius * c.radius; }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <returns></returns> public static Vector2 GetUpperBoundsAtXValueCircle(BoundsCircle cBounds, float x) { float adjustedX = x - cBounds.center.x; float angle = Mathf.Acos(adjustedX / cBounds.radius); return(new Vector2(x, Mathf.Sin(angle) * cBounds.radius + cBounds.center.y)); }
/// <summary> /// Returns true if the line that was passed in intersect with the given circle /// </summary> /// <param name="c"></param> /// <param name="origin"></param> /// <param name="direction"></param> /// <param name="length"></param> /// <returns></returns> public static bool LineIntersectCircle(BoundsCircle c, Vector2 pointA, Vector2 pointB) { Vector2 point = c.center; float rectX = pointA.x; float recty = pointA.y; float nearestX = Mathf.Max(rectX, Mathf.Min(point.x, pointB.x)); float nearestY = Mathf.Max(recty, Mathf.Min(point.y, pointB.y)); float dX = point.x - nearestX; float dY = point.y - nearestY; return((dX * dX + dY * dY) < c.radius * c.radius); }
/// <summary> /// /// </summary> /// <param name="cap"></param> /// <param name="cir"></param> /// <returns></returns> public static bool CapsuleIntersectCircle(BoundsCapsule cap, BoundsCircle cir) { if (CircleIntersectCircle(cap.bottomCircleBounds, cir)) { return(true); } if (CircleIntersectCircle(cap.topCircleBounds, cir)) { return(true); } if (RectIntersectCircle(cap.rectBounds, cir)) { return(true); } return(false); }
/// <summary> /// Returns the collision point of the of the two collider bounds /// </summary> /// <param name="r1"></param> /// <param name="c1"></param> /// <returns></returns> public static Vector2 IntersectionPointNonstaticRectOnStaticCircle(CustomBoxCollider2D nonstaticRectCollider, CustomCircleCollider2D staticCircleCollider, bool collidedVertically = true) { BoundsRect r1 = nonstaticRectCollider.bounds; BoundsCircle c1 = staticCircleCollider.bounds; Vector2 centerPointOfCircle = c1.center; Vector2 collisionPoint; if (collidedVertically) { if (centerPointOfCircle.x < r1.bottomLeft.x) { collisionPoint.x = r1.bottomLeft.x; } else if (centerPointOfCircle.x > r1.bottomRight.x) { collisionPoint.x = r1.bottomRight.x; } else { collisionPoint.x = centerPointOfCircle.x; } return(IntersectionPointColliderVerticalAtXPoint(nonstaticRectCollider, staticCircleCollider, collisionPoint.x)); } else { if (centerPointOfCircle.y < r1.bottomLeft.y) { collisionPoint.y = r1.bottomLeft.y; } else if (centerPointOfCircle.y > r1.topLeft.y) { collisionPoint.y = r1.topLeft.y; } else { collisionPoint.y = centerPointOfCircle.y; } return(IntersectionPointColliderHorizontalAtYPoint(nonstaticRectCollider, staticCircleCollider, collisionPoint.y)); } }
/// <summary> /// /// </summary> public override void UpdateBoundsOfCollider() { BoundsCircle cBounds = new BoundsCircle(); cBounds.center = this.transform.position + new Vector3(colliderOffset.x, colliderOffset.y); cBounds.radius = radius; bounds = cBounds; if (!isStatic) { //Adjust the vertical and horizontal bounds of our circle collider if it is a static collider this.horizontalBoundsFromVelocity = bounds; this.horizontalBoundsFromVelocity.radius = bounds.radius - radiusBuffer; this.verticalBoundsFromVelocity = bounds; this.verticalBoundsFromVelocity.radius = bounds.radius - radiusBuffer; if (rigid.Velocity.y < 0) { verticalBoundsFromVelocity.center = bounds.center + Vector2.up * Mathf.Min(-radiusBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } else if (rigid.Velocity.y > 0) { verticalBoundsFromVelocity.center = bounds.center + Vector2.up * Mathf.Max(radiusBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } if (rigid.Velocity.x < 0) { horizontalBoundsFromVelocity.center = bounds.center + Vector2.right * Mathf.Min(-radiusBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } else if (rigid.Velocity.x > 0) { horizontalBoundsFromVelocity.center = bounds.center + Vector2.right * Mathf.Max(radiusBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } } }
private static Vector2 CollisionPointCircleOnCircleBounds(BoundsCircle c1, BoundsCircle c2) { float totalRadius = c1.radius + c2.radius; return(c1.center + (c2.center - c1.center) * c1.radius / totalRadius); }
/// <summary> /// Updates the bounds of the capsule collider. The Capsule collider is made up of one rect bounds and two circle bounds /// </summary> public override void UpdateBoundsOfCollider() { BoundsRect b = new BoundsRect(); Vector2 origin = this.transform.position + new Vector3(colliderOffset.x, colliderOffset.y); float xSize = drawHorizontal ? size : radius * 2; float ySize = drawHorizontal ? radius * 2 : size; b.topLeft = origin + Vector2.up * ySize / 2 - Vector2.right * xSize / 2; b.topRight = origin + Vector2.up * ySize / 2 + Vector2.right * xSize / 2; b.bottomLeft = origin - Vector2.up * ySize / 2 - Vector2.right * xSize / 2; b.bottomRight = origin - Vector2.up * ySize / 2 + Vector2.right * xSize / 2; bounds.rectBounds = b; BoundsCircle topCircle = new BoundsCircle(); topCircle.center = b.topLeft + (b.topRight - b.topLeft) / 2f; topCircle.radius = radius; bounds.topCircleBounds = topCircle; BoundsCircle bottomCircle = new BoundsCircle(); bottomCircle.center = b.bottomLeft + (b.bottomRight - b.bottomLeft) / 2f; bottomCircle.radius = radius; bounds.bottomCircleBounds = bottomCircle; if (!isStatic) { verticalBounds = bounds; verticalBounds.topCircleBounds.radius = bounds.topCircleBounds.radius - colliderBuffer; verticalBounds.bottomCircleBounds.radius = bounds.bottomCircleBounds.radius - colliderBuffer; verticalBounds.rectBounds.topLeft.x = bounds.rectBounds.topLeft.x + colliderBuffer / 2; verticalBounds.rectBounds.topRight.x = bounds.rectBounds.topRight.x - colliderBuffer / 2; verticalBounds.rectBounds.bottomLeft.x = verticalBounds.rectBounds.topLeft.x; verticalBounds.rectBounds.bottomRight.x = verticalBounds.rectBounds.topRight.x; horizontalBounds = bounds; horizontalBounds.topCircleBounds.radius -= colliderBuffer; horizontalBounds.bottomCircleBounds.radius -= colliderBuffer; //horizontalBounds.topCircleBounds.center += Vector2.down * colliderBuffer; //horizontalBounds.bottomCircleBounds.center += Vector2.up * colliderBuffer; Vector2 horizontalOffset = Vector2.zero; Vector2 verticalOffset = Vector2.zero; if (rigid.Velocity.y > 0) { verticalOffset = Vector2.up * Mathf.Max(colliderBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } else if (rigid.Velocity.y < 0) { verticalOffset = Vector2.up * Mathf.Min(-colliderBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } if (rigid.Velocity.x > 0) { horizontalOffset = Vector2.right * Mathf.Max(colliderBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } else if (rigid.Velocity.x < 0) { horizontalOffset = Vector2.right * Mathf.Min(-colliderBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } verticalBounds.SetOffset(verticalOffset); horizontalBounds.SetOffset(horizontalOffset); } }