Помощь - Поиск - Пользователи - Календарь
Полная версия: Находится ли один треугольник в другом
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
klem4
Даны 2 треугольника, заданные координатами своих вершин, нужно определить находится ли кокой либо из них полностью внутри другого. Алгоритм построен на следующем утверждении:
Если в треугольнике есть такая вершина, что прямая проведенная через нее и заданную точку не пересекает сторону треугольника, противоположную этой вершине, то заданная точка находится вне треугольника.

О найденных ошибках сообщайте сюда: Собираем Ошибки!

uses crt;

const
eps = 0.00001;

type

tfloat = extended;

tpoint = record
x, y: tfloat;
end;

tline = record
p1, p2: tpoint;
k, b : tfloat;
end;

ttriangle = record
top: array [1..3] of tpoint;
end;

{
функция вернет true, если координаты точе p1 и p2 совпадают
}
function points_equal(const p1, p2: tpoint): boolean;
begin
points_equal := (abs(p1.x - p2.x) < eps) and (abs(p1.y - p2.y) < eps)
end;

{
получаем уравнение вида y = k*x+b для прямой по двум точкам,
случаи если прямая параллельна одной из осей, в программе рассматриваются отдельно
}
procedure get_line_equation(var line: tline; const point1, point2: tpoint);
begin
with line do begin

p1.x := point1.x; p1.y := point1.y;
p2.x := point2.x; p2.y := point2.y;

if not((p1.x = p2.x) or (p1.y = p2.y)) then begin
k := (p2.y - p1.y) / (p2.x - p1.x);
b := -p1.x * ((p2.y - p1.y) / (p2.x - p1.x)) + p1.y;
end else begin
k := 0;
b := 0;
end;

end;
end;

{
значение функции заданной прямой line в точке x
}
function get_equation_value(const line: tline; const x: tfloat): tfloat;
begin
get_equation_value := line.k * x + line.b;
end;

{
функция вернет true, если значение value находится между значений A и B
}
function value_between(const value: tfloat; const a, b: tfloat): boolean;
begin
value_between :=
((value >= a) and (value <= b)) or ((value >= b) and (value <= a));
end;

{
функция вернет true, если точка point принадлежит прямой line (не отрезку)
}
function in_line(const point: tpoint; const line: tline): boolean;
begin
with line do begin
if (p1.x = p2.x) then in_line := point.x = p1.x
else if (p1.y = p2.y) then in_line := point.y = p1.y
else in_line := abs(point.y - get_equation_value(line, point.x)) < eps;
end;
end;

{
функция вернет true, если точка point принадлежит отрезку прямой line
крайние точки отрезка line1.p1 и line2.p2
}
function in_piece_line(const point: tpoint; const line: tline): boolean;
var
belongs: boolean;

begin
belongs := in_line(point, line);

if belongs then with line do begin
if abs(p1.x - p2.x) < eps then belongs := belongs and value_between(point.y, p1.y, p2.y)
else belongs := value_between(point.x, p1.x, p2.x)
end;

in_piece_line := belongs;
end;

{
если у прямых line1 и line2 есть точка пересечения, то функция вернет true и cross_point будет
содержать ее координаты
}
function get_crossing_point(const line1, line2: tline;
var cross_point: tpoint): boolean;
begin
if ((abs(line1.p1.x - line1.p2.x) < eps) and (abs(line2.p1.x - line2.p2.x) < eps))
or((abs(line1.p1.y - line1.p2.y) < eps) and (abs(line2.p1.y - line2.p2.y) < eps))
then get_crossing_point := false
else begin

get_crossing_point := true;

if (line1.p1.x = line1.p2.x) then begin

if (line2.p1.y = line2.p2.y) then begin

cross_point.x := line1.p1.x;
cross_point.y := line2.p1.y;

end else begin

cross_point.x := line1.p1.x;
cross_point.y := get_equation_value(line2, cross_point.x);

end;

end else if (line1.p1.y = line1.p2.y) then begin

if (line2.p1.x = line2.p2.x) then begin

cross_point.x := line2.p1.x;
cross_point.y := line1.p1.y;

end else begin

cross_point.y := line1.p1.y;
cross_point.x := (cross_point.y - line2.b) / line2.k;

end;

//
end else if (line2.p1.x = line2.p2.x) then begin

if (line1.p1.y = line1.p2.y) then begin

cross_point.x := line2.p1.x;
cross_point.y := line1.p1.y;

end else begin

cross_point.x := line2.p1.x;
cross_point.y := get_equation_value(line1, cross_point.x);

end;

end else if (line2.p1.y = line2.p2.y) then begin

if (line1.p1.x = line1.p2.x) then begin

cross_point.x := line1.p1.x;
cross_point.y := line2.p1.y;

end else begin

cross_point.y := line2.p1.y;
cross_point.x := (cross_point.y - line1.b) / line1.k;

end;
end else begin

cross_point.x := (line2.b - line1.b) / (line1.k - line2.k);
cross_point.y := get_equation_value(line1, cross_point.x);

end;

end;
end;

{
функция вернет true, если точка point находится в треугольнике triangle
}
function point_in_triangle(const point: tpoint;
const triangle: ttriangle): boolean;
var
test_line, check_side: tline;
cross_point: tpoint;

i, j: integer;
_include: boolean;
begin
i := 1;
_include := false;

while (i <= 2) and not(_include) do begin
j := i + 1;

while (j <= 3) and not(_include) do begin

get_line_equation(test_line, triangle.top[i], triangle.top[j]);

_include := in_piece_line(point, test_line);

inc(j);
end;

inc(i);
end;

if not(_include) then begin
_include := true;

i := 1;
while (i <= 3) and _include do begin

get_line_equation(test_line, triangle.top[i], point);

case i of
1: get_line_equation(check_side, triangle.top[2], triangle.top[3]);
2: get_line_equation(check_side, triangle.top[1], triangle.top[3]);
3: get_line_equation(check_side, triangle.top[1], triangle.top[2]);
end;

_include := get_crossing_point(test_line, check_side, cross_point)
and (in_piece_line(cross_point, check_side));

inc(i);
end;
end;

point_in_triangle := _include;
end;

{
функция вернет true, если треугольник t_1 находится в треугольнике t_2
}
function triangle_in_triangle(const t_1, t_2: ttriangle): boolean;
var
i: byte;
begin
i := 1;
while (i <= 3) and point_in_triangle(t_1.top[i], t_2) do inc(i);
triangle_in_triangle := (i > 3);
end;


var
cross_point: tpoint;
t: array [1..2] of ttriangle;

i, j: byte;

begin
clrscr;

for i := 1 to 2 do
with t[i] do begin
writeln('Enter coords of ', i, ' triangle: ');
writeln;
for j := 1 to 3 do begin
write('top(', j, ').x = '); readln(top[j].x);
write('top(', j, ').y = '); readln(top[j].y);
writeln;
end;
end;

if triangle_in_triangle(t[1], t[2]) then writeln('1 in 2')
else if (triangle_in_triangle(t[2], t[1])) then writeln('2 in 1')
else writeln('none');

readln;
end.

volvo
Находится ли один треугольник в другом

{
функция вернет true, если точка point принадлежит отрезку прямой line,
координаты крайних точек отрезка соотверствую координатам точек,
по которым была построена прямая line: line.p1 и line.p2
}
function in_piece_line(const point: tpoint; const line: tline): boolean;
var
belongs: boolean;

begin
belongs := in_line(point, line);

if belongs then with line do begin
if abs(p1.x - p2.x) < eps then belongs := belongs and value_between(point.y, p1.y, p2.y)
else belongs := belongs and
value_between(point.x, p1.x, p2.x)
end;
end;

Функция ничего не возвращает, обрати внимание - нет идентификатора, определяющего имя функции... Аккуратнее с этим...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.