13
\$\begingroup\$

Given the Cartesian coordinates of three points on a plane, find the equation of the circle through them all. The three points will not be on a straight line.

Each line of input to your program will contain the x and y coordinates of three points, in the order A(x),A(y),B(x),B(y),C(x),C(y). These coordinates will be real numbers less than 1,000,000 separated from each other by space.

The solution is to be printed as an equation of the form (x-h)^2 + (y-k)^2 = r^2. Values for h, k, r are to be printed with three digits after the decimal point. Plus and minus signs in the equations should be changed as needed to avoid multiple signs before a number.

Sample Inputs

7.0 -5.0 -1.0 1.0 0.0 -6.0
1.0 7.0 8.0 6.0 7.0 -2.0

Sample Outputs

(x - 3.000)^2 + (y + 2.000)^2 = 5.000^2
(x - 3.921)^2 + (y - 2.447)^2 = 5.409^2
\$\endgroup\$
  • \$\begingroup\$ Can we use polar or parametric equations instead? \$\endgroup\$ – Peter Olson Apr 27 '11 at 15:38
  • \$\begingroup\$ @peter No. That way it will be difficult to compare with other answers. \$\endgroup\$ – fR0DDY Apr 27 '11 at 15:52
  • \$\begingroup\$ What should be output in the case that there isn't a unique solution? What constraints are there on numerical robustness? \$\endgroup\$ – Peter Taylor Apr 27 '11 at 21:31
  • \$\begingroup\$ @peter-taylor It is given in the problem statement that 'The three points will not be on a straight line.' \$\endgroup\$ – fR0DDY Apr 28 '11 at 2:56
  • 2
    \$\begingroup\$ Granted, it is only a few characters so this isn't a rant that my solution could be a few shorter, just an honest question...but if whitespace is in the output spec, shouldn't it be mandatory? Otherwise, in a code-golf, why would anyone meet the output spec? \$\endgroup\$ – Rebecca Chernoff May 9 '11 at 17:43
6
\$\begingroup\$

Python, 176 189 chars

import sys,re
for s in sys.stdin:x,y,z=eval(re.sub(r'(\S+) (\S+)',r'\1+\2j,',s));w=z-x;w/=y-x;c=(x-y)*(w-abs(w)**2)/2j/w.imag-x;print'(x%+.3f)^2+(y%+.3f)^2=%.3f^2'%(c.real,c.imag,abs(c+x))

Does all its work in the complex plane. I go the math from the bottom of this page. -c is the center of the circle.

\$\endgroup\$
  • \$\begingroup\$ @Joey: yep, my bad. Fixed. \$\endgroup\$ – Keith Randall May 9 '11 at 1:58
2
\$\begingroup\$

C# - 490

using System;class C{static void Main(){Func<string,double>p=s=>double.Parse(s);Func<double,string>t=s=>(s<0?"+ ":"- ")+Math.Abs(s).ToString("F3");foreach(var l in System.IO.File.ReadAllLines("i")){var v=l.Split();double a=p(v[0]),b=p(v[1]),c=p(v[2]),d=p(v[3]),e=p(v[4]),f=p(v[5]),m=(d-b)/(c-a),n=(f-d)/(e-c),x=(m*n*(b-f)+n*(a+c)-m*(c+e))/(2*(n-m)),y=-(x-(a+c)/2)/m+(b+d)/2,r=Math.Sqrt((x-a)*(x-a)+(y-b)*(y-b));Console.WriteLine("(x "+t(x)+")^2+(y "+t(y)+")^2 = "+r.ToString("F3")+"^2");}}}

This finds the 2 lines between AB and BC. Then it finds where the bisects of those 2 lines intersect. (Which I just noticed is what @PeterTaylor mentioned in his comment to @PeterOfTheCorn.)

\$\endgroup\$
2
\$\begingroup\$

Ruby, 192 characters

$<.map{|l|a,b,c,d,e,f=l.split.map &:to_f
n=(f-d)/(e-c)
puts"(x%+.3f)^2+(y%+.3f)^2=%.3f^2"%[x=-(n*(a+c)+(n*(b-f)-(c+e))*m=(d-b)/(c-a))/2/n-=m,y=-(x+(a+c)/2)/m-(b+d)/2,((a+x)**2+(b+y)**2)**0.5]}

Usage examples:

$ echo "7.0 -5.0 -1.0 1.0 0.0 -6.0
1.0 7.0 8.0 6.0 7.0 -2.0" | ruby circle.rb
(x-3.000)^2+(y+2.000)^2=5.000^2
(x-3.921)^2+(y-2.447)^2=5.409^2
\$\endgroup\$
  • \$\begingroup\$ Inlining the assignments to x, y and r in the call to % should help, if possible. \$\endgroup\$ – Lowjacker Apr 28 '11 at 17:02
  • \$\begingroup\$ @Joey: Sorry, apparently missed that when reading the question. Fixed it now. \$\endgroup\$ – Ventero May 9 '11 at 8:38
1
\$\begingroup\$

Wolfram Alpha (27)

I say, use the proper tool for the job.

equation circle ([Input1],[Input2]),([Input3],[Input4]),([Input5],[Input6])

Example here.

\$\endgroup\$
  • 6
    \$\begingroup\$ No input handling? No support for multiple lines of input? I'd say this doesn't qualify. \$\endgroup\$ – Joey May 9 '11 at 0:58
0
\$\begingroup\$

Javascript (299)

The only way that I could think of solving this was algebraically solving three equations for three unknowns to find h, k, and r.

p=prompt().split(' ');a=p[0],b=p[1],c=p[2],d=p[3],e=p[4],f=p[5];h=((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))/2;k=((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))/2;r=Math.sqrt((a-h)*(a-h)+(b-k)*(b-k));alert("(x-"+h+")²+(y-"+k+")²="+r+"²");

Example I/O:

7.0 -5.0 -1.0 1.0 0.0 -6.0 --> (x-3)²+(y--2)²=5²

1.0 7.0 8.0 6.0 7.0 -2.0 --> (x-3.9210526315789473)²+(y-2.4473684210526314)² =5.409159155551175²

The only bug that I see is that if h or k is negative, it outputs -- instead of +.

\$\endgroup\$
  • 2
    \$\begingroup\$ It can be done with compass and straight edge. Take two points, draw the line which bisects them. Take a different pair of two points, ditto. Find the intersection. Whether that leads to shorter code, I have yet to investigate. \$\endgroup\$ – Peter Taylor Apr 27 '11 at 19:58
  • \$\begingroup\$ This handles only a single line of input, right? \$\endgroup\$ – Joey May 9 '11 at 0:57
  • \$\begingroup\$ @Joey, yes. Does the problem require multiple line handling? \$\endgroup\$ – Peter Olson May 9 '11 at 1:59
  • 1
    \$\begingroup\$ Quoting from the task: »Each line of input to your program will contain the x and y coordinates of three points ...« \$\endgroup\$ – Joey May 9 '11 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.