Cerchia attraverso tre punti


13

Date le coordinate cartesiane di tre punti su un piano, trova l'equazione del cerchio attraverso tutte. I tre punti non saranno su una linea retta.

Ogni linea di input per il programma conterrà il xe ycoordinate di tre punti, nell'ordine A(x),A(y),B(x),B(y),C(x),C(y). Queste coordinate saranno numeri reali a meno di 1.000.000 separati l'uno dall'altro dallo spazio.

La soluzione deve essere stampata come equazione del modulo (x-h)^2 + (y-k)^2 = r^2. I valori per h, k, rdevono essere stampate con tre cifre dopo la virgola. I segni più e meno nelle equazioni devono essere modificati secondo necessità per evitare segni multipli prima di un numero.

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

Possiamo usare invece equazioni polari o parametriche?
Peter Olson,

@peter No. In questo modo sarà difficile confrontarsi con altre risposte.
fR0DDY,

Cosa dovrebbe essere prodotto nel caso in cui non ci sia una soluzione unica? Quali sono i vincoli sulla robustezza numerica?
Peter Taylor,

@ peter-taylor Nella dichiarazione del problema viene indicato che "I tre punti non saranno su una linea retta".
fR0DDY,

2
Certo, sono solo pochi caratteri, quindi non è un caso che la mia soluzione potrebbe essere più breve, solo una domanda onesta ... ma se lo spazio bianco è nelle specifiche di output, non dovrebbe essere obbligatorio? Altrimenti, in un code-golf, perché qualcuno dovrebbe soddisfare le specifiche di output?
Rebecca Chernoff,

Risposte:


6

Python, 176 189 caratteri

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

Fa tutto il suo lavoro sul piano complesso. Vado in matematica dal fondo di questa pagina . -cè il centro del cerchio.


@Joey: sì, mio ​​male. Fisso.
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");}}}

Questo trova le 2 linee tra AB e BC. Quindi trova dove si intersecano le bisettrici di quelle 2 linee. (Che ho appena notato è ciò che @PeterTaylor ha menzionato nel suo commento a @PeterOfTheCorn.)


2

Rubino, 192 caratteri

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

Esempi di utilizzo:

$ 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

Inlining le assegnazioni per x, ye rnella chiamata a %dovrebbe aiutare, se possibile.
Lowjacker,

@Joey: Mi dispiace, a quanto pare perso durante la lettura della domanda. Risolto il problema ora.
Ventero,

1

Wolfram Alpha (27)

Dico, utilizzare lo strumento adeguato per il lavoro.

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

Esempio qui .


6
Nessuna gestione degli input? Nessun supporto per più righe di input? Direi che questo non è idoneo.
Joey,

0

Javascript (299)

L'unico modo in cui ho potuto pensare di risolvere questo è stato algebricamente risolvere tre equazioni per tre incognite per trovare h, k e 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+"²");

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

L'unico bug che vedo è che se h o k è negativo, --invece di +.


2
Può essere fatto con bussola e bordo dritto. Prendi due punti, disegna la linea che li taglia in due. Prendi una coppia diversa di due punti, idem. Trova l'incrocio. Se questo porta a un codice più breve, devo ancora indagare.
Peter Taylor,

Questo gestisce solo una singola riga di input, giusto?
Joey,

@Joey, sì. Il problema richiede la gestione di più righe?
Peter Olson,

1
Citando l'attività: »Ogni riga di input per il tuo programma conterrà le coordinate xey di tre punti ...«
Joey
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.