Коло через три точки


13

Давши декартові координати трьох точок на площині, знайдіть рівняння кола через них усіх. Три точки не будуть на прямій.

Кожен рядок введення до вашої програми буде містити xі yкоординати трьох точок у порядку A(x),A(y),B(x),B(y),C(x),C(y). Ці координати будуть дійсними числами менше ніж 1 000 000, відокремленими один від одного пробілом.

Розв’язання має бути надруковано як рівняння форми (x-h)^2 + (y-k)^2 = r^2. Значення h, k, rповинні бути надруковані з трьома цифрами після десяткової точки. Знаки плюс і мінус у рівняннях слід змінювати за необхідності, щоб уникнути декількох знаків перед числом.

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

Чи можемо ми використовувати замість них полярні чи параметричні рівняння?
Пітер Олсон

@peter Ні. Таким чином, складно буде порівняти з іншими відповідями.
fR0DDY

Що слід отримати у випадку, якщо не існує унікального рішення? Які обмеження існують щодо чисельної стійкості?
Пітер Тейлор

@ peter-taylor У задачі задачі зазначено, що "Три точки не будуть на прямій лінії".
fR0DDY

2
Зрозуміло, що це всього лише кілька символів, тому це не є сказом, що моє рішення може бути на кілька коротших, просто чесне питання ... але якщо пробіл знаходиться у специфікації виводу, чи не повинно це бути обов'язково? Інакше, у коді-гольф, чому б хто-небудь зустрічався із специфікацією виходу?
Ребекка Чернофф

Відповіді:


6

Пітон, 176 189 символів

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

Робить усю свою роботу в складній площині. Я переходжу математику з нижньої частини цієї сторінки . -cє центром кола.


@Joey: так, мій поганий. Виправлено.
Кіт Рендалл

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

Це знаходить 2 лінії між AB та BC. Потім він знаходить, де перетинаються бісектриси цих двох ліній. (Що я щойно помітив - це те, що згадував @PeterTaylor у своєму коментарі до @PeterOfTheCorn.)


2

Рубі, 192 символи

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

Приклади використання:

$ 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

Вбудовування завдання до x, yі rу виклику %повинно допомогти, якщо це можливо.
Lowjacker

@Joey: Вибачте, мабуть, пропустив це, читаючи запитання. Виправлено це зараз.
Вентеро

1

Вольфрам Альфа (27)

Я кажу, використовуйте належний інструмент для роботи.

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

Приклад тут .


6
Немає обробки вводу? Немає підтримки для декількох рядків введення? Я б сказав, що це не відповідає.
Joey

0

Javascript (299)

Єдиний спосіб, який я міг думати, щоб вирішити це, - це алгебраїчно розв'язати три рівняння для трьох невідомих, щоб знайти h, k і 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+"²");

Приклад вводу / виводу:

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²

Єдина помилка, яку я бачу, - це те, що якщо h або k негативний, він виводиться --замість +.


2
Це можна зробити за допомогою циркуля і прямого краю. Візьміть дві точки, намалюйте лінію, яка їх ділить. Візьміть різну пару з двох очок, дітто. Знайдіть перехрестя. Чи це призводить до скорочення коду, мені ще належить розслідувати.
Пітер Тейлор

Це обробляє лише один рядок вводу, правда?
Joey

@Joey, так. Чи потрібна проблема для обробки кількох ліній?
Пітер Олсон

1
Цитуючи завдання: "Кожен рядок введення у вашу програму буде містити координати x і y трьох точок ..."
Joey
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.