Kreis durch drei Punkte

13

Bestimmen Sie anhand der kartesischen Koordinaten von drei Punkten in einer Ebene die Gleichung des Kreises durch alle. Die drei Punkte liegen nicht auf einer geraden Linie.

Jede Eingabezeile in Ihr Programm enthält die xund yKoordinaten von drei Punkten in der Reihenfolge A(x),A(y),B(x),B(y),C(x),C(y). Diese Koordinaten sind reelle Zahlen, die kleiner als 1.000.000 sind und durch Leerzeichen voneinander getrennt sind.

Die Lösung soll als Gleichung des Formulars ausgedruckt werden (x-h)^2 + (y-k)^2 = r^2. Werte für h, k, rsind mit drei Stellen hinter dem Komma zu drucken. Plus- und Minuszeichen in den Gleichungen sollten nach Bedarf geändert werden, um Mehrfachzeichen vor einer Zahl zu vermeiden.

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
fR0DDY
quelle
Können wir stattdessen polare oder parametrische Gleichungen verwenden?
Peter Olson
@peter Nein. Auf diese Weise wird es schwierig sein, mit anderen Antworten zu vergleichen.
Freitag,
Was soll ausgegeben werden, wenn es keine eindeutige Lösung gibt? Welche Einschränkungen bestehen für die numerische Robustheit?
Peter Taylor
@ peter-taylor In der Problemstellung wird angegeben, dass die drei Punkte nicht auf einer geraden Linie liegen.
Freitag,
2
Zugegeben, es sind nur ein paar Zeichen, und das ist kein Widerspruch, dass meine Lösung ein paar kürzer sein könnte, nur eine ehrliche Frage ... Aber wenn in der Ausgabespezifikation ein Leerzeichen steht, sollte es nicht obligatorisch sein? Warum würde sonst jemand in einem Code-Golf die Ausgangsspezifikation erfüllen?
Rebecca Chernoff

Antworten:

6

Python, 176 189 Zeichen

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))

Arbeitet alles in der komplexen Ebene. Ich gehe die Mathematik vom Ende dieser Seite . -cist der Mittelpunkt des Kreises.

Keith Randall
quelle
@ Joey: yep, meine schlechte. Fest.
Keith Randall
2

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");}}}

Dies findet die 2 Linien zwischen AB und BC. Dann wird gefunden, wo sich die Halbierungen dieser beiden Linien schneiden. (Was mir gerade aufgefallen ist, ist das, was @PeterTaylor in seinem Kommentar zu @PeterOfTheCorn erwähnt hat.)

Rebecca Chernoff
quelle
2

Ruby, 192 Zeichen

$<.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]}

Anwendungsbeispiele:

$ 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
Ventero
quelle
Inlining die Zuordnungen x, yund rin dem Aufruf %soll, wenn möglich , helfen.
Lowjacker
@ Joey: Sorry, habe das anscheinend beim Lesen der Frage verpasst. Behebt es jetzt.
Ventero
1

Wolfram Alpha (27)

Ich sage, benutze das richtige Werkzeug für den Job.

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

Beispiel hier .

Peter Olson
quelle
6
Keine Eingabehandhabung? Keine Unterstützung für mehrere Eingabezeilen? Ich würde sagen, dass dies nicht qualifiziert.
Joey
0

Javascript (299)

Die einzige Möglichkeit, dies zu lösen, war die algebraische Lösung von drei Gleichungen für drei Unbekannte, um h, k und r zu finden.

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+"²");

Beispiel 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²

Der einzige Fehler, den ich sehe, ist, dass wenn h oder k negativ ist, es --anstelle von ausgibt +.

Peter Olson
quelle
2
Dies kann mit Kompass und gerader Kante erfolgen. Nehmen Sie zwei Punkte und zeichnen Sie die Linie, die sie halbiert. Nehmen Sie ein anderes Paar von zwei Punkten, ebenso. Finde die Kreuzung. Ob das zu kürzerem Code führt, muss ich noch untersuchen.
Peter Taylor
Dies behandelt nur eine einzige Eingabezeile, oder?
Joey
@Joey, ja. Erfordert das Problem die Behandlung mehrerer Zeilen?
Peter Olson
1
Zitat aus der Aufgabe: »Jede Eingabezeile in Ihr Programm enthält die x- und y-Koordinaten von drei Punkten ...«
Joey