#### Detect 2d collision Circle to Rectangle (with angle) and vice versa

Hi i’m trying to detect when two objects connect , either a circle or rectangle. I can’t figure it out how to do it. Most examples/tutorials online are really math heavy Or doesn’t use the Angle for rectangle

This is what i have so far.

``````public abstract record Location
{
public abstract double DistanceTo(Location location);
public abstract double DirectionTo(Location location);
}

public sealed record CircleLocation(double X, double Y, int Radius) : Location
{
public override double DistanceTo(Location location)
{
return location switch
{
CircleLocation circleLocation => Math.Sqrt(Math.Pow(X - circleLocation.X, 2) + Math.Pow(Y - circleLocation.Y, 2)) - circleLocation.Radius,
RectangleLocation rectangleLocation => Math.Max(rectangleLocation.Left - X, X - rectangleLocation.Right) + Math.Max(rectangleLocation.Top - Y, Y - rectangleLocation.Bottom),
_ => throw new Exception("Invalid location type")
};
}

public override double DirectionTo(Location location)
{
return location switch
{
CircleLocation circleLocation => Math.Atan2(circleLocation.Y - Y, circleLocation.X - X),
RectangleLocation rectangleLocation => Math.Atan2(rectangleLocation.CenterY - Y, rectangleLocation.CenterX - X),
_ => throw new Exception("Invalid location type")
};
}
}

public sealed record RectangleLocation(double X, double Y, double Width, double Height, double Angle) : Location
{
public double Left => X - Math.Cos(Angle) * Width / 2;
public double Top => Y - Math.Sin(Angle) * Height / 2;
public double Right => Left + (double)Math.Cos(Angle) * Width;
public double Bottom => Top + Math.Sin(Angle) * Height;
public double CenterX => X - Width / 2;
public double CenterY => Y - Height / 2;

public override double DistanceTo(Location location)
{
return location switch
{
CircleLocation circleLocation => Math.Sqrt(Math.Pow(X - circleLocation.X, 2) + Math.Pow(Y - circleLocation.Y, 2)) - circleLocation.Radius,
RectangleLocation rectangleLocation => Math.Max(rectangleLocation.Left - X, X - rectangleLocation.Right) + Math.Max(rectangleLocation.Top - Y, Y - rectangleLocation.Bottom),
_ => throw new Exception("Invalid location type")
};
}

public override double DirectionTo(Location location)
{
return location switch
{
CircleLocation circleLocation => Math.Atan2(circleLocation.Y - Y, circleLocation.X - X),
RectangleLocation rectangleLocation => Math.Atan2(rectangleLocation.CenterY - CenterY, rectangleLocation.CenterX - CenterX),
_ => throw new Exception("Invalid location type")
};
}
}

``````

Here’s the unit tests i’m playing with

``````public class UnitTest1
{
[Fact]
public void CircleToCircleTouches()
{
var circle1 = new CircleLocation(0, 0, 1);
var circle2 = new CircleLocation(2, 0, 1);

var distance = circle1.DistanceTo(circle2);

Assert.Equal(0, distance);
}

[Fact]
public void CircleToCircleDoesNotTouch()
{
var circle1 = new CircleLocation(0, 0, 1);
var circle2 = new CircleLocation(4, 0, 1);

var distance = circle1.DistanceTo(circle2);

Assert.Equal(2, distance);
}

[Fact]
public void RectangleToRectangleTouches()
{
var rectangle1 = new RectangleLocation(0, 0, 2, 2, 0);
var rectangle2 = new RectangleLocation(2, 2, 2, 2, 0);

var distance = rectangle1.DistanceTo(rectangle2);

Assert.Equal(0, distance);
}

[Fact]
public void RectangleToRectangleDoesNotTouch()
{
var rectangle1 = new RectangleLocation(0, 0, 2, 2, 0);
var rectangle2 = new RectangleLocation(3, 3, 2, 2, 0);

var distance = rectangle1.DistanceTo(rectangle2);

Assert.Equal(1, distance);
}

[Fact]
public void TestCircleToRectangleDistance()
{
var circle = new CircleLocation(0, 0, 1);
var rectangle = new RectangleLocation(3, 4, 2, 2, 0);

var distance = circle.DistanceTo(rectangle);

Assert.Equal(5, distance);
}

[Fact]
public void TestRectangleToCircleDistance()
{
var rectangle = new RectangleLocation(0, 0, 2, 2, 0);
var circle = new CircleLocation(3, 4, 1);

var distance = rectangle.DistanceTo(circle);

Assert.Equal(5, distance, 1);
}
}
``````