Задача: Три произвольно заданных точки лежат на окружности. Составить на Паскале программу опредения координат центра этой окружности.
На чем я застрял: раз три точки - ежику ясно: вершины треугольника с описанной вокруг него окружностью. Стороны, площадь, радиус - пожалуйста, не проблема вычислить, т.к. координаты точек есть. Но что дальше? ](*,)
В методичке даже близко подобного ничего нету, включив логику и остатки знаний по геометрии, вторую неделю бьюсь с идеей нахождения через серединные перпендикуляры к сторонам.
Т.е. если одну сторону получившегося треугольника представить, как часть графика функции Y=kX+b, то перпендикуляр, если не ошибаюсь, будет Yp=-X/k+b (так?). Если добавить поправочный коэф-т, чтоб при Хсреднем давал Yсреднее - формула серединного перпендикуляра готова. Но как найти точку пересечения этих самых перпендикуляров (aka центр окружности) - вообще идей нету, школьная математика успела вылететь напрочь за эти годы. Да и было ли оно такое в школе?
А может есть более простой алгоритм? Задачка-то считается обычной контрольной для заочников, всего лишь второе задание из 4, причем остальные три я расщелкал как орешки...
xKVtor Ну не знаю... По твоим формулам у меня вообще выходило нечто жуткое, типа -90372, -285793644. На опечатки при набивке формул проверял несколько раз, но где прятались грабли - так и не нашел.
PS Еще раз спасибо всем принимавшим участие.
Настоящий джентльмен назовет кошку кошкой, даже наступив на нее в темноте.
Что-то ищем? Google в помощь
Хоть минус три мильярда! Если в процедуре CHECK получается три одинаковых радиуса, то значит все верно, таки и должно быть.
Хотя, теперь уже неважно, все равно мои формулы забраковали
ПС [13-06-2006] Идеальный скриншот BIOS'а ? Запросто ! // K.V.
Такие дикие результаты у меня получались после перевода формул с картинки в программу. Причем при одних и тех же исходных данных ответы были каждый раз разные
Мистика, вобщем. Или то, что я вместо extended использовал real 
Так что я сам где-то намудрил. Правда где - так и не понял. :oops: Наверное, зимний авитаминоз на мозги давит
Настоящий джентльмен назовет кошку кошкой, даже наступив на нее в темноте.
Что-то ищем? Google в помощь
DanZer напутал с координатами по Y

при выводе везде надо 'ymax-' подставлять, и ёще вроде где-то индексы перепутал. вот попробуй, тока с делением на ноль сам уж доведи...
дебаг версия:
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; a:array [1..6] of array [1..2] of integer; // координаты точек закинуты в массив a[1,1]=x1, a[1,2]=y1, a[2,1]=x2 и т.д. MyMetafile: TMetafile; b1,b2,k1,k2,xa,ya,xb,yb:real; i:byte; const YMax: Integer = 400; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin {т.к. ось OY идет сверху вниз, значение Y отнимаем от Ymax, чтобы график рисовался как положено, а не вверх ногами} a[1,1]:=119; a[1,2]:=ymax-85; a[2,1]:=257; a[2,2]:=ymax-201; a[3,1]:=166; a[3,2]:=ymax-271; //**************************************** k1:=(a[3,1]-a[2,1]) / (a[2,2]-a[3,2]); k2:=(a[1,1]-a[3,1]) / (a[3,2]-a[1,2]); xa:=( (a[2,1] + a[3,1]) / 2 ); ya:=( (a[2,2] + a[3,2]) / 2 ); xb:=( (a[3,1] + a[1,1]) / 2 ); yb:=( (a[3,2] + a[1,2]) / 2 ); b1:=ya - k1*xa; b2:=yb - k2*xb; {и, наконец, вычисляем координаты центра окружности} a[5,1]:=round( (b2 - b1) / (k1 - k2) ); {это x0} a[5,2]:=round( k1 * a[5,1] + b1 ); {а это y0} //*********************************** if round( k1*a[5,1]+b1) = round( k2*a[5,1]+b2) then Label2.Caption := 'True' else Label2.Caption := 'False'; //********************** k1:=(a[1,1]-a[3,1]) / (a[3,2]-a[1,2]); k2:=(a[2,1]-a[1,1]) / (a[1,2]-a[2,2]); xa:=( (a[3,1] + a[1,1]) / 2 ); ya:=( (a[3,2] + a[1,2]) / 2 ); xb:=( (a[1,1] + a[2,1]) / 2 ); yb:=( (a[1,2] + a[2,2]) / 2 ); b1:=ya-k1*xa; b2:=yb-k2*xb; {и, наконец, вычисляем координаты центра окружности} a[6,1]:=round( (b2 - b1) / (k1 - k2) ); {это x0} a[6,2]:=round( k1 * a[6,1] + b1 ); {а это y0} //*********************************** if round( k1*a[6,1]+b1) = round( k2*a[6,1]+b2) then Label3.Caption := 'True' else Label3.Caption := 'False'; if a[1,2] <> a[2,2] then k1:=(a[2,1]-a[1,1]) / (a[1,2]-a[2,2]) else k1:= 0; if a[3,2] <> a[2,2] then k2:=(a[3,1]-a[2,1]) / (a[2,2]-a[3,2]) else k2:= 0; xa:=( (a[1,1] + a[2,1]) / 2 ); ya:=( (a[1,2] + a[2,2]) / 2 ); xb:=( (a[2,1] + a[3,1]) / 2 ); yb:=( (a[2,2] + a[3,2]) / 2 ); b1:=ya-k1*xa; b2:=yb-k2*xb; {и, наконец, вычисляем координаты центра окружности} a[4,1]:= round( (b2 - b1) / (k1 - k2) ); {это x0} a[4,2]:= round( k1 * a[4,1] + b1 ); {а это y0} if round( k1*a[4,1]+b1) = round( k2*a[4,1]+b2) then Label1.Caption := 'True' else Label1.Caption := 'False'; //********************** {и выводим результаты на экран} MyMetafile := TMetafile.Create; for i:=6 downto 1 do begin with TMetafileCanvas.Create(MyMetafile, 0) do try if i<4 then Brush.Color := clRed else Brush.Color := clYellow; if i=5 then Brush.Color := clBlue; if i=6 then Brush.Color := clGreen; Ellipse(a[i,1]-i*4,ymax-a[i,2]-i*4,a[i,1]+i*4,ymax-a[i,2]+i*4); if i<3 then begin MoveTo(a[i,1],ymax-a[i,2]); LineTo(a[i+1,1], ymax-a[i+1,2]); end; if i=3 then begin MoveTo(a[i,1],ymax-a[i,2]); LineTo(a[1,1], ymax-a[1,2]); end; if i=1 then begin MoveTo( round(xa),ymax-round(ya) ); LineTo( round(xa-50),ymax-round(k1*(xa-50)+b1) ); MoveTo( round(xb),ymax-round(yb) ); LineTo( round(xb-50),ymax-round(k2*(xb-50)+b2) ); end; finally Free; end; Form1.Canvas.Draw(0,0,MyMetafile); end; end; end.--== Михаил ==--
Да ладно, я уже успел нагло передрать функции X0 и Y0 из поста xKVtor'а
прикрутить их к своей программке. Все сошлось. Теперь осталось только комментарии добить и прочее мелкое украшательство, типа генерации координат точек случайным образом. Но с этим я как-нибудь и сам справлюсь! :twisted:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Menus; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; c:integer; a:array [1..4] of array [1..2] of integer; implementation uses Unit2; {$R *.dfm} Function X0:extended; Var chisl,znam:longint; Begin chisl:=(a[3,2]-a[2,2])*(a[1,1]*a[1,1]+a[1,2]*a[1,2])+(a[1,2]-a[3,2])*(a[2,1]*a[2,1]+a[2,2]*a[2,2])+ (a[2,2]-a[1,2])*(a[3,1]*a[3,1]+a[3,2]*a[3,2]); znam :=2*((a[1,2]-a[2,2])*(a[1,1]-a[3,1])-(a[1,2]-a[3,2])*(a[1,1]-a[2,1])); X0:=chisl/znam; End; Function Y0(x0:extended):extended; Var chisl,znam:extended; Begin chisl:=a[1,1]*a[1,1]-a[2,1]*a[2,1]+a[1,2]*a[1,2]-a[2,2]*a[2,2]-2*(a[1,1]-a[2,1])*x0; znam :=2*(a[1,2]-a[2,2]); Y0:=chisl/znam; End; procedure PutCircle(X,Y,R:integer; Solid:Boolean); const YMax: Integer = 400; var MyMetafile: TMetafile; begin MyMetafile := TMetafile.Create; with TMetafileCanvas.Create(MyMetafile, 0) do try if Solid then with Brush do begin Color := clRed; Style := bsSolid; end else Brush.Style := bsClear; Ellipse(X-R,Ymax-(Y-R),X+R,Ymax-(Y+R)); finally Free; end; Form1.Canvas.Draw(0,0,MyMetafile); end; procedure TForm1.FormCreate(Sender: TObject); begin a[1,1]:=257; a[1,2]:=201; a[2,1]:=166; a[2,2]:=279; a[3,1]:=119; a[3,2]:=85; end; procedure TForm1.Form1Click(Sender: TObject); var i,r:byte; begin a[4,1]:=round(X0); a[4,2]:=round(Y0(a[4,1])); for i:=1 to 3 do begin PutCircle(a[i,1],a[i,2],5,True); end; r:=round(sqrt(sqr((a[1,1]-a[4,1]))+sqr((a[1,2]-a[4,2])))); PutCircle(a[4,1],a[4,2],r,False); end; end.Настоящий джентльмен назовет кошку кошкой, даже наступив на нее в темноте.
Что-то ищем? Google в помощь
DanZer попробуй ка координаты (100,100) (200,101) (200,200) а потом (100,100) (200,100) (200,200)
Добавлено спустя 21 минуту 29 секунд:
Сдаётся мне, что проще через окружности считать, тем более радиус известен из площади. :?
--== Михаил ==--
Ну подумаешь, обычное деление на 0, с кем не бывает
Все равно домучаю! :twisted:
Добавлено спустя 7 часов 21 минуту 36 секунд:
Вот!
Настоящий джентльмен назовет кошку кошкой, даже наступив на нее в темноте.
Что-то ищем? Google в помощь
Класс! На 0 деление тока для прямой получается
--== Михаил ==--
Вам вероятность выпадения сразу трех точек с одинаковыми значениями Х или Y посчитать?
Для квадрата 400*400 это будет одна тридцатидвухмиллионная, если я тервер еще не забыл
И так еле успел к 8 марта 
А если серьезно, эта проблема решается легче легкого: просто проверю, если znam=0 - перегенерю координаты.
Настоящий джентльмен назовет кошку кошкой, даже наступив на нее в темноте.
Что-то ищем? Google в помощь
Нуля не будет, я об этом говорил, ведь что бы 0 получился, надо чтоб был не треугольник а прямая или две точки с одинаковыми координатами - что тоже прямая
--== Михаил ==--
Отправить комментарий