I plan to try and get back into 3D programming with OpenGL. As such I would like to create a simple OpenGL framework for games, based in part on things I read in the OpenGL Game programming book a few years ago. So over the next few days, I plan to post various classes that I plan to use in the future and that will become part of JEDI-SDL, so most will have an SDL slant.

My hope is that with everyone's input we can create a set of classes that are clean, documented and that everyone will find usefull and easy to use, not just me. So I'm looking for comments about what is wrong, what could be done better, what is useless.

Here is my first Vector class...
[pascal]
unit vector;

interface

type
TScalar = single;

TVector = class( TObject )
public
x : TScalar;
y : TScalar;
z : TScalar; // x,y,z coordinates

constructor Create( a : TScalar = 0; b : TScalar = 0; c : TScalar = 0 ); overload;
constructor Create( const vec : TVector ); overload;


// vector assignment
function Assign( const vec : TVector ) : TVector;

// vector equality
function IsEqual( const vec : TVector ) : Boolean;

// vector inequality
function IsNotEqual( const vec : TVector ) : Boolean;

// vector add
function Add( const vec : TVector ) : TVector;

// vector Increment
function Inc( const vec : TVector ) : TVector;

// vector subtraction
function Subtract( const vec : TVector ) : TVector;

// vector Decrement
function Dec( const vec : TVector ) : TVector;

// vector negation
function Negative : TVector;

// vector Positivisation
function Positive : TVector;

// Scale
function Scale( s : TScalar ) : TVector;

// Multiply
function Multiply( vec : TVector ) : TVector;

// Divide
function Divide( vec : TVector ) : TVector;

// cross product
function CrossProduct( const vec : TVector ) : TVector;

// dot product
function DotProduct( const vec : TVector ) : TScalar;


// Interpolate
function Interpolate( const vec : TVector; Amount : TScalar ) : TVector;

// length of vector
function Length : TScalar;

// Set the length of vector
function SetLength( LengthLimit : TScalar ) : TVector;

// return the unit vector
function UnitVector : TVector;

// normalize this vector
procedure Normalize;

// return angle between two vectors
function Angle( const vec : TVector ) : TScalar;

// reflect this vector off surface with normal vector
function Reflection( const normal : TVector ) : TVector;
end;

implementation

function TVector.Assign( const vec : TVector ) : TVector;
begin
x := vec.x;
y := vec.y;
z := vec.z;

result := self;
end;

constructor TVector.Create( a : TScalar = 0; b : TScalar = 0; c : TScalar = 0 );
begin
x := a;
y := b;
z := c;
end;

constructor TVector.Create( const vec : TVector );
begin
x := vec.x;
y := vec.y;
z := vec.z;
end;

function TVector.IsEqual( const vec : TVector ) : Boolean;
begin
result := ( ( x = vec.x ) and ( y = vec.y ) and ( z = vec.z ) );
end;

function TVector.IsNotEqual( const vec : TVector ) : Boolean;
begin
result := not IsEqual( vec );
end;

function TVector.Add( const vec : TVector ) : TVector;
begin
result := TVector.Create( x + vec.x, y + vec.y, z + vec.z );
end;

function TVector.Subtract( const vec : TVector ) : TVector;
begin
result := TVector.Create( x - vec.x, y - vec.y, z - vec.z );
end;

function TVector.Negative : TVector;
begin
result := TVector.Create( -x, -y, -z );
end;

function TVector.Scale( s : TScalar ) : TVector;
begin
x := x * s;
y := y * s;
z := z * s;

result := self;
end;

function TVector.Multiply( vec : TVector ) : TVector;
begin
x := x * vec.x;
y := y * vec.y;
z := z * vec.z;

result := self;
end;

function TVector.CrossProduct( const vec : TVector ) : TVector;
begin
result := TVector.Create( y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x );
end;

function TVector.DotProduct( const vec : TVector ) : TScalar;
begin
result := x * vec.x + y * vec.y + z * vec.z;
end;

function TVector.Interpolate( const vec : TVector; Amount : TScalar ) : TVector;
begin
X := X + ( vec.X - X ) * Amount;
Y := Y + ( vec.Y - Y ) * Amount;
Z := Z + ( vec.Z - Z ) * Amount;
result := self;
end;

function TVector.Length : TScalar;
begin
result := sqrt( ( x * x + y * y + z * z ) );
end;

function TVector.UnitVector : TVector;
begin
x := x / Length;
y := y / Length;
z := z / Length;

result := self;
end;

procedure TVector.Normalize;
var
ScaleValue, Len : Single;
begin
Len := Length;
if Len = 0.0 then
Exit;

ScaleValue := 1.0 / Len;

Scale( ScaleValue );
end;

function TVector.Angle( const vec : TVector ) : TScalar;
begin
result := VectArcCos( self.DotProduct( vec ) );
end;

function TVector.Reflection( const normal : TVector ) : TVector;
var
vec : TVector;
begin
vec := TVector.Create( self.SetLength( 1 ) ); // normalize this vector
result := vec.Subtract( normal.Scale( 2.0 * ( vec.DotProduct( normal ) ) ) ).Scale( Length );
end;

function TVector.Divide( vec : TVector ) : TVector;
begin
x := x / vec.x;
y := y / vec.y;
z := z / vec.z;

result := self;
end;

function TVector.Positive : TVector;
begin
result := TVector.Create( +x, +y, +z );
end;

function TVector.SetLength( LengthLimit : TScalar ) : TVector;
begin
result := Scale( LengthLimit / Length );
end;

function TVector.Dec( const vec : TVector ) : TVector;
begin
x := x - vec.x;
y := y - vec.y;
z := z - vec.z;

result := self;
end;

function TVector.Inc( const vec : TVector ) : TVector;
begin
x := x + vec.x;
y := y + vec.y;
z := z + vec.z;

result := self;
end;
[/pascal]