Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Pascal]Геометрия


Автор: dimentiys 17.3.2008, 17:59
С помощью графики отобразить на экране дисплея ход решения следующей задачи: из заданного на плоскости множества точек выбрать такие три точки, не лежащие на одной прямой, которые составляют треугольник наименьшей площади. 

Автор: ama_kid 19.3.2008, 13:26
Лови такой вариант:  smile 
Код
Program Triangles;
uses crt, graph;
const MaxPoints = 100;
const delta = 0.01;
type
 TPoint = PointType;
 TPointArray = array [1..MaxPoints] of TPoint;
 TMinimumInfo = record
  P1          : TPoint;
  P2          : TPoint;
  P3          : TPoint;
  Square      : double;
 end;
var
 gd,gm    :integer;
 NumPts   :integer;
 i        :integer;
 j,k      :integer;
 sleep    :longint;
 Points   :TPointArray;
 Min      :TMinimumInfo;

procedure CheckTriangleInfo(P1,P2,P3:TPoint;var MinimumInfo:TMinimumInfo);
var
 S:double;
 p:double;
 a,b,c:double;
begin
 a:=sqrt(sqr(1.0*(P2.X-P1.X))+sqr(1.0*(P2.Y-P1.Y)));
 b:=sqrt(sqr(1.0*(P3.X-P2.X))+sqr(1.0*(P3.Y-P2.Y)));
 c:=sqrt(sqr(1.0*(P1.X-P3.X))+sqr(1.0*(P1.Y-P3.Y)));
 p:=(a+b+c)/2;
 S:=sqrt(p*(p-a)*(p-b)*(p-c));
 if (S<MinimumInfo.Square)or(MinimumInfo.Square<0) then
  begin
   MinimumInfo.P1:=P1;
   MinimumInfo.P2:=P2;
   MinimumInfo.P3:=P3;
   MinimumInfo.Square:=S;
  end;
end;

function TriangleIsCorrect(P1,P2,P3:TPoint):boolean;
var
 a,b,c:double;
begin
 TriangleIsCorrect:=true;
 a:=sqrt(sqr(1.0*(P2.X-P1.X))+sqr(1.0*(P2.Y-P1.Y)));
 b:=sqrt(sqr(1.0*(P3.X-P2.X))+sqr(1.0*(P3.Y-P2.Y)));
 c:=sqrt(sqr(1.0*(P1.X-P3.X))+sqr(1.0*(P1.Y-P3.Y)));
 if (abs(a - (b+c))<delta)or
    (abs(b - (a+c))<delta)or
    (abs(c - (a+b))<delta) then TriangleIsCorrect:=false;
end;

Procedure DrawAllPoints;
var
 Cur:integer;
begin
 SetColor(white);
 for Cur:=1 to NumPts do
  begin
   Circle(Points[Cur].X,Points[Cur].Y,2);
   FloodFill(Points[Cur].X,Points[Cur].Y,white);
  end;
end;

procedure DrawTriangle(P1,P2,P3:TPoint;Filled:boolean);
var
 Pts:array [1..4] of TPoint;
begin
 Pts[1]:=P1;
 Pts[2]:=P2;
 Pts[3]:=P3;
 Pts[4]:=P1;
 SetColor(Random(10)+3);
 if not Filled then DrawPoly(4,Pts) else FillPoly(4,Pts);
end;

begin
 NumPts:=0;
 Min.Square:=-1.0;

 while (NumPts<=2)or(NumPts>MaxPoints) do
  begin
   clrscr;
   Write('Введите количество точек: ');
   Readln(NumPts);
  end;
 for i:=1 to NumPts do
  begin
   Write('Точка ',i,'. Координата Х (0..640):');
   Readln(Points[i].X);
   if (Points[i].X<10) then Points[i].X:=10;
   if (Points[i].X>630) then Points[i].X:=630;
   Write('Точка ',i,'. Координата Y (0..480):');
   Readln(Points[i].Y);
   if (Points[i].Y<10) then Points[i].Y:=10;
   if (Points[i].Y>470) then Points[i].Y:=470;
  end;
 InitGraph(gd,gm,'');
 ClearDevice;
 If GraphResult <> grOk Then
  begin
   Writeln('Не удалось инициализировать графический режим...');
   Writeln('Завершение работы');
   Halt(1);
  end;
 for i:=1 to NumPts-2 do
  for j:=i+1 to NumPts-1 do
   for k:=j+1 to NumPts do
    begin
     if not TriangleIsCorrect(Points[i],Points[j],Points[k]) then continue;
     ClearDevice;
     DrawAllPoints;
     CheckTriangleInfo(Points[i],Points[j],Points[k],Min);
     DrawTriangle(Points[i],Points[j],Points[k],false);
     for sleep:=1 to 100000000 do ;
    end;
 ClearDevice;
 DrawAllPoints;
 DrawTriangle(Min.P1,Min.P2,Min.P3,true);
 while keypressed do readkey;
 readkey;
 CloseGraph;
end.

Автор: ama_kid 19.3.2008, 17:37
подредактировал немного...

Автор: dimentiys 19.3.2008, 19:23
[подредактировал немного... 



--------------------]
Скажи пожалуйста что это обозначает.

Автор: THandle 19.3.2008, 19:28
dimentiys, это означает то что тот пост был написан в 13:26, а подредактирован в 17:37. То есть изначально там был другой код видимо smile 

Автор: ama_kid 19.3.2008, 19:33
Цитата(THandle @  19.3.2008,  19:28 Найти цитируемый пост)
То есть изначально там был другой код видимо
точно, я там просто внешний лоск небольшой навел, когда вернулся с местной командировки  smile 

Автор: dimentiys 19.3.2008, 20:56
А у кого нибудь будет модуль graph?

Автор: ama_kid 19.3.2008, 21:35
Цитата(dimentiys @  19.3.2008,  20:56 Найти цитируемый пост)
А у кого нибудь будет модуль graph? 
Вобще-то, он лежит в папке Units стандартной поставки Turbo\Borland Pascal, но если у тебя нет(хотя маловероятно), то в аттаче прикрепляю (а также драйвер видеорежима, который должен лежать в папке с программой)... 
P.S. Проверь, что все пути в настройках указаны правильно...

Автор: dimentiys 19.3.2008, 22:00
Спасибо!

Автор: dimentiys 19.3.2008, 23:20
Я посмотрел твою прогу, в результате получается все точки на одной линии но на разном расстоянии, вне зависимости какие я координаты Y задавал.И еще может как нибудь можно в результате получившийся треугольник наименьшей площади из множества точек как нибудь выделить(соединить линиями). 

Автор: ama_kid 20.3.2008, 00:43
dimentiys, что-то ты не то говоришь, у меня всё нормально работает... Покажи какие данные задавал, я проверю...

Автор: dimentiys 20.3.2008, 17:27
Например:(23-43),(132;234),(12;47),(78;367),(68;98)

Автор: ama_kid 20.3.2008, 18:20
Цитата(dimentiys @  19.3.2008,  23:20 Найти цитируемый пост)
в результате получается все точки на одной линии но на разном расстоянии, вне зависимости какие я координаты Y задавал.
Не знаю, я ввел твои данные, все треугольники перебираемые - хорошо заметны (проверял программу как на винде, так и в чистом DOS на VM), я не заметил, чтобы точки лежали на одной линии... В общем, у меня все нормально отрабатывает...  smile 
Цитата(dimentiys @  19.3.2008,  23:20 Найти цитируемый пост)
может как нибудь можно в результате получившийся треугольник наименьшей площади из множества точек как нибудь выделить(соединить линиями).
Получившийся треугольник не только выделяется линиями в конце, но и закрашивается сплошным цветом вообще-то...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)