Could somebody please show code which would do this quickly? Assume we get three points p1, p2, p3 in left-->right order. Thus, the solution should also check whether or not the circle is valid, ie (p1, p2, p3) are counter-clockwise.
Asked
Active
Viewed 2.3k times
3 Answers
14
To calculate the circle parameters, have a look at:
http://paulbourke.net/geometry/circlesphere/ Look for "Equation of a Circle from 3 Points (2 dimensions)"
to determine orientation, you can use the polygon area formula:
http://paulbourke.net/geometry/polygonmesh/ Look for "Calculating the area and centroid of a polygon"
Please tell me if you need this in an specific programming language.

Maple
- 741
- 13
- 28
-
Exactly what I needed, thorough and clear explanation. Thanks! – themaestro May 06 '12 at 01:12
-
Both the links are broken. Any other links? – Sharjith N. Mar 28 '13 at 17:00
-
@SharjithN./M.Hassan - Links fixed. – Maple May 09 '13 at 13:52
-
Any solution that depnds on slopes (m = (y2 - y1)/(x2 - x1)) doesn't work when a line is vertical (x2 - x1 = 0 and you divide by zero). Linear algebra is the way to go. – NovaDenizen May 20 '21 at 22:08
7
Connect any two points on the circle and you have a chord.
The perpendicular bisector of a chord must pass through the center.
The intersection of the bisectors of two chords will be the center.
Remainder (reduction to form for most efficient calculation) is left as an exercise for the reader...

Chris Stratton
- 39,853
- 6
- 84
- 117
2
Here is a short function (Swift language) with only a single if.
enum Result {
case circle(center: CGPoint, radius: CGFloat)
case invalid
}
func circleTouching3Points(a: CGPoint, b: CGPoint, c: CGPoint) -> Result {
let d1 = CGPoint(x: b.y - a.y, y: a.x - b.x)
let d2 = CGPoint(x: c.y - a.y, y: a.x - c.x)
let k: CGFloat = d2.x * d1.y - d2.y * d1.x
guard k < -0.00001 || k > 0.00001 else {
return Result.invalid
}
let s1 = CGPoint(x: (a.x + b.x) / 2, y: (a.y + b.y) / 2)
let s2 = CGPoint(x: (a.x + c.x) / 2, y: (a.y + c.y) / 2)
let l: CGFloat = d1.x * (s2.y - s1.y) - d1.y * (s2.x - s1.x)
let m: CGFloat = l / k
let center = CGPoint(x: s2.x + m * d2.x, y: s2.y + m * d2.y)
let dx = center.x - a.x
let dy = center.y - a.y
let radius = sqrt(dx * dx + dy * dy)
return Result.circle(center: center, radius: radius)
}

neoneye
- 50,398
- 25
- 166
- 151