So is this better??
[pascal]
unit vector;
interface
type
TScalar = single;
TVector = class( TObject )
public
x : TScalar;
y : TScalar;
z : TScalar; // x,y,z coordinates
constructor Create( aX : TScalar = 0; aY : TScalar = 0; aZ : TScalar = 0 ); overload;
constructor Create( const vec : TVector ); overload;
// vector assignment
function Assign( const vec : TVector ) : TVector; overload;
function Assign( aX : TScalar = 0; aY : TScalar = 0; aZ : TScalar = 0 ) : TVector; overload;
// vector equality
function IsEqual( const vec : TVector ) : Boolean;
// vector inequality
function IsNotEqual( const vec : TVector ) : Boolean;
// vector add
procedure Add( const vec : TVector; var aAddedVector : TVector );
// vector Increment
function Inc( const vec : TVector ) : TVector;
// vector subtraction
procedure Subtract( const vec : TVector; var aSubtractedVector : TVector );
// vector Decrement
function Dec( const vec : TVector ) : TVector;
// vector negation
procedure Negative( var aNegativeVector : TVector );
// vector Positivisation
procedure Positive( var aPositiveVector : TVector );
// Scale
function Scale( s : TScalar ) : TVector;
// Multiply
function Multiply( vec : TVector ) : TVector;
// Divide
function Divide( vec : TVector ) : TVector;
// cross product
procedure CrossProduct( const vec : TVector; var aCrossProductedVector : TVector );
// dot product
function DotProduct( const vec : TVector ) : TScalar;
// Interpolate
function Interpolate( const vec : TVector; Amount : TScalar ) : TVector;
// length of vector
function Length : TScalar;
// square of the vector length
function LengthSquare : 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
procedure Reflection( const normal : TVector; var aReflectionVector : TVector );
{
const CVector vec(*this | 1); // normalize this vector
result := (vec - normal * 2.0 * (vec % normal)) * !*this;
}
end;
// Taken from Martin Beaudet's clVecteurs
function VectArcTan2( Y, X : Extended ) : Extended;
function VectArcCos( X : Single ) : Single;
function VectArcSin( X : Single ) : Single;
function RadianToDegrees( Radian : Single ) : Single;
function DegreesToRadian( Degrees : Single ) : Single;
implementation
function TVector.Assign( const vec : TVector ) : TVector;
begin
x := vec.x;
y := vec.y;
z := vec.z;
result := self;
end;
function TVector.Assign(aX, aY, aZ: TScalar): TVector;
begin
x := aX;
y := aY;
z := aZ;
result := self;
end;
constructor TVector.Create( aX : TScalar = 0; aY : TScalar = 0; aZ : TScalar = 0 );
begin
inherited Create;
x := aX;
y := aY;
z := aZ;
end;
constructor TVector.Create( const vec : TVector );
begin
inherited Create;
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;
procedure TVector.Add( const vec : TVector; var aAddedVector : TVector );
begin
if aAddedVector <> nil then
aAddedVector.Assign( x + vec.x, y + vec.y, z + vec.z )
end;
procedure TVector.Subtract( const vec : TVector; var aSubtractedVector : TVector );
begin
if aSubtractedVector <> nil then
aSubtractedVector.Assign( x - vec.x, y - vec.y, z - vec.z );
end;
procedure TVector.Negative( var aNegativeVector : TVector );
begin
if aNegativeVector <> nil then
aNegativeVector.Assign( -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;
procedure TVector.CrossProduct( const vec : TVector; var aCrossProductedVector : TVector );
begin
if aCrossProductedVector <> nil then
aCrossProductedVector.Assign( 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.LengthSquare: TScalar;
begin
result := ( x * x + y * y + z * z );
end;
function TVector.UnitVector : TVector;
var
Len : Single;
begin
// Store the Length
Len := Length;
x := x / Len;
y := y / Len;
z := z / Len;
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;
procedure TVector.Reflection( const normal : TVector; var aReflectionVector : TVector );
begin
if aReflectionVector <> nil then
begin
aReflectionVector.Assign( self );
aReflectionVector.Subtract( normal.Scale( 2.0 * ( aReflectionVector.DotProduct( normal ) ) ), aReflectionVector );
aReflectionVector.Scale( Length );
aReflectionVector.Normalize; // normalize this vector
end;
end;
function TVector.Divide( vec : TVector ) : TVector;
begin
x := x / vec.x;
y := y / vec.y;
z := z / vec.z;
result := self;
end;
procedure TVector.Positive( var aPositiveVector : TVector );
begin
if aPositiveVector <> nil then
aPositiveVector.Assign( +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;
function VectArcTan2( Y, X : Extended ) : Extended;
asm
FLD Y
FLD X
FPATAN
FWAIT
end;
function VectArcCos( X : Single ) : Single;
begin
Result := VectArcTan2( Sqrt( 1 - X * X ), X );
end;
function VectArcSin( X : Single ) : Single;
begin
result := VectArcTan2( X, Sqrt( 1 - X * X ) );
end;
function RadianToDegrees( Radian : Single ) : Single;
begin
result := Radian * ( 180 / PI );
end;
function DegreesToRadian( Degrees : Single ) : Single;
begin
result := Degrees * ( PI / 180 );
end;
end.
[/pascal]
Next on the list is a basic camera class.
Bookmarks