<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. BIM Math
  3. Lines and curves
All lessons in this course

Lesson 15 of 44 15 minIntermediate

Circles and arcs: 3-point arcs and tangents

Describe arcs by centre, radius and angles; build an arc through three points; get arc length, sagitta and bulge; and find the tangent points from a point to a circle.

Curved walls, round columns, pipe bends, arched openings and road alignments are circles or arcs. BIM and CAD tools store them in several interchangeable forms, and much of the work is converting between them.

FormStored asWhere you meet it
Centre, radius, anglesC, r, start and end angleRevit’s Arc.Create(plane, radius, start, end), DXF ARC entities
Three pointsstart, a point on the arc, endthe 3-point arc drawing tool, survey data
Start, end, bulgetwo points and tan(sweep ÷ 4)DXF and DWG polylines
Start, end, radiustwo points, r, and which sidewall and road alignment tools

A point on a circle

The point at angle θ on a circle with centre C and radius r is C + r(cos θ, sin θ). An arc is the same formula with θ limited to a range, which is the parametric idea from the first lesson again. Two facts follow directly:

  • Arc length = r × sweep, with the sweep in radians. In degrees, multiply by π ÷ 180 first.
  • The tangent at θ is (−sin θ, cos θ) for counterclockwise travel: at right angles to the radius.
Interactive

An arc through three points

Drag the start P1, a point on the arc P2, and the end P3. Try putting all three in a line.

centreP1P2P3
centre(0.67, −2.67)
radius4.96
directionclockwise
start, end angle160.3°, 47.7°
sweep−112.6° = 1.966 rad
arc length r × sweep9.74
chord |P3 − P1|8.25

perpendicular bisectors   tangent at P1

The centre is where the two perpendicular bisectors cross: it is 4.96 from all three points. The tangent at P1 (orange) is at right angles to the radius. Arc length r × sweep = 9.74, against a chord of 8.25.

An arc through three points

The centre is the same distance from all three points, so it lies on the perpendicular bisector of P1P2 and on that of P2P3: the dashed lines in the widget. Intersecting them gives a closed formula. Work relative to P1 to keep the numbers small, and check the denominator: it is zero when the points are in a line.

ThreePointArc.cs
var p1 = new V2(0, 0);var p2 = new V2(4, 2);var p3 = new V2(8, 0); var (c, r) = Circumcircle(p1, p2, p3);double a1 = Math.Atan2(p1.Y - c.Y, p1.X - c.X);double a3 = Math.Atan2(p3.Y - c.Y, p3.X - c.X);bool ccw = V2.Cross(p2 - p1, p3 - p2) > 0;        // does the path turn left?double sweep = ccw ? Wrap(a3 - a1) : -Wrap(a1 - a3); Console.WriteLine($"Centre {c}, radius {r}");Console.WriteLine($"Sweep {sweep * 180 / Math.PI:F2} deg ({(ccw ? "counterclockwise" : "clockwise")})");Console.WriteLine($"Arc length {r * Math.Abs(sweep):F3} m, chord {(p3 - p1).Length} m"); static double Wrap(double a) => a < 0 ? a + 2 * Math.PI : a;   // into [0, 2 pi) static (V2 Centre, double Radius) Circumcircle(V2 a, V2 b, V2 c){    V2 ab = b - a, ac = c - a;    double d = 2 * V2.Cross(ab, ac);    if (Math.Abs(d) < 1e-12) throw new ArgumentException("The points are collinear: no arc");    double ab2 = V2.Dot(ab, ab), ac2 = V2.Dot(ac, ac);    var centre = new V2(ac.Y * ab2 - ab.Y * ac2, ab.X * ac2 - ac.X * ab2) * (1 / d);    return (a + centre, centre.Length);} readonly record struct V2(double X, double Y){    public static V2 operator +(V2 a, V2 b) => new(a.X + b.X, a.Y + b.Y);    public static V2 operator -(V2 a, V2 b) => new(a.X - b.X, a.Y - b.Y);    public static V2 operator *(V2 v, double k) => new(v.X * k, v.Y * k);    public static double Dot(V2 a, V2 b) => a.X * b.X + a.Y * b.Y;    public static double Cross(V2 a, V2 b) => a.X * b.Y - a.Y * b.X;    public double Length => Math.Sqrt(X * X + Y * Y);    public override string ToString() => $"({X:0.###}, {Y:0.###})";}
Output
Centre (4, -3), radius 5
Sweep -106.26 deg (clockwise)
Arc length 9.273 m, chord 8 m

Sagitta, bulge and radius from a chord

Site information often gives a chord and a rise: “an arched opening 2.4 m wide that rises 0.4 m”. The rise in the middle is called the sagitta s. With the half-chord h, the radius is r = (h² + s²) ÷ (2s). DXF polylines store arcs as a bulge, which is tan(sweep ÷ 4), and also equals s ÷ h. Its sign gives the direction: positive is counterclockwise.

ArchedOpening.cs
double width = 2.4, rise = 0.4;           // an arched openingdouble h = width / 2; double r = (h * h + rise * rise) / (2 * rise);double bulge = rise / h;double sweep = 4 * Math.Atan(bulge);      // tan(sweep / 4) = bulgeConsole.WriteLine($"Radius {r:F3} m");Console.WriteLine($"Sweep {sweep * 180 / Math.PI:F2} deg, bulge {bulge:F4}");Console.WriteLine($"Arc length {r * sweep:F3} m (the chord is {width} m)");
Output
Radius 2.000 m
Sweep 73.74 deg, bulge 0.3333
Arc length 2.574 m (the chord is 2.4 m)

Tangents from a point

Where should a straight pipe leave a round tank so that it heads straight for a valve? From a point P outside a circle there are two lines that just touch it, at two tangent points. The radius to a tangent point T is at right angles to the tangent, so C, T and P form a right-angled triangle. Its long side is |P − C|, so the tangent length is √(|P − C|² − r²), and the angle at the centre is acos(r ÷ |P − C|).

TangentPoints.cs
var c = new V2(0, 0);double r = 3;                             // a round tankvar p = new V2(5, 0);                     // a valve outside it V2 cp = p - c;double dist = cp.Length;if (dist <= r) { Console.WriteLine("The point is inside the circle: no tangents"); return; } double alpha = Math.Acos(r / dist);       // angle at the centredouble toP = Math.Atan2(cp.Y, cp.X);foreach (double sign in new[] { 1.0, -1.0 }){    double angle = toP + sign * alpha;    Console.WriteLine($"Tangent point {c + new V2(Math.Cos(angle), Math.Sin(angle)) * r}");}Console.WriteLine($"Tangent length {Math.Sqrt(dist * dist - r * r)} m"); readonly record struct V2(double X, double Y){    public static V2 operator +(V2 a, V2 b) => new(a.X + b.X, a.Y + b.Y);    public static V2 operator -(V2 a, V2 b) => new(a.X - b.X, a.Y - b.Y);    public static V2 operator *(V2 v, double k) => new(v.X * k, v.Y * k);    public static double Dot(V2 a, V2 b) => a.X * b.X + a.Y * b.Y;    public static double Cross(V2 a, V2 b) => a.X * b.Y - a.Y * b.X;    public double Length => Math.Sqrt(X * X + Y * Y);    public override string ToString() => $"({X:0.###}, {Y:0.###})";}
Output
Tangent point (1.8, 2.4)
Tangent point (1.8, -2.4)
Tangent length 4 m
Quick check

An arc has a radius of 5 m and sweeps 90°. How long is it?

Quick check

Why is there no arc through three points that lie in a line?

Practice

A curved wall is an arc with centre (10, 0) and radius 10 m, running counterclockwise from 90° to 180°. Print its start and end points, its length, and the positions of three windows at ¼, ½ and ¾ of the way along it.

Show a hint

Convert the angles to radians. Evenly spaced along the length means evenly spaced in angle, so window i is at start + (end − start) × i ÷ 4.

Show the solution
Solution.cs
var c = new V2(10, 0);double r = 10, start = 90 * Math.PI / 180, end = 180 * Math.PI / 180; V2 At(double angle) => c + new V2(Math.Cos(angle), Math.Sin(angle)) * r; Console.WriteLine($"Start {At(start)}, end {At(end)}");Console.WriteLine($"Length {r * (end - start):F3} m");for (int i = 1; i <= 3; i++)    Console.WriteLine($"Window {i}: {At(start + (end - start) * i / 4)}"); readonly record struct V2(double X, double Y){    public static V2 operator +(V2 a, V2 b) => new(a.X + b.X, a.Y + b.Y);    public static V2 operator -(V2 a, V2 b) => new(a.X - b.X, a.Y - b.Y);    public static V2 operator *(V2 v, double k) => new(v.X * k, v.Y * k);    public static double Dot(V2 a, V2 b) => a.X * b.X + a.Y * b.Y;    public static double Cross(V2 a, V2 b) => a.X * b.Y - a.Y * b.X;    public double Length => Math.Sqrt(X * X + Y * Y);    public override string ToString() => $"({X:0.###}, {Y:0.###})";}
Output
Start (10, 10), end (0, 0)
Length 15.708 m
Window 1: (6.173, 9.239)
Window 2: (2.929, 7.071)
Window 3: (0.761, 3.827)

Remember

  • A point on a circle is C + r(cos θ, sin θ); an arc limits θ to a range.
  • Arc length is r × sweep in radians; the tangent is at right angles to the radius.
  • The centre of a 3-point arc is where the perpendicular bisectors cross; collinear points have no arc.
  • From a chord and a rise: r = (h² + s²) ÷ (2s); the DXF bulge is tan(sweep ÷ 4) = s ÷ h.
  • Tangents from an outside point P touch the circle at an angle acos(r ÷ |P − C|) either side of CP.
0 of 44 lessons completed