Помощь - Поиск - Пользователи - Календарь
Полная версия: Площадь окружности и треугольника
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
milfes
Есть задача, надо из множества точек выбрать три так, что бы разница между площадью круга и треугольника проходящими через эти точки была минимальна.
Но выдает ошибку, Error 207:Invalid floating point operation,когда чмсло точек больше 14.
Вот текст программы, подскажите в чем может быть ошибка
program graphpoints;
uses crt,graph;
const nmax=1000;
type t_point=record
       x:longint;
       y:longint;
     end;
var p:array[1..nmax]of t_point;
maxx,maxy,j,n,i,k,x1,x2,x3,y1,y2,y3,l:longint;
driver,mode:integer;
t,tbest,r,a,b,rb,c,per,sk,skb,st,stb,d,db:real;
rad,radb:t_point;

procedure generatedata;
      var i:integer;
      begin
        for i:=1 to n do
          begin
            p[i].x:=random(maxx);
            p[i].y:=random(maxy);
          end;
      end;

Function FindOuterRadius(A, B, C : t_point; Var Rr : t_point): Boolean;
Var M : Array[1..2,1..3] Of Extended;
    D, Dx, Dy : Extended;
Begin
 M[1, 1] := 2 * (A.X - B.X);
 M[1, 2] := 2 * (A.Y - B.Y);
 M[1, 3] := Sqr(A.X) +Sqr(A.Y) - (Sqr(B.X) + Sqr(B.Y));

 M[2, 1] := 2 * (B.X - C.X);
 M[2, 2] := 2 * (B.Y - C.Y);
 M[2, 3] := Sqr(B.X) +Sqr(B.Y) - (Sqr(C.X) + Sqr(C.Y));

 D := M[1, 1] * M[2, 2] - M[2, 1] * M[1, 2];
 Dx := M[1, 3] * M[2, 2] - M[2, 3] * M[1, 2];
 Dy := M[1, 1] * M[2, 3] - M[2, 1] * M[1, 3];

 If D <> 0 Then
  Begin
   Rr.X := trunc(Dx/D);
   Rr.Y := trunc(Dy/D);
   FindOuterRadius := True;
  End Else
  Begin
   Rr.X := 0;
   Rr.Y := 0;
   FindOuterRadius := False;
  End;
End;

begin
  randomize;
  write('Введите количество точек: ');
  readln(n);
  driver:=detect;
  initgraph(driver,mode,'d:\tp\bgi');
  maxx:=getmaxx;
  maxy:=getmaxy;
  generatedata;
  db:=1000000;
  j:=1;
  k:=1;
  for i:=1 to n do
  begin
      putpixel(p[i].x,p[i].y,white);
      circle(p[i].x,p[i].y,1);
  end;
  for i:=1 to n-2 do
  begin
       for j:=i+1 to n-1 do
       begin
            for k:=j+1 to n do
            begin
                 if FindOuterRadius(p[i],p[j],p[k],Rad) then
                 begin
                      r:=sqrt(sqr(Rad.x-p[i].x)+sqr(Rad.y-p[i].y));
                      sk:=pi*r*r;
                      a:=sqrt(sqr(p[j].x-p[i].x)+sqr(p[j].y-p[i].y));
                      b:=sqrt(sqr(p[k].x-p[j].x)+sqr(p[k].y-p[j].y));
                      c:=sqrt(sqr(p[i].x-p[k].x)+sqr(p[i].y-p[k].y));
                      per:=(a+b+c)/2;
                      st:=sqrt(per*(per-c)*(per-b)*(per-a));
                      d:=abs(st-sk);
                      if (d<db) and (Rad.x<=maxx) and (Rad.y<=maxy) then
                      begin
                           db:=d;
                           stb:=st;
                           skb:=sk;
                           x1:=p[i].x;
                           x2:=p[j].x;
                           x3:=p[k].x;
                           y1:=p[i].y;
                           y2:=p[j].y;
                           y3:=p[k].y;
                           l:=1;
                           radb.x:=rad.x;
                           radb.y:=rad.y;
                           rb:=r;
                      end;
                 end;
            end;
       end;
  end;
  if l=1 then
  begin
       circle(Radb.x,Radb.y,trunc(rb));
       line(x1,y1,x2,y2);
       line(x2,y2,x3,y3);
       line(x1,y1,x3,y3);
  end;
  readkey;
  closegraph;
  if l=1 then
      writeln('S круга = ',skb,' S треугольника ',stb,' разница между ними ',db)
  else
      writeln('не существует 3 таких точек через которые можно провести окружность');
  readkey;
end.

volvo
Цитата
выдает ошибку, Error 207:Invalid floating point operation,когда чмсло точек больше 14.
При 20 точках прогнал раз 5, никакой ошибки не возникло...
milfes
Хм..странно blink.gif У меня не работает никак, но все равно спасибо.
klem4
На какой строчке программа вылетает, скажи может разберемся

ps скорее всего где-то корень квадратный из нуля или отрицательного берешь ....
milfes
Цитата
На какой строчке программа вылетает, скажи может разберемся


В том то и дело что не показывает где.

Цитата
ps скорее всего где-то корень квадратный из нуля или отрицательного берешь ....


Да вроде нет такого, где это возможно.

st:=sqrt(per*(per-c)*(per-b)*(per-a));


Только если вот тут, так как в остольных случаях из положительных всегда извлекается. Хотя по смыслу тут тоже отрицательным не может быть.
volvo
№207 возникает в одном из следующих случаев:
1) аргумент Trunc/Round не может быть корректно преобразован к значению типа LongInt
2) аргумент Ln равен нулю или отрицателен
3) переполнение стека сопроцессора

Смотри, что у тебя может быть, а чего - нет... Если только третья причина - надо разбивать вычисления из длинных формул на более простые выражения...

В частности, я бы очень сильно посмотрел в сторону:
 If D <> 0 Then
(кто же ТАК сравнивает вещественные значения?)
milfes
Спасибо, у меня всего скорее первое.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.