Решение системы 2-х уравнений с двумя неизвестными
{ ------------------------------------------------------------------------ }
{ решение уравнений вида }
{ |a1*x + b1*y = c1 }
{ |a2*x + b2*y = c2 }
{ }
{ метод решения: }
{ |c1 b1| |a1 c1| }
{ |c2 b2| |a2 c2| }
{ x = --------- y = --------- }
{ |a1 b1| |a1 b1| }
{ |a2 b2| |a2 b2| }
{ }
{ выражаем определители второго порядка: }
{ x = (c1*b2-c2*b1)/(a1*b2-a2*b1) }
{ y = (a1*c2-a2*c1)/(a1*b2-a2*b1) }
{ ------------------------------------------------------------------------ }
var a1,a2,b1,b2,c1,c2,x,y,d,dx,dy:real;
begin
writeln('введите коэффициенты уравнения: a1,b1,c1,a2,b2,c2');
readln(a1,b1,c1,a2,b2,c2);
d := (a1*b2-a2*b1);
dx := (c1*b2-c2*b1);
dy := (a1*c2-a2*c1);
if ( d=0 ) and ( (dx=0) or (dy=0) ) then
writeln('бесконечное множество решений')
else if ( d<>0 ) and ( (dx=0) or (dy=0) ) then
writeln('нет решений')
else begin
x:=dx/d; y:=dy/d;
writeln('x = ', x); writeln('y = ', y);
end;
end.
Решение системы 3-х уравнений с тремя неизвестными
{ ------------------------------------------------------------------------ }
{ решение уравнений вида: }
{ |a1*x + b1*y + c1*z = d1| }
{ |a2*x + b2*y + c2*z = d2| }
{ |a3*x + b3*y + c3*z = d3| }
{ }
{ метод решения: }
{ |d1 b1 c1| |a1 d1 c1| |a1 b1 d1| }
{ |d2 b2 c2| |a2 d2 c2| |a2 b2 d2| }
{ |d3 b3 c3| |a3 d3 c3| |a3 b3 d3| }
{ x = ---------- y = ---------- z = ---------- }
{ |a1 b1 c1| |a1 b1 c1| |a1 b1 c1| }
{ |a2 b2 c2| |a2 b2 c2| |a2 b2 c2| }
{ |a3 b3 c3| |a3 b3 c3| |a3 b3 c3| }
{ }
{ выражаем определители третьего порядка: }
{ e := (a1*b2*c3+b1*c2*a3+c1*a2*b3-a3*b2*c1-b3*c2*a1-c3*a2*b1); }
{ ex := (d1*b2*c3+b1*c2*d3+c1*d2*b3-d3*b2*c1-b3*c2*d1-c3*d2*b1); }
{ ey := (a1*d2*c3+d1*c2*a3+c1*a2*d3-a3*d2*c1-d3*c2*a1-c3*a2*d1); }
{ ez := (a1*b2*d3+b1*d2*a3+d1*a2*b3-a3*b2*d1-b3*d2*a1-d3*a2*b1); }
{ x = ex/e }
{ y = ey/e }
{ z = ez/e }
{ ------------------------------------------------------------------------ }
var a1,a2,a3,b1,b2,b3,c1,c2,c3,d1,d2,d3,x,y,z,e,ex,ey,ez:real;
begin
writeln('введите коэффициенты уравнения:a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3');
readln(a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3);
e := (a1*b2*c3+b1*c2*a3+c1*a2*b3-a3*b2*c1-b3*c2*a1-c3*a2*b1);
ex := (d1*b2*c3+b1*c2*d3+c1*d2*b3-d3*b2*c1-b3*c2*d1-c3*d2*b1);
ey := (a1*d2*c3+d1*c2*a3+c1*a2*d3-a3*d2*c1-d3*c2*a1-c3*a2*d1);
ez := (a1*b2*d3+b1*d2*a3+d1*a2*b3-a3*b2*d1-b3*d2*a1-d3*a2*b1);
if ( e=0 ) and ( (ex=0) or (ey=0) or (ez=0) ) then
writeln('бесконечное множество решений')
else if ( e<>0 ) and ( (ex=0) or (ey=0) or (ez=0) ) then
writeln('нет решений')
else begin
x:=ex/e; y:=ey/e; z:=ez/e;
writeln('x = ', x); writeln('y = ', y); writeln('z = ', z);
end;
end.
Геометрические алгоритмы
Пересекаются ли 2 отрезка?
{ ------------------------------------------------------------------------ }
{ Определяет пересечение отрезков A(ax1,ay1,ax2,ay2) и B (bx1,by1,bx2,by2),}
{ функция возвращает TRUE - если отрезки пересекаются, а если пересекаются }
{ в концах или вовсе не пересекаются, возвращается FALSE (ложь) }
{ ------------------------------------------------------------------------ }
function Intersection(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2:real):boolean;
var v1,v2,v3,v4:real;
begin
v1:=(bx2-bx1)*(ay1-by1)-(by2-by1)*(ax1-bx1);
v2:=(bx2-bx1)*(ay2-by1)-(by2-by1)*(ax2-bx1);
v3:=(ax2-ax1)*(by1-ay1)-(ay2-ay1)*(bx1-ax1);
v4:=(ax2-ax1)*(by2-ay1)-(ay2-ay1)*(bx2-ax1);
Intersection:=(v1*v2<0) and (v3*v4<0);
end;
begin { основная программа, вызов функции - тест }
writeln(Intersection(1,1,5,5,1,2,3,1)); {test1, yes Intersection}
writeln(Intersection(1,1,5,5,1,2,1,3)); {test2, no Intersection}
end.
Точка внутри сектора или нет?
{ ------------------------------------------------------------------------ }
{ Если точка внутри сектора (или на сторонах) - TRUE, если нет - FALSE }
{ tx,ty - вершина сектора }
{ x1,y1,x2,y2 - точки на сторонах сектора }
{ px,py - точка на плоскости }
{ }
{ ------------------------------------------------------------------------ }
{возвращает знак числа, 1 - положительное число, -1 - отрицательное, 0 - 0 }
function sign(r:real):integer;
begin
sign:=0; if r=0 then exit;
if r<0 then sign:=-1 else sign:=1;
end;
function InsideSector(tx,ty,x1,y1,x2,y2,px,py:real):boolean;
var x,y,a1,a2,b1,b2,c1,c2:real;
var i1,i2,i3,i4:integer;
begin
x:=(tx+x1+x2)/3; y:=(ty+y1+y2)/3;
a1:=ty-y1; b1:=x1-tx; c1:=tx*y1-ty*x1;
a2:=ty-y2; b2:=x2-tx; c2:=tx*y2-ty*x2;
i1:=sign(a1*x+b1*y+c1); i2:=sign(a2*x+b2*y+b2);
i3:=sign(a1*px+b1*py+c1); i4:=sign(a2*px+b2*py+c2);
InsideSector:=((i1=i3) and (i2=i4)) or
((i1=0) and (i2=i4)) or
((i1=i3) and (i2=0));
end;
begin { основная программа, вызов функции - тест }
writeln(InsideSector(1,1,5,1,1,5,3,3)); {test1, yes Inside}
writeln(InsideSector(1,1,5,1,7,2,3,3)); {test2, no Intersection}
end.
С какой стороны вектора лежит точка?
{ ------------------------------------------------------------------------ }
{ Если 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 }
{ beta - угол бета для вектора 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.
С какой стороны вектора лежит точка? Вариант 1
{ ------------------------------------------------------------------------ }
{ Идея: обходим треугольник по часовой стрелке. }
{ Точка должна лежать справа от всех сторон, если она внутри }
{ ------------------------------------------------------------------------ }
(* функция определеяет положение точки относительно вектора *)
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.
Арифметические алгоритмы