Centre and radius of a circle passing through 3 points in a plane
Appearance
(Redirected from Centre and radius of a ciircle passing through 3 points in a plane)
Centre and radius of a circle passing through 3 points in a plane
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
Write a function which returns the centre and radius of a circle passing through three point in a plane. Demonstrate the function using the points (22.83,2.07) (14.39,30.24) and (33.65,17.31)
Ada
procedure Program
is
type Real is digits 2;
package Real_IO is
new Ada.Text_IO.Float_IO (Real);
package Math is
new Ada.Numerics.Generic_Elementary_Functions (Real);
type Point is record
X, Y : Real'Base;
end record;
procedure Find_Circle (P1, P2, P3 : in Point;
Center : out Point;
Radius : out Real)
is
use Math;
X_12 : constant Real'Base := P1.X - P2.X;
X_13 : constant Real'Base := P1.X - P3.X;
Y_12 : constant Real'Base := P1.Y - P2.Y;
Y_13 : constant Real'Base := P1.Y - P3.Y;
Y_31 : constant Real'Base := P3.Y - P1.Y;
Y_21 : constant Real'Base := P2.Y - P1.Y;
X_31 : constant Real'Base := P3.X - P1.X;
X_21 : constant Real'Base := P2.X - P1.X;
SX_13 : constant Real'Base := P1.X**2 - P3.X**2;
SY_13 : constant Real'Base := P1.Y**2 - P3.Y**2;
SX_21 : constant Real'Base := P2.X**2 - P1.X**2;
SY_21 : constant Real'Base := P2.Y**2 - P1.Y**2;
F : constant Real'Base
:= (SX_13 * X_12 + SY_13 * X_12 + SX_21 * X_13 + SY_21 * X_13)
/ (2.0 * (Y_31 * X_12 - Y_21 * X_13));
G : constant Real'Base
:= (SX_13 * Y_12 + SY_13 * Y_12 + SX_21 * Y_13 + SY_21 * Y_13)
/ (2.0 * (X_31 * Y_12 - X_21 * Y_13));
C : constant Real'Base
:= -(P1.X**2) - P1.Y**2 - 2.0 * G * P1.X - 2.0 * F * P1.Y;
H : constant Real'Base := -G;
K : constant Real'Base := -F;
R : constant Real'Base := Sqrt (H * H + K * K - C);
begin
Center.X := H;
Center.Y := K;
Radius := R;
end Find_Circle;
use Ada.Text_IO;
Center : Point;
Radius : Real'Base;
begin
Real_IO.Default_Aft := 2;
Real_IO.Default_Exp := 0;
Find_Circle ((22.83, 2.07), (14.39, 30.24), (33.65, 17.31),
Center, Radius);
Put ("Center is at ("); Real_IO.Put (Center.X);
Put (", "); Real_IO.Put (Center.Y);
Put (")");
New_Line;
Put ("Radius is "); Real_IO.Put (Radius);
New_Line;
end Program;
- Output:
Center is at (18.98, 16.27) Radius is 14.71
ALGOL 68
Follows the lines of the C++ code at geeksforgeeks.org.
BEGIN # find the centre and radius of a circle through 3 points #
# follows the lines of the C++ code at #
# https://www.geeksforgeeks.org/equation-of-circle-when-three-points-on-the-circle-are-given/ #
MODE POINT = STRUCT( REAL x, y );
MODE CIRCLE = STRUCT( POINT centre, REAL radius );
# returns the circle that passes through p1, p2 and p3 #
PROC find circle = ( POINT p1, p2, p3 )CIRCLE:
BEGIN
REAL x1 = x OF p1, y1 = y OF p1, x2 = x OF p2, y2 = y OF p2, x3 = x OF p3, y3 = y OF p3;
REAL x12 = x1 - x2
, x13 = x1 - x3
, y12 = y1 - y2
, y13 = y1 - y3
, y31 = y3 - y1
, y21 = y2 - y1
, x31 = x3 - x1
, x21 = x2 - x1
;
REAL sx13 = x1^2 - x3^2
, sy13 = y1^2 - y3^2
, sx21 = x2^2 - x1^2
, sy21 = y2^2 - y1^2
;
REAL f = ( ( ( sx13 + sy13 ) * x12 )
+ ( ( sx21 + sy21 ) * x13 )
)
/ ( 2 * ( ( y31 * x12 ) - ( y21 * x13 ) ) )
, g = ( ( ( sx13 + sy13 ) * y12 )
+ ( ( sx21 + sy21 ) * y13 )
)
/ ( 2 * ( ( x31 * y12 ) - ( x21 * y13 ) ) )
;
REAL c = - (x1^2) - (y1^2) - ( 2 * g * x1 ) - ( 2 * f * y1 );
( ( -g, -f ), sqrt( g^2 + f^2 - c ) )
END # find circle # ;
BEGIN # test #
CIRCLE c = find circle( ( 22.83, 2.07 ), ( 14.39, 30.24 ), ( 33.65, 17.31 ) );
print( ( "Centre = ( ", fixed( x OF centre OF c, -10, 6 ) ) );
print( ( ", ", fixed( y OF centre OF c, -10, 6 ) ) );
print( ( " ), Radius = ", fixed( radius OF c, -10, 6 ), newline ) )
END
END
- Output:
Centre = ( 18.978516, 16.265411 ), Radius = 14.708624
BASIC
BASIC256
call findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
end
subroutine findCircle(x1, y1, x2, y2, x3, y3)
x12 = x1 - x2
x13 = x1 - x3
y12 = y1 - y2
y13 = y1 - y3
y31 = y3 - y1
y21 = y2 - y1
x31 = x3 - x1
x21 = x2 - x1
sx13 = x1 * x1 - x3 * x3
sy13 = y1 * y1 - y3 * y3
sx21 = x2 * x2 - x1 * x1
sy21 = y2 * y2 - y1 * y1
f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
h = -g
k = -f
r = sqr(h * h + k * k - c)
print "Centre is at ("; h; ", "; k; ")"
print "Radius is "; r
print
print "Check radius as the distance between the centre and the first point:"
print sqr((22.83 - h) ^ 2 + (2.07 - k) ^ 2)
end subroutine
- Output:
Centre is at (18.9785156601, 16.2654107977) Radius is 14.708624 Check radius as the distance between the centre and the first point: 14.708624
Chipmunk Basic
100 sub findcircle(x1,y1,x2,y2,x3,y3)
110 x12 = x1-x2
120 x13 = x1-x3
130 y12 = y1-y2
140 y13 = y1-y3
150 y31 = y3-y1
160 y21 = y2-y1
170 x31 = x3-x1
180 x21 = x2-x1
190 '
200 sx13 = x1*x1-x3*x3
210 sy13 = y1*y1-y3*y3
220 sx21 = x2*x2-x1*x1
230 sy21 = y2*y2-y1*y1
240 '
250 f = (sx13*x12+sy13*x12+sx21*x13+sy21*x13)/(y31*x12-y21*x13)/2
260 g = (sx13*y12+sy13*y12+sx21*y13+sy21*y13)/(x31*y12-x21*y13)/2
270 '
280 c = -x1*x1-y1*y1-2*g*x1-2*f*y1
290 h = -g
300 k = -f
310 r = sqr(h*h+k*k-c)
320 '
330 print "Centre is at ( ";h;", ";k;")"
340 print "Radius is ";r
350 print
360 print "Check radius as the distance between the centre and the first point:"
370 print sqr((22.83-h)^2+(2.07-k)^2)
380 end sub
390 cls
400 findcircle(22.83,2.07,14.39,30.24,33.65,17.31)
410 end
Gambas
Sub findCircle(x1 As Float, y1 As Float, x2 As Float, y2 As Float, x3 As Float, y3 As Float)
Dim x12 As Float = x1 - x2
Dim x13 As Float = x1 - x3
Dim y12 As Float = y1 - y2
Dim y13 As Float = y1 - y3
Dim y31 As Float = y3 - y1
Dim y21 As Float = y2 - y1
Dim x31 As Float = x3 - x1
Dim x21 As Float = x2 - x1
Dim sx13 As Float = x1 * x1 - x3 * x3
Dim sy13 As Float = y1 * y1 - y3 * y3
Dim sx21 As Float = x2 * x2 - x1 * x1
Dim sy21 As Float = y2 * y2 - y1 * y1
Dim f As Float = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
Dim g As Float = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
Dim c As Float = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
Dim h As Float = -g
Dim k As Float = -f
Dim r As Float = Sqr(h * h + k * k - c)
Print "Centre is at (" & h & ", " & k & ")"
Print "Radius is "; r
Print
Print "Check radius as the distance between the centre and the first point:"
Print Sqr((22.83 - h) ^ 2 + (2.07 - k) ^ 2)
End Sub
Public Sub Main()
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
End
- Output:
Centre is at (18.9785156601488, 16.2654107977159) Radius is 14,7086239783342 Check radius as the distance between the centre and the first point: 14,7086239783342
PureBasic
Procedure.d findCircle(x1, y1, x2, y2, x3, y3)
Define.d x12, x13, y12, y13, y31, y21, x31, x21, sx13, sy13, sx21, sy21
Define.d f, g, c, h, k, r
x12 = x1 - x2
x13 = x1 - x3
y12 = y1 - y2
y13 = y1 - y3
y31 = y3 - y1
y21 = y2 - y1
x31 = x3 - x1
x21 = x2 - x1
sx13 = x1 * x1 - x3 * x3
sy13 = y1 * y1 - y3 * y3
sx21 = x2 * x2 - x1 * x1
sy21 = y2 * y2 - y1 * y1
f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
h = -g
k = -f
r = Sqr(h * h + k * k - c)
PrintN("Centre is at (" + Str(h) + ", " + Str(k) + ")")
PrintN("Radius is " + Str(r))
PrintN("")
PrintN("Check radius as the distance between the centre and the first point: " + Str(Sqr(Pow((22.83 - h), 2) + Pow((2.07 - k), 2))))
EndProcedure
OpenConsole()
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
PrintN(#CRLF$ + "--- terminado, pulsa RETURN---"): Input()
PrintN(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
Yabasic
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
END
SUB findCircle(x1, y1, x2, y2, x3, y3)
x12 = x1 - x2
x13 = x1 - x3
y12 = y1 - y2
y13 = y1 - y3
y31 = y3 - y1
y21 = y2 - y1
x31 = x3 - x1
x21 = x2 - x1
sx13 = x1 * x1 - x3 * x3
sy13 = y1 * y1 - y3 * y3
sx21 = x2 * x2 - x1 * x1
sy21 = y2 * y2 - y1 * y1
f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
h = -g
k = -f
r = SQRT(h * h + k * k - c)
PRINT "Centre is at (", h, ", ", k, ")"
PRINT "Radius is ", r
PRINT
PRINT "Check radius as the distance between the centre and the first point:"
PRINT SQRT((22.83 - h) ^ 2 + (2.07 - k) ^ 2)
END SUB
- Output:
Centre is at (18.9785, 16.2654) Radius is 14.7086 Check radius as the distance between the centre and the first point: 14.7086
C++
This follows the lines of the C++ code here.
#include <iostream>
#include <math.h>
using namespace std;
void findCircle(float x1, float y1, float x2, float y2, float x3, float y3) {
float x12 = x1 - x2;
float x13 = x1 - x3;
float y12 = y1 - y2;
float y13 = y1 - y3;
float y31 = y3 - y1;
float y21 = y2 - y1;
float x31 = x3 - x1;
float x21 = x2 - x1;
float sx13 = pow(x1, 2) - pow(x3, 2);
float sy13 = pow(y1, 2) - pow(y3, 2);
float sx21 = pow(x2, 2) - pow(x1, 2);
float sy21 = pow(y2, 2) - pow(y1, 2);
float f = ((sx13) * (x12) + (sy13) * (x12) + (sx21) * (x13) + (sy21) * (x13))
/ (2 * ((y31) * (x12) - (y21) * (x13)));
float g = ((sx13) * (y12) + (sy13) * (y12) + (sx21) * (y13) + (sy21) * (y13))
/ (2 * ((x31) * (y12) - (x21) * (y13)));
float c = -pow(x1, 2) - pow(y1, 2) - 2 * g * x1 - 2 * f * y1;
float h = -g;
float k = -f;
float r = sqrt(h * h + k * k - c);
cout << "Centre is at (" << h << ", " << k << ")" << endl;
cout << "Radius is " << r;
}
int main() {
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31);
return 0;
}
Dart
import 'dart:math';
void findCircle(
double x1, double y1, double x2, double y2, double x3, double y3) {
double x12 = x1 - x2;
double x13 = x1 - x3;
double y12 = y1 - y2;
double y13 = y1 - y3;
double y31 = y3 - y1;
double y21 = y2 - y1;
double x31 = x3 - x1;
double x21 = x2 - x1;
double sx13 = x1 * x1 - x3 * x3;
double sy13 = y1 * y1 - y3 * y3;
double sx21 = x2 * x2 - x1 * x1;
double sy21 = y2 * y2 - y1 * y1;
double f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) /
(2 * (y31 * x12 - y21 * x13));
double g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) /
(2 * (x31 * y12 - x21 * y13));
double c = -pow(x1, 2) - pow(y1, 2) - 2 * g * x1 - 2 * f * y1;
double h = -g;
double k = -f;
double r = sqrt(h * h + k * k - c);
print("Centre is at ($h, $k)");
print("\nCheck radius as the distance between the centre and the first point: $r");
}
void main() {
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31);
}
- Output:
Centre is at (18.978515660148815, 16.265410797715866) Check radius as the distance between the centre and the first point: 14.70862397833418
EasyLang
proc circ x1 y1 x2 y2 x3 y3 . cx cy cr .
x12 = x1 - x2
x13 = x1 - x3
y12 = y1 - y2
y13 = y1 - y3
y31 = y3 - y1
y21 = y2 - y1
x31 = x3 - x1
x21 = x2 - x1
sx13 = x1 * x1 - x3 * x3
sy13 = y1 * y1 - y3 * y3
sx21 = x2 * x2 - x1 * x1
sy21 = y2 * y2 - y1 * y1
f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
cx = -g
cy = -f
cr = sqrt (cx * cx + cy * cy - c)
.
circ 22.83 2.07 14.39 30.24 33.65 17.31 cx cy cr
print "Centre: (" & cx & ", " & cy & ") Radius: " & cr
- Output:
Centre: (18.98, 16.27) Radius: 14.71
F#
// Centre and radius of a circle passing through 3 points in a plane. Nigel Galloway: February 20th., 2024
let c (a,b) (c,d) (e,f)=(0.5*((a*a+b*b)*(f-d)+(c*c+d*d)*(b-f)+(e*e+f*f)*(d-b))/(a*(f-d)+c*(b-f)+e*(d-b)),
0.5*((a*a+b*b)*(e-c)+(c*c+d*d)*(a-e)+(e*e+f*f)*(c-a))/(b*(e-c)+d*(a-e)+f*(c-a)))
let d n g = let n,g=fst n-fst g,snd n-snd g in sqrt(n*n+g*g)
let circ P1 P2 P3 = let c=c P1 P2 P3 in (c,d c P1)
let centre,radius=circ (22.83, 2.07) (14.39, 30.24) (33.65, 17.31)
printfn $"Centre = %A{centre}, radius = %f{radius}"
- Output:
Centre = (18.97851566, 16.2654108), radius = 14.708624
FreeBASIC
Sub findCircle(x1 As Double, y1 As Double, x2 As Double, y2 As Double, x3 As Double, y3 As Double)
Dim x12 As Double = x1 - x2
Dim x13 As Double = x1 - x3
Dim y12 As Double = y1 - y2
Dim y13 As Double = y1 - y3
Dim y31 As Double = y3 - y1
Dim y21 As Double = y2 - y1
Dim x31 As Double = x3 - x1
Dim x21 As Double = x2 - x1
Dim sx13 As Double = x1 * x1 - x3 * x3
Dim sy13 As Double = y1 * y1 - y3 * y3
Dim sx21 As Double = x2 * x2 - x1 * x1
Dim sy21 As Double = y2 * y2 - y1 * y1
Dim f As Double = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
Dim g As Double = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
Dim c As Double = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
Dim h As Double = -g
Dim k As Double = -f
Dim r As Double = Sqr(h * h + k * k - c)
Print "Centre is at (" & h & ", " & k & ")"
Print "Radius is"; r
Print
Print "Check radius as the distance between the centre and the first point:"
Print Sqr((22.83 - h)^2 + (2.07 - k)^2)
End Sub
findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
Sleep
- Output:
Centre is at (18.97851566014882, 16.26541079771587) Radius is 14.70862397833418 Check radius as the distance between the centre and the first point: 14.70862397833418
FutureBasic
//Centre and radius of a circle passing through 3 points in a plane
//https://rosettacode.org/wiki/Centre_and_radius_of_a_circle_passing_through_3_points_in_a_plane
// Translated from Yabasic to FutureBasic
local fn findCircle(x1 as double, y1 as double, x2 as double, y2 as double, x3 as double, y3 as double)
double x12 = x1 - x2
double x13 = x1 - x3
double y12 = y1 - y2
double y13 = y1 - y3
double y31 = y3 - y1
double y21 = y2 - y1
double x31 = x3 - x1
double x21 = x2 - x1
double sx13 = x1 * x1 - x3 * x3
double sy13 = y1 * y1 - y3 * y3
double sx21 = x2 * x2 - x1 * x1
double sy21 = y2 * y2 - y1 * y1
double f = (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13) / (y31 * x12 - y21 * x13) / 2
double g = (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13) / (x31 * y12 - x21 * y13) / 2
double c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
double h = -g
double k = -f
double r = fn SQRT(h * h + k * k - c)
PRINT "Centre is at (", h, ", ", k, ")"
PRINT "Radius is ", r
PRINT
PRINT "Check radius as the distance between the centre and the first point:"
PRINT fn SQRT((22.83 - h) ^ 2 + (2.07 - k) ^ 2)
END fn
fn findCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
handleevents
- Output:
Centre is at ( 18.97851566014882 , 16.26541079771587 ) Radius is 14.70862397833418 Check radius as the distance between the centre and the first point: 14.70862397833418
Java
public final class CentreAndRadiusOfACirclePassingThrough3PointsInAPlane {
public static void main(String[] args) {
Circle circle = computeCircle( new Point(22.83, 2.07), new Point(14.39, 30.24), new Point(33.65, 17.31) );
System.out.println(circle);
}
private static Circle computeCircle(Point pointOne, Point pointTwo, Point pointThree) {
double centreX = 0.5 *
(
( pointOne.x * pointOne.x + pointOne.y * pointOne.y ) * ( pointThree.y - pointTwo.y ) +
( pointTwo.x * pointTwo.x + pointTwo.y * pointTwo.y ) * ( pointOne.y - pointThree.y ) +
( pointThree.x * pointThree.x + pointThree.y * pointThree.y ) * ( pointTwo.y - pointOne.y )
)
/
(
pointOne.x * ( pointThree.y - pointTwo.y ) +
pointTwo.x * ( pointOne.y - pointThree.y ) +
pointThree.x * ( pointTwo.y - pointOne.y )
);
double centreY = 0.5 *
(
( pointOne.x * pointOne.x + pointOne.y * pointOne.y ) * ( pointThree.x - pointTwo.x ) +
( pointTwo.x * pointTwo.x + pointTwo.y * pointTwo.y ) * ( pointOne.x - pointThree.x ) +
( pointThree.x * pointThree.x + pointThree.y * pointThree.y ) * ( pointTwo.x - pointOne.x )
)
/
(
pointOne.y * ( pointThree.x - pointTwo.x ) +
pointTwo.y * ( pointOne.x - pointThree.x ) +
pointThree.y * ( pointTwo.x - pointOne.x )
);
double radius = Math.sqrt( ( centreX - pointOne.x ) * ( centreX - pointOne.x ) +
( centreY - pointOne.y ) * ( centreY - pointOne.y ) );
return new Circle( new Point(centreX, centreY), radius);
}
private static record Circle(Point centre, double radius) {
public String toString() {
return "centre: (" + format(centre.x) + ", " + format(centre.y) + "), radius = " + format(radius);
}
private String format(double value) {
return String.format("%.5f", value);
}
}
private static record Point(double x, double y) {}
}
- Output:
centre: (18.97852, 16.26541), radius = 14.70862
jq
Adapted from Julia
Works with jq, the C implementation of jq
Works with gojq, the Go implementation of jq
# Emit {x,y,r} corresponding to the circle through the three points
# specified as [x,y] pairs.
def findcircle($p1; $p2; $p3):
def assertEq($p; $q): if ($p - $q)|length < 1e-12 then . else "assertion failed: \($p) != \($q)" | error end;
def ss($a; $b) : ($a|.*.) + ($b|.*.);
$p1 as [$a,$b]
| $p2 as [$c,$d]
| $p3 as [$e,$f]
| ($a - $e) as $ae
| ($d - $b) as $db
| ($b - $f) as $bf
| ($e - $c) as $ec
| ($c - $a) as $ca
| ($f - $d) as $fd
| ss($a; $b) as $a2b2
| ss($c; $d) as $c2d2
| ss($e; $f) as $e2f2
| {x: (0.5 * ($a2b2 * $fd + $c2d2 * $bf + $e2f2 * $db) / ($a * $fd + $c * $bf + $e * $db)),
y: (0.5 * ($a2b2 * $ec + $c2d2 * $ae + $e2f2 * $ca) / ($b * $ec + $d * $ae + $f * $ca)) }
# any one of these should do / be nearly identical:
| [ss(.x-$a; .y-$b), ss(.x-$c; .y-$d), ss(.x-$e; .y-$f)] as $r123
| assertEq( $r123|max; $r123|min )
| .r = (($r123 | add) / 3 | sqrt) ;
findcircle( [22.83, 2.07]; [14.39, 30.24]; [33.65, 17.31])
| "Centre = \([.x, .y]), radius = \(.r)"
- Output:
Centre = [18.978515660148815,16.26541079771587], radius = 14.708623978334177
Julia
function findcircle(p1, p2, p3)
a, b = p1
c, d = p2
e, f = p3
a2b2 = a * a + b * b
ae = a - e
db = d - b
c2d2 = c * c + d * d
bf = b - f
ec = e - c
e2f2 = e * e + f * f
ca = c - a
fd = f - d
cx = 0.5 * (a2b2 * fd + c2d2 * bf + e2f2 * db) / (a * fd + c * bf + e * db)
cy = 0.5 * (a2b2 * ec + c2d2 * ae + e2f2 * ca) / (b * ec + d * ae + f * ca)
# any one of these should do / be nearly identical:
r123 = [(cx-a)^2 + (cy-b)^2, (cx-c)^2 + (cy-d)^2, (cx-e)^2 + (cy-f)^2]
@assert maximum(r123) - minimum(r123) < 1e-12
r = sqrt(sum(r123) / length(r123))
return (cx, cy), r
end
ctr, r = findcircle((22.83, 2.07), (14.39, 30.24), (33.65, 17.31))
println("Centre = $ctr, radius = $r")
- Output:
Centre = (18.978515660148815, 16.26541079771587), radius = 14.708623978334177
Kotlin
import kotlin.math.sqrt
data class Point(val x: Double, val y: Double)
fun findCircle(p1: Point, p2: Point, p3: Point): Pair<Point, Double> {
fun sq(x: Double) = x * x
val centreX =
0.5 * (
(sq(p1.x) + sq(p1.y)) * (p3.y - p2.y) +
(sq(p2.x) + sq(p2.y)) * (p1.y - p3.y) +
(sq(p3.x) + sq(p3.y)) * (p2.y - p1.y)
) / (
p1.x * (p3.y - p2.y) +
p2.x * (p1.y - p3.y) +
p3.x * (p2.y - p1.y)
)
val centreY =
0.5 * (
(sq(p1.x) + sq(p1.y)) * (p3.x - p2.x) +
(sq(p2.x) + sq(p2.y)) * (p1.x - p3.x) +
(sq(p3.x) + sq(p3.y)) * (p2.x - p1.x)
) / (
p1.y * (p3.x - p2.x) +
p2.y * (p1.x - p3.x) +
p3.y * (p2.x - p1.x)
)
val centre = Point(centreX, centreY)
val radius = sqrt(sq(centreX - p1.x) + sq(centreY - p1.y))
return Pair(centre, radius)
}
fun main() {
findCircle(Point(22.83,2.07), Point(14.39,30.24), Point(33.65,17.31))
.let { (c, r) ->
println("Centre = $c")
println("Radius = $r")
}
}
- Output:
Centre = Point(x=18.978515660148815, y=16.26541079771587) Radius = 14.70862397833418
Mathematica / Wolfram Language
points = {{22.83, 2.07}, {14.39, 30.24}, {33.65, 17.31}};
centerAndRadiusOfCircleThrough[points_List] := Flatten@Apply[List, CircleThrough[points]];
{x, y, r} = centerAndRadiusOfCircleThrough[points]
- Output:
{18.9785, 16.2654, 14.7086}
PascalABC.NET
uses graphwpf;
type
PointR = record
x, y: real;
end;
CircleR = record
center: PointR;
radius: real;
end;
function FindCircle(p1, p2, p3: PointR): CircleR;
begin
var x12 := p1.x - p2.x;
var x13 := p1.x - p3.x;
var y12 := p1.y - p2.y;
var y13 := p1.y - p3.y;
var y31 := p3.y - p1.y;
var y21 := p2.y - p1.y;
var x31 := p3.x - p1.x;
var x21 := p2.x - p1.x;
var sx13 := p1.x.Sqr - p3.x.Sqr;
var sy13 := p1.y.Sqr - p3.y.Sqr;
var sx21 := p2.x.Sqr - p1.x.Sqr;
var sy21 := p2.y.Sqr - p1.y.Sqr;
var f := (sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13)
/ (2.0 * (y31 * x12 - y21 * x13));
var g := (sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13)
/ (2.0 * (x31 * y12 - x21 * y13));
var c := -(p1.x.Sqr) - p1.y.Sqr - 2.0 * g * p1.x - 2.0 * f * p1.y;
var h := -g;
var k := -f;
var r := (h.Sqr + k.Sqr - c).Sqrt;
Result.center.x := h;
Result.center.y := k;
Result.radius := r;
end;
begin
var p1: PointR := (x: 22.83; y: 2.07);
var p2: PointR := (x: 14.39; y: 30.24);
var p3: PointR := (x: 33.65; y: 17.31);
var solved := FindCircle(p1, p2, p3);
Println(solved);
setMathematicCoords(0, 60, 0, true);
Circle(solved.center.x, solved.center.y, solved.radius);
Line(p1.x, p1.y, p2.x, p2.y);
Line(p1.x, p1.y, p3.x, p3.y);
Line(p2.x, p2.y, p3.x, p3.y);
end.
- Output:
((18.9785156601488,16.2654107977159),14.7086239783342)
Perl
# 20240914 Perl programming solution
use strict;
use warnings;
sub circle {
my ($point1, $point2, $point3) = @_;
my (($x1, $y1), ($x2, $y2), ($x3, $y3)) = ( @$point1, @$point2, @$point3);
my $C_x = ((($x1**2 + $y1**2) * ($y3 - $y2) +
($x2**2 + $y2**2) * ($y1 - $y3) +
($x3**2 + $y3**2) * ($y2 - $y1)) /
($x1*($y3 - $y2) + $x2*($y1 - $y3) + $x3*($y2 - $y1)) / 2);
my $C_y = ((($x1**2 + $y1**2) * ($x3 - $x2) +
($x2**2 + $y2**2) * ($x1 - $x3) +
($x3**2 + $y3**2) * ($x2 - $x1)) /
($y1*($x3 - $x2) + $y2*($x1 - $x3) + $y3*($x2 - $x1)) / 2);
my $radius = sqrt(($C_x - $x1)**2 + ($C_y - $y1)**2);
return { center => [$C_x, $C_y], radius => $radius };
}
my $result = circle([22.83, 2.07], [14.39, 30.24], [33.65, 17.31]);
print "center => (", join(" ", @{$result->{center}}), ") radius => ", $result->{radius}, "\n";
You may Attempt This Online!
Phix
with javascript_semantics
function circle(sequence p1, p2, p3)
atom {a,b} = p1, {c,d} = p2, {e,f} = p3,
a2b2 = a*a+b*b, ae = a-e, db = d-b,
c2d2 = c*c+d*d, bf = b-f, ec = e-c,
e2f2 = e*e+f*f, ca = c-a, fd = f-d,
cx = 0.5*(a2b2*fd+c2d2*bf+e2f2*db)/(a*fd+c*bf+e*db),
cy = 0.5*(a2b2*ec+c2d2*ae+e2f2*ca)/(b*ec+d*ae+f*ca)
-- any one of these should do / be nearly identical:
sequence r123 = {power(cx-a,2)+power(cy-b,2),
power(cx-c,2)+power(cy-d,2),
power(cx-e,2)+power(cy-f,2)}
assert((max(r123)-min(r123))<1e-12)
atom r = sqrt(average(r123))
return {{cx,cy},r}
end function
atom {{cx,cy},r} = circle({22.83,2.07},{14.39,30.24},{33.65,17.31})
printf(1,"Centre = %.8f, %.7f, radius = %.6f\n",{cx,cy,r})
- Output:
Centre = 18.97851566, 16.2654108, radius = 14.708624
Python
# 3pt_center_radius.py by Xing216
# https://math.stackexchange.com/questions/213658/get-the-equation-of-a-circle-when-given-3-points
# https://web.archive.org/web/20060909065617/http://www.math.okstate.edu/~wrightd/INDRA/MobiusonCircles/node4.html
def circle_from_3_points(z1:complex, z2:complex, z3:complex) -> tuple[complex, float]:
if (z1 == z2) or (z2 == z3) or (z3 == z1):
raise ValueError(f"Duplicate points: {z1}, {z2}, {z3}")
w = (z3 - z1)/(z2 - z1)
# You should change 0 to a small tolerance for floating point comparisons
if abs(w.imag) <= 0:
raise ValueError(f"Points are collinear: {z1}, {z2}, {z3}")
c = (z2 - z1)*(w - abs(w)**2)/(2j*w.imag) + z1 # Simplified denominator
r = abs(z1 - c)
return c, r
center, radius = circle_from_3_points(22.83+2.07j,14.39+30.24j,33.65+17.31j)
print(f"centerpoint: ({round(center.real,2)}, {round(center.imag, 2)})\nradius: {round(radius, 2)}")
- Output:
centerpoint: (18.98, 16.27) radius: 14.71
Raku
Don't bother defining all the intermediate variables.
sub circle( (\𝒳ᵢ, \𝒴ᵢ), (\𝒳ⱼ, \𝒴ⱼ), (\𝒳ₖ, \𝒴ₖ) ) {
my \𝒞ₓ = ((𝒳ᵢ² + 𝒴ᵢ²) × (𝒴ₖ - 𝒴ⱼ) + (𝒳ⱼ² + 𝒴ⱼ²) × (𝒴ᵢ - 𝒴ₖ) + (𝒳ₖ² + 𝒴ₖ²) × (𝒴ⱼ - 𝒴ᵢ)) /
(𝒳ᵢ × (𝒴ₖ - 𝒴ⱼ) + 𝒳ⱼ × (𝒴ᵢ - 𝒴ₖ) + 𝒳ₖ × (𝒴ⱼ - 𝒴ᵢ)) / 2 ;
my \𝒞ᵧ = ((𝒳ᵢ² + 𝒴ᵢ²) × (𝒳ₖ - 𝒳ⱼ) + (𝒳ⱼ² + 𝒴ⱼ²) × (𝒳ᵢ - 𝒳ₖ) + (𝒳ₖ² + 𝒴ₖ²) × (𝒳ⱼ - 𝒳ᵢ)) /
(𝒴ᵢ × (𝒳ₖ - 𝒳ⱼ) + 𝒴ⱼ × (𝒳ᵢ - 𝒳ₖ) + 𝒴ₖ × (𝒳ⱼ - 𝒳ᵢ)) / 2 ;
center => (𝒞ₓ,𝒞ᵧ), radius => ((𝒞ₓ - 𝒳ᵢ)² + (𝒞ᵧ - 𝒴ᵢ)²).sqrt
}
say circle (22.83,2.07), (14.39,30.24), (33.65,17.31);
- Output:
(center => (18.97851566 16.2654108) radius => 14.70862397833418)
You may Attempt This Online!
Swift
import Foundation
import Matrix
extension Matrix where Element: SignedNumeric {
func minor(row: Int, column: Int) -> Element {
var submatrix = self
_ = submatrix.remove(rowAt: row - 1)
_ = submatrix.remove(columnAt: column - 1)
return submatrix.determinant as Element
}
}
enum MatrixErrors: Error {
case notEnoughPoints, tooManyPoints, pointsOnALine, miscError
}
func circleFrom3Points(points: (Double,Double)... ) throws -> (Double,Double,Double){
var pointArray: [[Double]] = [[0,0,0,0]]
for p in points {
pointArray.append([pow(p.0, 2) + pow(p.1, 2), p.0, p.1, 1])
}
guard pointArray.count > 3 else { throw MatrixErrors.notEnoughPoints }
guard pointArray.count < 5 else { throw MatrixErrors.tooManyPoints }
var matrix = Matrix(elements:pointArray)
var m11 = matrix.minor(row: 1, column: 1)
guard m11 != 0 else { throw MatrixErrors.pointsOnALine }
var m12 = matrix.minor(row: 1, column: 2)
var m13 = matrix.minor(row: 1, column: 3)
let x = 0.5 * m12 / m11
let y = -0.5 * m13 / m11
let r = (pow(x - pointArray[1][1],2) + pow(y - pointArray[1][2],2)).squareRoot()
return (x,y,r)
}
do {
let (x,y,r) = try circleFrom3Points(points: (22.83,2.07), (14.39,30.24), (33.65,17.31))
print("x:\(x), y:\(y), r: \(r)")
} catch {
debugPrint(error)
exit(1)
}
x:18.978515660148812, y:16.265410797715873, r: 14.708623978334185
Uiua
# Find centre of circle given 3 points on its radius.
Ps ← [[22.83 2.07] [14.39 30.24] [33.65 17.31]]
Diffs ← ↻¯1-↻¯1.Ps
Squares ← ≡(/+≡(×.))Ps
Tops ← ⇌÷2/+×Squares Diffs
Bots ← /+ ×Ps ≡⇌Diffs
&p $"Centre of circle\n_\n" .÷ Bots Tops
≡(√/+×.-)Ps ¤
&p $"The distances to the 3 points (i.e. r)\n_"
- Output:
Centre of circle [18.978515660148815 16.26541079771587] The distances to the 3 points (i.e. r) [14.70862397833418 14.708623978334176 14.708623978334177]
Tacit version
Terse too.
[[22.83 2.07] [14.39 30.24] [33.65 17.31]]
⊸⊃(≡(/+≡(×.))|↻¯1-↻¯1.). # Squares and diffs
÷⊃(/+ × ≡⇌◌|⇌÷2/+×) # Find centre
≡(⍜(×100)⁅)⊂⟜(√/+×.-⊙⊢) # Derive radius, round
- Output:
[18.98 16.27 14.71]
Wren
This follows the lines of the C++ code here.
var findCircle = Fn.new { |x1, y1, x2, y2, x3, y3|
var x12 = x1 - x2
var x13 = x1 - x3
var y12 = y1 - y2
var y13 = y1 - y3
var y31 = y3 - y1
var y21 = y2 - y1
var x31 = x3 - x1
var x21 = x2 - x1
var sx13 = x1 * x1 - x3 * x3
var sy13 = y1 * y1 - y3 * y3
var sx21 = x2 * x2 - x1 * x1
var sy21 = y2 * y2 - y1 * y1
var f = sx13 * x12 + sy13 * x12 + sx21 * x13 + sy21 * x13
f = f / (y31 * x12 - y21 * x13) / 2
var g = sx13 * y12 + sy13 * y12 + sx21 * y13 + sy21 * y13
g = g / (x31 * y12 - x21 * y13) / 2
var c = -x1 * x1 - y1 * y1 - 2 * g * x1 - 2 * f * y1
var h = -g
var k = -f
var r = (h * h + k * k - c).sqrt
return [h, k, r]
}
var hkr = findCircle.call(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
System.print("Centre is at %([hkr[0], hkr[1]])")
System.print("Radius is %(hkr[2])")
System.print("\nCheck radius as the distance between the centre and the first point:")
System.print(((22.83 - hkr[0]).pow(2) + (2.07 - hkr[1]).pow(2)).sqrt)
- Output:
Centre is at [18.978515660149, 16.265410797716] Radius is 14.708623978334 Check radius as the distance between the centre and the first point: 14.708623978334
XPL0
proc FindCircle(X1, Y1, X2, Y2, X3, Y3);
real X1, Y1, X2, Y2, X3, Y3;
real X12, X13, Y12, Y13, Y31, Y21, X31, X21,
SX13, SY13, SX21, SY21,
F, G, C, H, K, R;
[
X12:= X1 - X2;
X13:= X1 - X3;
Y12:= Y1 - Y2;
Y13:= Y1 - Y3;
Y31:= Y3 - Y1;
Y21:= Y2 - Y1;
X31:= X3 - X1;
X21:= X2 - X1;
SX13:= sq(X1) - sq(X3);
SY13:= sq(Y1) - sq(Y3);
SX21:= sq(X2) - sq(X1);
SY21:= sq(Y2) - sq(Y1);
F:= (SX13*X12 + SY13*X12 + SX21*X13 + SY21*X13) / (2.*(Y31*X12 - Y21*X13));
G:= (SX13*Y12 + SY13*Y12 + SX21*Y13 + SY21*Y13) / (2.*(X31*Y12 - X21*Y13));
C:= -sq(X1) - sq(Y1) - 2.*G*X1 - 2.*F*Y1;
H:= -G;
K:= -F;
R:= sqrt(H*H + K*K - C);
Text(0, "Centre is at "); RlOut(0, H); Text(0, ", "); RlOut(0, K); CrLf(0);
Text(0, "Radius is "); RlOut(0, R);
];
FindCircle(22.83, 2.07, 14.39, 30.24, 33.65, 17.31)
- Output:
Centre is at 18.97852, 16.26541 Radius is 14.70862