{*******************************************************}
{ }
{ Vector Object Library }
{ }
{ Copyright (c) 2004 Noeska }
{ }
{*******************************************************}
unit glVector;
interface
uses classes, windows;
type
TRandomFunc = (rNegoneToOne, rZeroToOne); // (-1..1) (0..1)
TVector3D = class(TObject)
private
Fx: single;
Fy: single;
Fz: single;
function GetNormalized: TVector3d; //same as above but return a new vector
function GetLength: single; //returns the length of a vector
protected
public
constructor Create; reintroduce; overload;
constructor Create(vx,vy,vz: single); reintroduce; overload;
destructor Destroy; reintroduce;
property x: single read Fx write Fx;
property y: single read Fy write Fy;
property z: single read Fz write Fz;
procedure Assign(v: TVector3D); reintroduce; //set x,y,z from other vector
procedure Add(v: TVector3D); //Addition
procedure Sub(v: TVector3D); //Subtraction
procedure Mul(value: single); //Scale by Multiplication
procedure Divide(value: single); //Scale by Division
function Dot(v: TVector3D): single; //Dot product (angle between 2 vectors)
function Cross(v: TVector3D): TVector3D; //Cross product (perpendicular vector)
procedure Negative; //flips positive and negative
procedure Normalize; //make the vector have a length of 1 but keep direction
property Normalized: TVector3D read GetNormalized; //as above but returns a new vector
property Length: single read GetLength; //length of vector
property Magnitude: single read GetLength; //length of vector
procedure Rand(value: TRandomFunc); //fills vector with random values
end;
implementation
constructor TVector3D.Create;
begin
inherited Create();
Fx:=0.0;
Fy:=0.0;
Fz:=0.0;
end;
constructor TVector3D.Create(vx,vy,vz: single);
begin
inherited Create();
Fx:=vx;
Fy:=vy;
Fz:=vz;
end;
destructor TVector3D.Destroy;
begin
if normalized <> nil then normalized.free; //free's the normalized property if not done from application
inherited Destroy();
end;
procedure TVector3D.Assign(v: TVector3D);
begin
Fx:=v.x;
Fy:=v.y;
Fz:=v.z;
end;
procedure TVector3D.Add(v: TVector3D);
begin
Fx:=Fx+v.x;
Fy:=Fy+v.y;
Fz:=Fz+v.z;
end;
procedure TVector3D.Sub(v: TVector3D);
begin
Fx:=Fx-v.x;
Fy:=Fy-v.y;
Fz:=Fz-v.z;
end;
procedure TVector3D.Mul(value: single);
begin
Fx:=Fx*value;
Fy:=Fy*value;
Fz:=Fz*value;
end;
procedure TVector3D.Divide(value: single);
begin
Fx:=Fx/value;
Fy:=Fy/value;
Fz:=Fz/value;
end;
function TVector3D.Dot(v: TVector3D): single;
begin
result:= Fx*v.x+Fy*v.y+Fz*v.z;
end;
function TVector3D.Cross(v: TVector3D): TVector3D;
begin
result:= TVector3D.Create();
result.x:= Fy*v.z-Fz*v.y;
result.y:= Fz*v.x-Fx*v.z;
result.z:= Fx*v.y-Fy*v.x;
end;
procedure TVector3D.Negative;
begin
Fx:=-Fx;
Fy:=-Fy;
Fz:=-Fz;
end;
function TVector3D.GetLength: single;
begin
result := sqrt(Fx*Fx + Fy*Fy + Fz*Fz);
end;
procedure TVector3d.normalize;
var
tmplength: single;
begin
tmplength:=GetLength;
if tmplength <> 0 then
begin
Fx:=Fx / tmplength;
Fy:=Fy / tmplength;
Fz:=Fz / tmplength;
end;
end;
function TVector3d.GetNormalized;
var
tmplength: single;
begin
result:=nil;
tmplength:=Length;
if tmplength <> 0 then
begin
if normalized <> nil then normalized.free; //free's the normalized property if not done from application
result:=TVector3d.Create();
result.x:=Fx / tmplength;
result.y:=Fy / tmplength;
result.z:=Fz / tmplength;
end;
end;
function RandNegOneToOne: single;
begin
result := -1.0+(random / 16383.0);
end;
function RandZeroToOne: single;
begin
result := (random / 32767.0);
end;
procedure TVector3d.Rand(value: TRandomFunc);
begin
if value=rNegOneToOne then
begin
Fx:=RandNegOneToOne;
Fy:=RandNegOneToOne;
Fz:=RandNegOneToOne;
Normalize;
end;
if value=rZeroToOne then
begin
Fx:=RandZeroToOne;
Fy:=RandZeroToOne;
Fz:=RandZeroToOne;
Normalize;
end;
end;
end.