{$mode objfpc}
unit dvector2i;

interface

uses
  dtypes,
  dmath;

type
PVec2i = ^TVec2i;
TVec2i = packed record
case Integer of
  0: (X, Y: Integer);
  1: (Arr: array[0..1] of Integer);
end;

const
  Zero2i: TVec2i = (X: 0; Y: 0);

function Vec2i(X, Y: Integer): TVec2i; inline;
function Add2i(const A, B: TVec2i): TVec2i; inline;
function Sub2i(const A, B: TVec2i): TVec2i; inline;
function Neg2i(const V: TVec2i): TVec2i; inline;
function Mul2i(const A, B: TVec2i): TVec2i; inline;
function Mul2i(const V: TVec2i; F: Integer): TVec2i; inline;
function Div2i(const V: TVec2i; F: Integer): TVec2i; inline;
function Dot2i(const A, B: TVec2i): Integer; inline;
function QLen2i(const V: TVec2i): Integer; inline;
function Len2i(const V: TVec2i): Double; inline;
function QDist2i(const A, B: TVec2i): Integer; inline;
function Dist2i(const A, B: TVec2i): Double; inline;
function Normal2i(const V: TVec2i): TVec2i; inline;
function Normal2i(const A, B: TVec2i): TVec2i; inline;
function Rand2i(L, R: Integer): TVec2i; inline;

operator + (const A, B: TVec2i): TVec2i; inline;
operator - (const A, B: TVec2i): TVec2i; inline;
operator - (const A: TVec2i): TVec2i; inline;
operator * (const A, B: TVec2i): TVec2i; inline;
operator * (F: Integer; const V: TVec2i): TVec2i; inline;

implementation

function Vec2i(X, Y: Integer): TVec2i;
begin
  Result.X := X;
  Result.Y := Y;
end;

function Add2i(const A, B: TVec2i): TVec2i;
begin
  Result.X := A.X + B.X;
  Result.Y := A.Y + B.Y;
end;

function Sub2i(const A, B: TVec2i): TVec2i;
begin
  Result.X := A.X - B.X;
  Result.Y := A.Y - B.Y;
end;

function Neg2i(const V: TVec2i): TVec2i;
begin
  Result.X := - V.X;
  Result.Y := - V.Y;
end;

function Mul2i(const A, B: TVec2i): TVec2i;
begin
  Result.X := A.X * B.X;
  Result.Y := A.Y * B.Y;
end;

function Mul2i(const V: TVec2i; F: Integer): TVec2i;
begin
  Result.X := V.X * F;
  Result.Y := V.Y * F;
end;

function Div2i(const V: TVec2i; F: Integer): TVec2i;
begin
  Result.X := V.X div F;
  Result.Y := V.Y div F;
end;

function Dot2i(const A, B: TVec2i): Integer;
begin
  Result := A.X * B.X + A.Y * B.Y;
end;

function QLen2i(const V: TVec2i): Integer;
begin
  Result := V.X * V.X + V.Y * V.Y;
end;

function Len2i(const V: TVec2i): Double;
begin
  Result := sqrt(V.X * V.X + V.Y * V.Y);
end;

function QDist2i(const A, B: TVec2i): Integer;
begin
  Result := QLen2i(Sub2i(A, B));
end;

function Dist2i(const A, B: TVec2i): Double;
begin
  Result := Len2i(Sub2i(A, B));
end;

function Normal2i(const V: TVec2i): TVec2i;
begin
  Result := Vec2i(- V.Y, V.X);
end;

function Normal2i(const A, B: TVec2i): TVec2i;
begin
  Result := Sub2i(A, B);
  Result := Vec2i(- Result.Y, Result.X);
end;

function Rand2i(L, R: Integer): TVec2i;
begin
  Result.X := Random(R - L + 1) + L;
  Result.Y := Random(R - L + 1) + L;
end;

operator + (const A, B: TVec2i): TVec2i;
begin
  Result := Add2i(A, B);
end;

operator - (const A, B: TVec2i): TVec2i;
begin
  Result := Sub2i(A, B);
end;

operator - (const A: TVec2i): TVec2i;
begin
  Result := Neg2i(A);
end;

operator * (const A, B: TVec2i): TVec2i;
begin
  Result := Mul2i(A, B);
end;

operator * (F: Integer; const V: TVec2i): TVec2i;
begin
  Result := Mul2i(V, F);
end;

end.

