Другие языки программирования и технологии

Как определить точку внутри треугольника? Turbo Delphi

Readln(X1,Y1);
Writeln('Введите координаты второй точки B');
Readln(X2,Y2);
Writeln('Введите координаты третьей точки C');
Readln(X3,Y3);
Writeln('Введите координаты любой точки');
Readln(T1,T2);
AB := SQRT( SQR(X2-X1) + SQR(Y2-Y1));
BC := SQRT( SQR(X3-X2) + SQR(Y3-Y2));
AC := SQRT( SQR(X3-X1) + SQR(Y3-Y1));
P := (AB + BC + AC)/2;
S := SQRT( P * (P - AC) * (P - AB) * (P - BC));
TA := SQRT( SQR(X1-T1) + SQR(Y1-T2));
TB := SQRT( SQR(X2-T1) + SQR(Y2-T2));
TC := SQRT( SQR(X3-T1) + SQR(Y3-T2));
P1 := (TA + AB + TB)/2;
P2 := (TB + BC + TC)/2;
P3 := (TA + AC + TC)/2;
S1 := SQRT( P1 * (P1 - TA) * (P1 - AB) * (P1 - TB));
S2 := SQRT( P2 * (P2 - TB) * (P2 - BC) * (P2 - TC));
S3 := SQRT( P3 * (P3 - TC) * (P3 - AC) * (P3 - TA));

SumOfS := S1 + S2 + S3;
If SumOfS = S then Writeln('Точка находится внутри треугольника')
else If S1 = 0 then Writeln('Точка лежит на стороне треугольника')
else if S2 = 0 then Writeln('Точка лежит на стороне треугольника')
else if S3 = 0 then Writeln('Точка лежит на стороне треугольника')
else Writeln('Точка находится не внутри треугольника');

Readln;

Суть моего метода: точка, находящаяся внутри треугольника разбивает его еще на три маленьких. Так вот если сумма площадей маленьких треугольников совпадет с площадью большого, значит точка внутри. Но ничего не выходит. Все время пишет, что точка не в трегольнике, хотя это не так. Помогите плиз.

Writeln('Введите координаты любой точки');
Readln(T1,T2);
If((T1 - X1) * (Y1 - Y2) - (T2 - Y1) *( X1 - X2)>=0)
and((T1 - X2) * (Y2 - Y3) - (T2 - Y2) * (X2 - X3)>=0)
and((T1 - X3) * (Y3 - Y1) - (T2 - y3) * (X3 - X1)>=0)
then
Writeln('Точка лежит в треугольнике')
else Writeln('Точка не лежит в треугольнике');
Readln;
На просторах сети нашел еще один метод, он у меня тоже срабатывает. Может, что-то у меня с Delphi не так ?(
Во-первых: для работы со связанными структурами данных, лучше использовать записи.
К примеру, для твоей задачи:

type
  CoordType = record
    X, Y : Real;
  end;

var
  A, B, C : CoordType; // Координаты вершин треугольника
  D : CoordType; // Координаты искомой точки

Во-вторых: Для нахождения площади треугольника, заданного своими координатами, есть гораздо проще формулы. А для выполнения однообразных действий, проще воспользоваться подпрограммами.
К примеру, для твоей задачи:

function STriangle(A, B, C : CoordType) : Real;
begin
  Result := Abs(A.X * (B.Y - C.Y) + B.X * (C.Y - A.Y) + C.X * (A.Y - B.Y)) / 2;
end;

Ну и в-третьих: Вычисление действительных значений (хоть компьютером, хоть в ручную) не может быть точным. В них всегда закладываются некоторые погрешности. Поэтому нельзя просто взять и сравнить 2 действительных числа!
Для выявления „примерного равенства“ можно воспользоваться следующим допущением:
две действительные величины можно считать равными, если модуль их разности меньше заданной точности.

Т. е. для твоей задачи это будет выглядеть так:

begin
  Write('Введите через пробел координаты точки A: '); ReadLn(A.X, A.Y);
  Write('Введите через пробел координаты точки B: '); ReadLn(B.X, B.Y);
  Write('Введите через пробел координаты точки C: '); ReadLn(C.X, C.Y);

  Write('Введите через пробел координаты искомой точки: '); ReadLn(D.X, D.Y);

  Write('Точка с координатами (', D.X, ', ', D.Y, ') -');
  if Abs(STriangle(A, B, C) - STriangle(A, B, D) - STriangle(A, D, C) - STriangle(D, B, C)) > 0.0001 then Write('не');
  WriteLn('принадлежит заданному треугольнику. ');
end.
Илья Румянцев
Илья Румянцев
82 621
Лучший ответ
как определить находится ли точка внутри ЛЮБОЙ фигуры:
отбрасываем от точки луч вправо и считаем сколько граней фигуры он пересекает. Если чётное количество, то точка вне вигуры, если нечётное - тогда внутри.

Как это делается? А просто, для каждой грани считаем (x1-x2)/(y1-y2)=k (при увеличении y на 1 наш x увеличивается на k)
теперь xp=k*(y-y1)+x1 - это наша x координата пересечения... если она больше нашего х, а также лежит между x1 и x2 - значит луч пересекает грань. Есть один особенный случай, когда y1-y2 равен нулю, тогда если y лежит между y1 и y2 - значит луч тоже пересекает грань... Итак, в итоге

function peresech(x1, x2, y1, y2, x, y);
var res: boolean; k, xp: double;
begin
if(y1-y20) then
begin
k:=(x1-x2)/(y1-y2);
if (k0) then
begin
xp:=k*(y-y1)+x1;
if ((xp>x) and ((xp=x2)) or ((xp=x1))) then res:=true else res:=false;
end
else res:=false;
end
else
begin
if (((y=y2)) or ((y=y1))) then res:=true else res:=false;
end;
peresech:=res;
end;

запускаем эту функцию для каждой грани, суммируем пересечения и проверяем на чётность (если нигде не ошибся конечно).
Nurlan Esentayev
Nurlan Esentayev
42 952