14
\$\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\$
9
  • \$\begingroup\$ Can we use polar or parametric equations instead? \$\endgroup\$ Apr 27, 2011 at 15:38
  • \$\begingroup\$ @peter No. That way it will be difficult to compare with other answers. \$\endgroup\$
    – fR0DDY
    Apr 27, 2011 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\$ Apr 27, 2011 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, 2011 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\$ May 9, 2011 at 17:43

4 Answers 4

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\$
1
  • \$\begingroup\$ @Joey: yep, my bad. Fixed. \$\endgroup\$ May 9, 2011 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\$
0
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\$
2
  • \$\begingroup\$ Inlining the assignments to x, y and r in the call to % should help, if possible. \$\endgroup\$
    – Lowjacker
    Apr 28, 2011 at 17:02
  • \$\begingroup\$ @Joey: Sorry, apparently missed that when reading the question. Fixed it now. \$\endgroup\$
    – Ventero
    May 9, 2011 at 8:38
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\$
4
  • 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\$ Apr 27, 2011 at 19:58
  • \$\begingroup\$ This handles only a single line of input, right? \$\endgroup\$
    – Joey
    May 9, 2011 at 0:57
  • \$\begingroup\$ @Joey, yes. Does the problem require multiple line handling? \$\endgroup\$ May 9, 2011 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, 2011 at 2:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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