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.
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.
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...
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)
}
来源:https://stackoverflow.com/questions/10407700/calculate-center-and-radius-of-circle-from-3-points-on-it