unit UCalcVec;
{---------------------------------------------------------------}
interface
{---------------------------------------------------------------}
type
     TVector   = packed array[1..3] of Real;
     TVec2Real = packed array[1..2] of Real;
     TVec2Int  = packed array[1..2] of Integer;
{---------------------------------------------------------------}
const VecZero: TVector = (0, 0, 0);
      VecI: TVector = (1, 0, 0); {Vectorii unitari}
      VecJ: TVector = (0, 1, 0);
      VecK: TVector = (0, 0, 1);
      Pi_c = 3.1415926535897932385;
      Radian = 180 / Pi_c;
{---------------------------------------------------------------}
function  IsNul(v: TVector): boolean;      { v = 0 }
function  Modul(v: TVector): Real;         { |v| }
function  ProdScal(v1, v2: TVector): Real; { v1*v2 }
procedure ProdVec (var r: TVector; v1, v2: TVector); { r := [v1,v2] }
procedure AddVec  (var r: TVector; v1, v2: TVector); { r := v1 + v2 }
procedure SubVec  (var r: TVector; v1, v2: TVector); { r := v1 - v2 }
procedure MulScal (var r: TVector; v: TVector; scal: Real); { r := v * scal }
procedure AddScal (var r: TVector; v: TVector; scal: Real); { r := v + scal }
function  VecParal(var u: TVector; v: TVector; scal: Real): Real; { u // v, |u| = scal }
{---------------------------------------------------------------}
procedure MulScal2D(var r: TVec2Real; v: TVec2Real; scal: Real); { r := v * scal }
procedure AddVec2D (var r: TVec2Real; v1, v2: TVec2Real); { r := v1 + v2 }
procedure SubVec2D (var r: TVec2Real; v1, v2: TVec2Real); { r := v1 - v2 }
{---------------------------------------------------------------}
procedure RotAx(var v: TVector; rad: real; ax: byte); {roteste v cu rad in jurul ax}
procedure RotVec(v1, v2: TVector; rad: real; var x, y: TVector);
function  r(g:real):real; {grade   -> radiani}
function  g(r:real):real; {radiani -> grade  }
{---------------------------------------------------------------}

implementation
{---------------------------------------------------------------}
procedure MulScal2D(var r: TVec2Real; v: TVec2Real; scal: Real);
begin  { r := v * scal }
   r[1] := v[1] * scal;
   r[2] := v[2] * scal;
end;
{---------------------------------------------------------------}
procedure AddVec2D (var r: TVec2Real; v1, v2: TVec2Real);
begin  { r := v1 + v2 }
   r[1] := v1[1] + v2[1];
   r[2] := v1[2] + v2[2];
end;
{---------------------------------------------------------------}
procedure SubVec2D (var r: TVec2Real; v1, v2: TVec2Real);
begin  { r := v1 - v2 }
   r[1] := v1[1] - v2[1];
   r[2] := v1[2] - v2[2];
end;
{---------------------------------------------------------------}
procedure RotAx(var v: TVector; rad: real; ax: byte);
var sn, cs, x, y: real;
    i, j: byte;
begin
   { case ax of 1: Ox; 2: Oy; 3: Oz; }
   sn := sin(rad);  i := ax mod 3 + 1; inc(ax);  x := v[i];
   cs := cos(rad);  j := ax mod 3 + 1;           y := v[j];

   v[i] := x*cs - y*sn;
   v[j] := x*sn + y*cs;
end;
{---------------------------------------------------------------}
procedure RotVec(v1, v2: TVector; rad: real; var x, y: TVector);
var sn, cs: real;
begin {Roteste v1 spre v2}
  sn := sin(rad);
  cs := cos(rad);
  MulScal(x,  v1, cs);  MulScal(y,  v2, cs);
  MulScal(v1, v1, sn);  MulScal(v2, v2, sn);
  SubVec(x, x, v2);     AddVec(y, y, v1);
end;
{---------------------------------------------------------------}
function  VecParal(var u: TVector; v: TVector; scal: Real): Real;
var M: Real;
begin { u // v, |u| = scal }
   M := Modul(v);
   MulScal(u, v, scal/M);
   VecParal := M;
end;
{---------------------------------------------------------------}
procedure MulScal(var r: TVector; v: TVector; scal: Real);
begin  { r := v * scal }
   r[1] := v[1] * scal;
   r[2] := v[2] * scal;
   r[3] := v[3] * scal;
end;
{---------------------------------------------------------------}
procedure AddScal(var r: TVector; v: TVector; scal: Real);
begin  { r := v + scal }
   r[1] := v[1] + scal;
   r[2] := v[2] + scal;
   r[3] := v[3] + scal;
end;
{---------------------------------------------------------------}
procedure AddVec(var r: TVector; v1, v2: TVector);
begin  { r := v1 + v2 }
   r[1] := v1[1] + v2[1];
   r[2] := v1[2] + v2[2];
   r[3] := v1[3] + v2[3];
end;
{---------------------------------------------------------------}
procedure SubVec(var r: TVector; v1, v2: TVector);
begin  { r := v1 - v2 }
   r[1] := v1[1] - v2[1];
   r[2] := v1[2] - v2[2];
   r[3] := v1[3] - v2[3];
end;
{---------------------------------------------------------------}
procedure  ProdVec(var r: TVector; v1, v2: TVector);
begin  { r := [v1,v2] }
   r[1] := v1[2]*v2[3] - v1[3]*v2[2];
   r[2] := v1[3]*v2[1] - v1[1]*v2[3];
   r[3] := v1[1]*v2[2] - v1[2]*v2[1];
end;
{---------------------------------------------------------------}
function  ProdScal(v1, v2: TVector): Real; { v1*v2 }
begin ProdScal := v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3] end;
{---------------------------------------------------------------}
function  Modul(v: TVector): Real; { |v| }
begin Modul := sqrt(sqr(v[1])+sqr(v[2])+sqr(v[3])) end;
{---------------------------------------------------------------}
function  IsNul(v: TVector): boolean; { v = 0 }
begin IsNul := (v[1] = 0) and (v[2] = 0) and (v[3] = 0) end;
{---------------------------------------------------------------}
function r(g:real):real; begin r:=g/Radian; end;
function g(r:real):real; begin g:=r*Radian; end;
{---------------------------------------------------------------}
end.