It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Miguel Gomez
Gamasutra
July 2, 1999

Letters to the Editor:
Write a letter
View all letters


Features

The VECTOR type

Contents

Introduction

The Vector type

The MATRIX type

The BASIS type

The COORDINATE FRAME type

The RIGID_BODY STATE type

Bibliography

A vector is an ordered set of numbers that represents a magnitude and a direction. Vectors can be added, subtracted, multiplied and divided by scalars, and have special operations such as the dot and cross product. They are used to represent almost every non-scalar quantity in physics and math: velocity, acceleration, surface normal, unit direction, etc. Since most of the physics in games is only in three dimensions, the VECTOR type has only x, y and z components. All basic vector operations are implemented as overloaded operators or inline member functions. The VECTOR type will also be the building block for the MATRIX class.

In Listing 1, notice that the members of VECTOR are public. Object-oriented purists may freak out, but having the ability to directly access the components of the vector makes math and physics programming much easier in the long run. Also, you might notice the const keyword permeates the member functions. The const in front of the return type means that the return value cannot be assigned. The const in front of the arguments means that the arguments are not changed within the function. The const after the argument list means that none of the members of the calling object are changed within that function. In my opinion, const should be used liberally since it will generate a compile error on a statement like:

if( (a + b) = c )

{

printf( "Typos are easy to overlook.\n" );

}

Points have pretty much the same operations as vectors, so they are simply typedef’ed as a VECTOR (see Listing 1).

Listing 1.

#include <cmath>

// A floating point number

//

typedef float SCALAR;

 

//

// A 3D vector

//

class VECTOR

{

public:

SCALAR x,y,z; //x,y,z coordinates

public:

VECTOR()

: x(0), y(0), z(0)

{}

VECTOR( const SCALAR& a, const SCALAR& b, const SCALAR& c )

: x(a), y(b), z(c)

{}

//index a component

//NOTE: returning a reference allows

//you to assign the indexed element

SCALAR& operator [] ( const long i )

{

return *((&x) + i);

}

//compare

const bool operator == ( const VECTOR& v ) const

{

return (v.x==x && v.y==y && v.z==z);

}

const bool operator != ( const VECTOR& v ) const

{

return !(v == *this);

}

//negate

const VECTOR operator - () const

{

return VECTOR( -x, -y, -z );

}

//assign

const VECTOR& operator = ( const VECTOR& v )

{

x = v.x;

y = v.y;

z = v.z;

return *this;

}

//increment

const VECTOR& operator += ( const VECTOR& v )

{

x+=v.x;

y+=v.y;

z+=v.z;

return *this;

}

//decrement

const VECTOR& operator -= ( const VECTOR& v )

{

x-=v.x;

y-=v.y;

z-=v.z;

return *this;

}

//self-multiply

const VECTOR& operator *= ( const SCALAR& s )

{

x*=s;

y*=s;

z*=s;

return *this;

}

//self-divide

const VECTOR& operator /= ( const SCALAR& s )

{

const SCALAR r = 1 / s;

x *= r;

y *= r;

z *= r;

return *this;

}

//add

const VECTOR operator + ( const VECTOR& v ) const

{

return VECTOR(x + v.x, y + v.y, z + v.z);

}

//subtract

const VECTOR operator - ( const VECTOR& v ) const

{

return VECTOR(x - v.x, y - v.y, z - v.z);

}

//post-multiply by a scalar

const VECTOR operator * ( const SCALAR& s ) const

{

return VECTOR( x*s, y*s, z*s );

}

//pre-multiply by a scalar

friend inline const VECTOR operator * ( const SCALAR& s, const VECTOR& v )

{

return v * s;

}

//divide

const VECTOR operator / (SCALAR s) const

{

s = 1/s;

return VECTOR( s*x, s*y, s*z );

}

//cross product

const VECTOR cross( const VECTOR& v ) const

{

//Davis, Snider, "Introduction to Vector Analysis", p. 44

return VECTOR( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x );

}

//scalar dot product

const SCALAR dot( const VECTOR& v ) const

{

return x*v.x + y*v.y + z*v.z;

}

//length

const SCALAR length() const

{

return (SCALAR)sqrt( (double)this->dot(*this) );

}

//unit vector

const VECTOR unit() const

{

return (*this) / length();

}

//make this a unit vector

void normalize()

{

(*this) /= length();

}

//equal within an error ‘e’

const bool nearlyEquals( const VECTOR& v, const SCALAR e ) const

{

return fabs(x-v.x)<e && fabs(y-v.y)<e && fabs(z-v.z)<e;

}

};

//

// A 3D position

//

typedef VECTOR POINT;


The MATRIX type


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service