С какой стороны вектора лежит точка — Pascal(Паскаль)

Если vector(a) и vector(b) — вектора a и b соответственно, то vector(a)*vector(b) = ax*by — ay*bx = a*b*sin(beta-alfa)
ax,ay,bx,by — координаты концов векторов
a — длина вектора a,
b — длина вектора b,
alfa — угол альфа для вектора a
 eta — угол бета для вектора b
Вывод: при общей начальной точке двух векторов их векторное произведение больше нуля, если второй вектор направлен влево от первого, и меньше нуля, если вправо.

Если известны две точки, то вектор, основанный на них можно получить вычитанием двух векторов направленных из начала координат:
Например, есть точка A и точка B
вектор|AB| = Вектор|B| — Вектор|A|, иным словом AB_x = Bx-Ax, AB_y= By-Ay
Таким образом, получается:

Если есть вектор |AB|, заданный координатами ax,ay,bx,by и точка px,py,то для того чтобы узнать лежит ли она слева или справа, надо узнать знак произведения:
(bx-ax)*(py-ay)-(by-ay)*(px-ax)

var i:integer;
 
(* функция определеяет положение точки относительно вектора               *)
Function WherePoint(ax,ay,bx,by,px,py:real):integer;
var s :real;
begin
    s:=(bx-ax)*(py-ay)-(by-ay)*(px-ax);
    if s>0 then WherePoint:=1
    else if s<0 then WherePoint:=-1
    else WherePoint:=0;
end;
 
Begin (* Тело основной программы *)
   i:=WherePoint(1,1,8,8,2,5);
   if i > 0 then writeln('точка слева от вектора')
   else if i < 0 then writeln('точка справа от вектора')
   else writeln('на векторе, прямо по вектору или сзади вектора');
End.

Вариант 2

Идея: обходим треугольник по часовой стрелке. Точка должна лежать справа от всех сторон, если она внутри. Функция определяет положение точки относительно вектора.

(* функция вычисляет расстояние между точками *)
Function WherePoint(ax,ay,bx,by,px,py:real):integer;
var s :real;
begin
    s:=(bx-ax)*(py-ay)-(by-ay)*(px-ax);
    if s>0 then WherePoint:=1
    else if s<0 then WherePoint:=-1
    else WherePoint:=0;
end;
 
(* функция определяет относительное положение точки: внутри или нет *)
Function PointInsideTreangle(ax,ay,bx,by,cx,cy,px,py:real):boolean;
var s1,s2,s3 :integer;
begin
    PointInsideTreangle:=FALSE;
    s1:=WherePoint(ax,ay,bx,by,px,py);
    s2:=WherePoint(bx,by,cx,cy,px,py);
    if s2*s1<=0 then EXIT;
    s3:=WherePoint(cx,cy,ax,ay,px,py);
    if s3*s2<=0 then EXIT;
    PointInsideTreangle:=TRUE;
end;
 
Begin (* Тело основной программы *)
   writeln(PointInsideTreangle(1,1,8,1,1,8,2,2)); {TEST1, Inside}
   writeln(PointInsideTreangle(1,1,8,1,1,8,6,6)); {TEST2, Outside}
End.

Вариант 2

Идея: Пусть есть треугольник ABC и точка P. Если Площадь ABC равна сумме площадей треугольников ABP,BCP,CAP, то точка внутри треугольника.

(* функция вычисляет расстояние между точками *)
Function Distance(ax,ay,bx,by:real):real;
begin
  Distance := sqrt(sqr(ax-bx)+sqr(ay-by));
end;
 
(* функция вычисляет площадь треугольника по формуле Герона *)
Function SqrGeron(ax,ay,bx,by,cx,cy:real):real;
var p,a,b,c :real;
Begin
  a:=Distance(cx,cy,bx,by);
  b:=Distance(ax,ay,cx,cy);
  c:=Distance(ax,ay,bx,by);
  p:=(a+b+c)/2;
  SqrGeron:=sqrt(p*(p-a)*(p-b)*(p-c));
End;
 
(* функция определяет относительное положение точки: внутри или нет *)
Function PointInsideTreangle(ax,ay,bx,by,cx,cy,px,py:real):boolean;
const error = 1.000001;
var s,s1,s2,s3 :real;
begin
    PointInsideTreangle:=TRUE;
    s :=SqrGeron(ax,ay,bx,by,cx,cy);
    s1:=SqrGeron(ax,ay,bx,by,px,py);
    s2:=SqrGeron(bx,by,cx,cy,px,py);
    s3:=SqrGeron(cx,cy,ax,ay,px,py);
    if s*error>s1+s2+s3 then PointInsideTreangle:=TRUE
                        else PointInsideTreangle:=FALSE;
end;
 
Begin (* Тело основной программы *)
   writeln(PointInsideTreangle(1,1,8,1,1,8,2,2)); {TEST1, Inside}
   writeln(PointInsideTreangle(1,1,8,1,1,8,6,6)); {TEST2, Outside}
End.

Leave a Comment