Given three points, how does one find the center and radius of a circle fitting those points? Three points determine a unique circle if, and only if, they are not on the same line. From analytic geometry, we know that there is a unique circle that passes through the three points:
It can be found by solving the following determinant equation:(x1, y1), (x2, y2), (x3, y3)
x2 + y2 x y 1 x12 + y12 x1 y1 1 x22 + y22 x2 y2 1 x32 + y32 x3 y3 1 = 0
This can be solved by evaluating the cofactors for the first row of the determinant. The determinant can be written as an equation of these cofactors:
(x2 + y2) M11 - x M12 + y M13 - M14 = 0
Since, (x2 + y2) = r2 this can be simplified to
r2 - x M12 / M11 + y M13 / M11 - M14 / M11 = 0
The general equation of a circle with radius r0 and center (x0, y0) is
(x - x0)2 + (y - y0)2 - r02 = 0
Expanding this gives,
(x2 - 2 x x0 + x02) + (y2 - 2 y y0 + y02) - r02 = 0
Re-arranging terms and substitution gives,
r2 - 2 x x0 - 2 y y0 + x02 + y02 - r02 = 0
Equating the like terms from the determinant equation and the general equation for the circle gives:
x0 = + 0.5 M12 / M11 y0 = - 0.5 M13 / M11 r02 = x02 + y02 + M14 / M11
Note that there is no solution when M11 is equal to zero. In this case, the points are not on a circle; they may all be on a straight line.
type POINT : record
x, y : real
end record
type THREEPOINTS : array[3] of POINT
type matrix : array[3,3] of real
program
var r : real
var c : POINT
var p : THREEPOINTS
p[1].x := 7
p[1].y := 7
p[2].x := 0
p[2].y := 8
p[3].x := 0
p[3].y := 0
put "points: "...
put "(", p[1].x, ", ", p[1].y, "), "...
put "(", p[2].x, ", ", p[2].y, "), "...
put "(", p[3].x, ", ", p[3].y, ") "
r := circle( c, p )
if r > 0 then
put "Circle: (", c.x, ", ", c.y, "), ", r
else
put "Not a circle!"
end if
end program
%
% Calculate center and radius of
% circle given three points
%
function circle( var c : POINT, var p : THREEPOINTS ) : real
var i : int
var r, m11, m12, m13, m14 : real
var a : matrix
for i := 1...3 do % find minor 11
a[i,1] := p[i].x
a[i,2] := p[i].y
a[i,3] := 1
end for
m11 := det( a, 3 )
for i := 1...3 do % find minor 12
a[i,1] := p[i].x^2 + p[i].y^2
a[i,2] := p[i].y
a[i,3] := 1
end for
m12 := det( a, 3 )
for i := 1...3 do % find minor 13
a[i,1] := p[i].x^2 + p[i].y^2
a[i,2] := p[i].x
a[i,3] := 1
end for
m13 := det( a, 3 )
for i := 1...3 do % find minor 14
a[i,1] := p[i].x^2 + p[i].y^2
a[i,2] := p[i].x
a[i,3] := p[i].y
end for
m14 := det( a, 3 )
if m11 = 0 then
r := 0 % not a circle
else
c.x := 0.5 * m12 / m11 % center of circle
c.y := -0.5 * m13 / m11
r := sqrt( c.x^2 + c.y^2 + m14/m11 )
end if
return r % the radius
end function
%
% Calculate determinate using recursive
% expansion by minors.
%
function det( var a : matrix, n : int ) : real
var i, j, j1, j2 : int
var d : real := 0
var m : matrix
assert n > 1
if n = 2 then
d := a[1,1]*a[2,2] - a[2,1]*a[1,2]
else
d := 0
for j1 := 1...n do
% create minor
for i := 2...n do
j2 := 1
for j := 1...n do
continue when j = j1
m[i-1,j2] := a[i,j]
incr j2
end for
end for
% calculate determinant
d := d + ( -1.0 )^(1 + j1 ) * a[1,j1] * det( m, n-1 )
end for
end if
return d
end function
AbCd Classics - free on-line books