Struct Circle2
A circle in 2D space, defined by a centre point and a Radius.
Circle2 is a readonly record struct, so it is value-type,
immutable, and can be compared for equality by value. All operations return new instances.
A circle is the set of all points whose distance from the centre equals the radius. This type lets you work with circles in unit-aware code: for example, you can check whether a real-world position lies inside a turn radius, or compute where a tangent from an external target touches the circle (useful for path-planning around obstacles).
public readonly record struct Circle2 : IEquatable<Circle2>
- Implements
- Inherited Members
- Extension Methods
Examples
// Define a circle centred at the origin with a 5 m radius
var circle = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
// Is a point inside?
bool inside = circle.Contains(LengthPoint2.FromMeters(3, 4)); // true (3² + 4² = 5²)
// Where does a tangent from an external point touch the circle?
var (t1, t2) = circle.CalculateTangentPoints(LengthPoint2.FromMeters(13, 0));
Constructors
Circle2(LengthPoint2, Radius)
public Circle2(LengthPoint2 center, Radius radius)
Parameters
centerLengthPoint2The position of the circle's centre.
radiusRadiusThe radius. Must be non-negative (enforced by Radius).
Circle2(LengthPoint2, Length)
Constructs a Circle2 from a centre and a UnitsNet.Length radius. The length is automatically wrapped in a Radius.
public Circle2(LengthPoint2 center, Length radius)
Parameters
centerLengthPoint2The position of the circle's centre.
radiusLengthThe radius as a raw length. Must be non-negative.
Properties
Center
The centre of the circle in world space.
public LengthPoint2 Center { get; }
Property Value
Radius
The radius of the circle.
public Radius Radius { get; }
Property Value
Methods
CalculateOrthogonalPoint(LengthPoint2)
Returns the point on the circumference closest to externalPoint.
Projects the external point through the centre and finds the intersection with the circumference. For any external point P, the closest boundary point lies on the ray from the centre through P, at distance equal to the radius.
public LengthPoint2 CalculateOrthogonalPoint(LengthPoint2 externalPoint)
Parameters
externalPointLengthPoint2Any point in space (inside or outside).
Returns
- LengthPoint2
The closest point on the circumference.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
var closest = c.CalculateOrthogonalPoint(LengthPoint2.FromMeters(13, 0)); // (5, 0)
CalculateTangentPoints(LengthPoint2)
Computes the two points on the circle where tangent lines drawn from
externalPoint touch the circumference.
A tangent line from an external point is a line that just touches the circle at exactly one point. There are always exactly two such points when the source is outside the circle.
Algorithm: If d = distance from centre to the external point, and r = radius,
then the half-angle between the centre-to-point line and the centre-to-tangent line is
α = asin(r / d). The two tangent contact points are found by rotating the
centre-to-external-point direction by ±α.
public (LengthPoint2, LengthPoint2) CalculateTangentPoints(LengthPoint2 externalPoint)
Parameters
externalPointLengthPoint2The point from which tangent lines are drawn. Must be outside the circle.
Returns
- (LengthPoint2, LengthPoint2)
The two tangent contact points on the circumference.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
var (p1, p2) = c.CalculateTangentPoints(LengthPoint2.FromMeters(13, 0));
// p1 and p2 are both on the circle, tangent lines from (13,0) just touch there
Exceptions
- ArgumentException
Thrown if
externalPointis inside or on the circle (no external tangent exists).
Contains(LengthPoint2)
Returns true if point lies inside or on the boundary
of this circle (i.e. its distance from Center is ≤ Radius).
public bool Contains(LengthPoint2 point)
Parameters
pointLengthPoint2The point to test.
Returns
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
c.Contains(LengthPoint2.FromMeters(3, 4)); // true — on boundary (3²+4²=5²)
c.Contains(LengthPoint2.FromMeters(4, 4)); // false — outside (≈ 5.66 m from centre)
DistanceTo(LengthPoint2)
Returns the shortest distance from point to the circle's boundary.
Returns UnitsNet.Length.Zero if the point is inside or on the circle.
public Length DistanceTo(LengthPoint2 point)
Parameters
pointLengthPoint2The world-space query point.
Returns
- Length
Distance to the nearest boundary point, or zero if the point is already inside.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
c.DistanceTo(LengthPoint2.FromMeters(8, 0)); // 3 m (outside)
c.DistanceTo(LengthPoint2.FromMeters(3, 0)); // 0 m (inside)
c.DistanceTo(LengthPoint2.FromMeters(5, 0)); // 0 m (on boundary)
FromPoints(LengthPoint2, LengthPoint2, LengthPoint2)
Returns the unique circumscribed circle (circumcircle) that passes through three non-collinear points.
The circumcenter is the intersection of the perpendicular bisectors of the three sides. All three input points lie exactly on the returned circle's circumference.
public static Circle2 FromPoints(LengthPoint2 p1, LengthPoint2 p2, LengthPoint2 p3)
Parameters
p1LengthPoint2First point.
p2LengthPoint2Second point.
p3LengthPoint2Third point.
Returns
Examples
var p1 = LengthPoint2.FromMeters(1, 0);
var p2 = LengthPoint2.FromMeters(0, 1);
var p3 = LengthPoint2.FromMeters(-1, 0);
var circle = Circle2.FromPoints(p1, p2, p3);
// circle.Center ≈ (0, 0), circle.Radius ≈ 1 m
Exceptions
- ArgumentException
Thrown when the three points are collinear (or nearly collinear within a 1e-10 m² tolerance), because no finite circle passes through them.
GetBoundingRectangle()
Returns the axis-aligned bounding square that exactly fits this circle.
The bounding square has its centre at Center and its side length equal to the diameter (2 × Radius). It is the smallest axis-aligned rectangle that fully contains the circle.
public Rectangle2 GetBoundingRectangle()
Returns
- Rectangle2
An axis-aligned Rectangle2 with dimensions (diameter × diameter).
Examples
var c = new Circle2(LengthPoint2.FromMeters(2, 3), Radius.FromMeters(4));
var box = c.GetBoundingRectangle();
// box.Center = (2, 3), box.Dimensions = (8, 8)
GetClosestPoint(LengthPoint2)
Returns the point on the circle's boundary that is nearest to point.
The closest boundary point lies in the same direction as point from the
circle's centre. If the point is exactly at the centre (a degenerate case), the point due
east (positive X axis) on the circumference is returned.
public LengthPoint2 GetClosestPoint(LengthPoint2 point)
Parameters
pointLengthPoint2The world-space query point.
Returns
- LengthPoint2
The nearest point on the circumference.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
// Point due north at 10 m — nearest circumference point is directly south of it
LengthPoint2 closest = c.GetClosestPoint(LengthPoint2.FromMeters(0, 10));
// closest ≈ (0, 5)
GetPointInDirection(Direction2)
Returns the point on the circumference in the given direction from the centre.
This is equivalent to Center + direction × Radius: walk from the centre
outward along direction for exactly the radius distance.
public LengthPoint2 GetPointInDirection(Direction2 direction)
Parameters
directionDirection2The direction to travel from the centre.
Returns
- LengthPoint2
The point on the circumference in that direction.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
var eastEdge = c.GetPointInDirection(Direction2.Zero); // (5, 0)
GetTangentLine(LengthPoint2)
Returns the tangent line at a given point on the circle's circumference.
The tangent line at a point is perpendicular to the radius that passes through that point. This is a fundamental theorem of circle geometry: the tangent is always at 90° to the radius.
public LengthLine2 GetTangentLine(LengthPoint2 pointOnCircle)
Parameters
pointOnCircleLengthPoint2A point on (or very close to) the circumference. The method projects it onto the circumference to obtain an exact tangent.
Returns
- LengthLine2
A LengthLine2 tangent to the circle at the given point.
Examples
var c = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(5));
var tangent = c.GetTangentLine(LengthPoint2.FromMeters(5, 0));
// tangent is a vertical line through (5, 0)
MoveCenterTo(LengthPoint2)
Returns a new Circle2 with its centre moved to
newCenter, preserving all other properties.
public Circle2 MoveCenterTo(LengthPoint2 newCenter)
Parameters
newCenterLengthPoint2The new centre position.
Returns
Examples
var moved = shape.MoveCenterTo(LengthPoint2.FromMeters(5, 0));
Overlaps(Circle2)
Returns true if this circle overlaps (intersects or touches) another circle. Two circles overlap when the distance between their centres is less than or equal to the sum of their radii.
public bool Overlaps(Circle2 other)
Parameters
otherCircle2The circle to test against.
Returns
Examples
var a = new Circle2(LengthPoint2.FromMeters(0, 0), Radius.FromMeters(3));
var b = new Circle2(LengthPoint2.FromMeters(5, 0), Radius.FromMeters(3));
a.Overlaps(b); // true — radii sum to 6, centres 5 m apart
Overlaps(Rectangle2)
Returns true if this circle overlaps (intersects or touches) a rectangle. The test finds the point on the rectangle's boundary closest to the circle's centre; if that point is within the circle's radius, the shapes overlap.
public bool Overlaps(Rectangle2 rect)
Parameters
rectRectangle2The rectangle to test against.
Returns
Examples
var c = new Circle2(LengthPoint2.FromMeters(5, 0), Radius.FromMeters(2));
var rect = new Rectangle2(LengthPoint2.FromMeters(0, 0), LengthVector2.FromMeters(4, 4));
c.Overlaps(rect); // true — circle at x=5 radius 2 reaches x=3, rect goes to x=2
ToString()
Returns the fully qualified type name of this instance.
public override string ToString()
Returns
- string
The fully qualified type name.
TryGetManifold(Capsule2, out CollisionManifold)
Tests whether this circle overlaps other and, if so, returns the
collision manifold describing the penetration.
public bool TryGetManifold(Capsule2 other, out CollisionManifold manifold)
Parameters
otherCapsule2The capsule to test against.
manifoldCollisionManifoldWhen this method returns true, contains the collision data.
Returns
Remarks
The algorithm treats the capsule as a swept circle: distance is measured from the circle center to the nearest point on the capsule spine. This correctly handles both the outside and inside-capsule cases. Degenerate case: when the circle center lies exactly on the spine East is used as a fallback normal.
TryGetManifold(Circle2, out CollisionManifold)
Tests whether this circle overlaps other and, if so, returns the
collision manifold describing the penetration.
public bool TryGetManifold(Circle2 other, out CollisionManifold manifold)
Parameters
otherCircle2The other circle to test against.
manifoldCollisionManifoldWhen this method returns true, contains the collision data: penetration depth, contact normal (pointing from
othertoward this circle), and the contact point. Otherwise the default value.
Returns
- bool
true if the circles penetrate (overlap strictly greater than zero); false if they are separated or only touching.
Remarks
Coincident centers: when both circles share the same center the contact normal cannot be derived from geometry. East is used as an arbitrary fallback; this is documented here so callers can handle the degenerate case if needed.
TryGetManifold(Polygon2, out CollisionManifold)
Tests whether this circle overlaps other and, if so, returns the
collision manifold describing the penetration.
public bool TryGetManifold(Polygon2 other, out CollisionManifold manifold)
Parameters
otherPolygon2The polygon to test against.
manifoldCollisionManifoldWhen this method returns true, contains the collision data.
Returns
TryGetManifold(Rectangle2, out CollisionManifold)
Tests whether this circle overlaps other and, if so, returns the
collision manifold describing the penetration.
public bool TryGetManifold(Rectangle2 other, out CollisionManifold manifold)
Parameters
otherRectangle2The rectangle to test against.
manifoldCollisionManifoldWhen this method returns true, contains the collision data.
Returns
Remarks
When the circle center is inside the rectangle the nearest face is used as the exit axis.
TryGetManifold(Triangle2, out CollisionManifold)
Tests whether this circle overlaps other and, if so, returns the
collision manifold describing the penetration.
public bool TryGetManifold(Triangle2 other, out CollisionManifold manifold)
Parameters
otherTriangle2The triangle to test against.
manifoldCollisionManifoldWhen this method returns true, contains the collision data.
Returns
Operators
operator +(Circle2, LengthVector2)
Translates the circle by a displacement vector. The radius is unchanged.
public static Circle2 operator +(Circle2 circle, LengthVector2 displacement)
Parameters
circleCircle2The circle to translate.
displacementLengthVector2The vector to add to the circle's centre.
Returns
operator +(LengthVector2, Circle2)
Translates the circle by a displacement vector (commutative overload).
public static Circle2 operator +(LengthVector2 displacement, Circle2 circle)
Parameters
displacementLengthVector2The vector to add to the circle's centre.
circleCircle2The circle to translate.