private static bool Raycast(float2 from, float2 to, CircleCollider circle) { float2 delta = to - from; float a = delta.x * delta.x + delta.y * delta.y; float b = 2 * (delta.x * (from.x - circle.position.x) + delta.y * (from.y - circle.position.y)); float c = (from.x - circle.position.x) * (from.x - circle.position.x) + (from.y - circle.position.y) * (from.y - circle.position.y) - (circle.radius * circle.radius); float discriminant = b * b - 4 * a * c; if (0 > discriminant) { return(false); } float positive = (-b + math.sqrt(discriminant)) / (2 * a); if (positive >= 0 && 1 >= positive) { return(true); } float negative = (-b - math.sqrt(discriminant)) / (2 * a); return(negative >= 0 && 1 >= negative); }
private static bool Intersects(CircleCollider circle, ShapeCollider shape) { float2 nearest = shape.position + shape.points[0]; float minDistance = math.distancesq(circle.position, nearest); for (int i = 1; shape.points.Count > i; i++) { float distance = math.distancesq(circle.position, shape.position + shape.points[i]); if (minDistance > distance) { minDistance = distance; nearest = shape.position + shape.points[i]; } } float2 axis = math.normalizesafe(nearest - circle.position); if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0) { return(false); } for (int i = 0; shape.points.Count > i; i++) { axis = math.normalizesafe(shape.edges[i].perpendicular()); if (LineOverlap(Project(shape, axis), Project(circle, axis)) == 0) { return(false); } } return(true); }
private static float2 Depenetrate(CircleCollider circleA, CircleCollider circleB) { float2 direction = circleA.position - circleB.position; float summedRadii = circleA.radius + circleB.radius; float distance = math.length(direction); return(summedRadii > distance?math.normalizesafe(direction) * (summedRadii - distance) : float2.zero); }
private static bool ContainedBy(ShapeCollider shapeCollider, CircleCollider circleCollider) { for (int i = 0; shapeCollider.points.Count > i; i++) { if (!ContainedBy(shapeCollider.position + shapeCollider.points[i], circleCollider)) { return(false); } } return(true); }
private static float2 Depenetrate(CircleCollider circle, ShapeCollider shape) { float2 nearest = shape.position + shape.points[0]; float lowest = math.distancesq(circle.position, nearest); for (int i = 1; shape.points.Count > i; i++) { float distance = math.distancesq(circle.position, shape.position + shape.points[i]); if (lowest > distance) { lowest = distance; nearest = shape.position + shape.points[i]; } } float2 depenetration = float2.zero; float depth = float.PositiveInfinity; float2 axis = math.normalizesafe(nearest - circle.position); float overlap = LineOverlap(Project(shape, axis), Project(circle, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } for (int i = 0; shape.points.Count > i; i++) { axis = math.normalizesafe(shape.edges[i].perpendicular()); overlap = LineOverlap(Project(shape, axis), Project(circle, axis)); if (overlap == 0) { return(float2.zero); } if (depth > overlap) { depth = overlap; depenetration = axis; } } return(depenetration * depth * (math.dot(depenetration, shape.position - circle.position) >= 0 ? -1 : 1)); }
private static float2 Depenetrate <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(Depenetrate(circleColliderA, circleColliderB)); case ShapeCollider shapeColliderB: return(Depenetrate(circleColliderA, shapeColliderB)); default: return(float2.zero); } }
private static bool ContainedBy <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(ContainedBy(circleColliderA, circleColliderB)); case ShapeCollider shapeColliderB: return(ContainedBy(shapeColliderB, circleColliderA)); default: return(false); } }
private static bool Intersects <T>(CircleCollider circleColliderA, T colliderB) where T : AbstractCollider { switch (colliderB) { case CircleCollider circleColliderB: return(Intersects(circleColliderA, circleColliderB)); case ShapeCollider shapeColliderB: return(Intersects(circleColliderA, shapeColliderB)); default: return(false); } }
private static float2 Depenetrate(ShapeCollider shape, CircleCollider circle) => - Depenetrate(circle, shape);
private static float2 Project(CircleCollider circle, float2 axis) { float dot = math.dot(circle.position, axis); return(new float2(dot - circle.radius, dot + circle.radius)); }
public CircleCollider(CircleCollider circleCollider) : this(circleCollider.radius) { }
public AABB(CircleCollider collider) : this(collider.position, collider.radius) { }
private static bool ContainedBy(float2 point, CircleCollider circleCollider) => circleCollider.radius * circleCollider.radius > math.distancesq(point, circleCollider.position);
private static bool ContainedBy(CircleCollider circleColliderA, CircleCollider circleColliderB) => (circleColliderB.radius - circleColliderA.radius) * (circleColliderB.radius - circleColliderA.radius) > math.distancesq(circleColliderA.position, circleColliderB.position);
private static bool Intersects(ShapeCollider shape, CircleCollider circle) => Intersects(circle, shape);
private static bool Intersects(CircleCollider circleA, CircleCollider circleB) => (circleA.radius + circleB.radius) * (circleA.radius + circleB.radius) > math.distancesq(circleA.position, circleB.position);