Advanced Mathematics Unit

unit AdvancedMathUnit;

interface

uses
  Math;

const
  {---Math Pre-Calculations---}
  Pi                 = 3.1415926535897932384626433832795;
  Pi_Div_180         = Pi / 180;       {Multiply by this for Convertion to Radians}
  Pi_Div_180_Mul_360 = 360 * Pi / 180; {360 Degrees in Radians}

var
  {--- Trig Lookup Tables ---}
  getSIN,
  getCOS,
  getTAN: Array[-360 .. 360] of Extended;


{Pre-Calculate SIN and COS Tables}
procedure PreCalculate_Trig;

{Advanced Trig Functions}
function GetDistance(X1, Y1, X2, Y2: Extended): Extended;

{Angle of Dest Point in Degrees and Radians}
function GetAngleToDestinationDeg(OriginX, OriginY, DestX, DestY: Extended): Integer;
function GetAngleToDestinationRad(OriginX, OriginY, DestX, DestY: Extended): Extended;

{X/Y 2-D Rotation for Degrees and Radians}
function RotateXDeg(oX, oY: Extended; AngleinDegrees: Integer): Extended;
function RotateXRad(oX, oY, AngleinRadians: Extended): Extended;
function RotateYDeg(oX, oY: Extended; AngleinDegrees: Integer): Extended;
function RotateYRad(oX, oY, AngleinRadians: Extended): Extended;


implementation

{Pre-Calculate SIN, COS & TAN Tables}
procedure PreCalculate_Trig;
var i: Integer;
begin
     // Sine
     for i := Low(getSIN) to High(getSIN) do
         getSIN[i] := sin(i * Pi_Div_180);
     // Cosine
     for i := Low(getCOS) to High(getCOS) do
         getCOS[i] := cos(i * Pi_Div_180);
     // Tangent
     for i := Low(getTAN) to High(getTAN) do
         getTAN[i] := tan(i * Pi_Div_180);
end;


{Get Distance of two Points}
function GetDistance(X1, Y1, X2, Y2: Extended): Extended;
begin
     Result := sqrt((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1));
end;


{Angle of Dest Point in Degrees and Radians}
function GetAngleToDestinationDeg(OriginX, OriginY, DestX, DestY: Extended): Integer;
var XDiff: Extended;
begin
     if (OriginX = DestX) and (OriginY = DestY) then
     begin
          Result := 0;
          Exit;
     end;

     XDiff := DestX - OriginX;
     if (XDiff = 0) then
        XDiff := 0.0001; // XDiff Cannot be Zero!

     if (OriginY > DestY) then
        Result := Round(360 - RadToDeg(ArcCos(XDiff / GetDistance(OriginX, OriginY, DestX, DestY))))
     else
         Result := Round(RadToDeg(ArcCos(XDiff / GetDistance(OriginX, OriginY, DestX, DestY))));
end;
function GetAngleToDestinationRad(OriginX, OriginY, DestX, DestY: Extended): Extended;
var XDiff: Extended;
begin
     if (OriginX = DestX) and (OriginY = DestY) then
     begin
          Result := 0;
          Exit;
     end;

     XDiff := DestX - OriginX;
     if (XDiff = 0) then
        XDiff := 0.0001; // XDiff Cannot be Zero!

     if (OriginY > DestY) then
        Result := Pi_Div_180_Mul_360 - ArcCos(XDiff / GetDistance(OriginX, OriginY, DestX, DestY))
     else
         Result := ArcCos(XDiff / GetDistance(OriginX, OriginY, DestX, DestY));
end;


{X/Y 2-D Rotation for Degrees and Radians}
{X Only}
function RotateXDeg(oX, oY: Extended; AngleinDegrees: Integer): Extended;
begin
     Result := oX * getCOS[AngleinDegrees] - oY * getSIN[AngleinDegrees];
end;
function RotateXRad(oX, oY, AngleinRadians: Extended): Extended;
begin
     Result := oX * cos(AngleinRadians) - oY * sin(AngleinRadians);
end;
{Y Only}
function RotateYDeg(oX, oY: Extended; AngleinDegrees: Integer): Extended;
begin
     Result := oX * getSIN[AngleinDegrees] + oY * getCOS[AngleinDegrees];
end;
function RotateYRad(oX, oY, AngleinRadians: Extended): Extended;
begin
     Result := oX * sin(AngleinRadians) + oY * cos(AngleinRadians);
end;

begin
     PreCalculate_Trig;
end.
Programming - a skill for life!

Part 4 of republished guest tutorial by Jason McMillen