/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg math*/
/**
* class for a 3D vertex
*
* #include "cVertex.hh"
*
* This class provides a 3D vertex and several operations on it.
* (e.g. adding, scaling, dot product)
*
* @see cMatrix
* @see cQuaternion
*/
#ifndef cVertex_hh
#define cVertex_hh
// PROJECT INCLUDES
#include "common.hh"
/**
* A class for easy matrix math.
*
* Always remember: This class might be used a lot and during time-critical
* operations. Thus, it's optimized for speed, which has the
* consequence that it cannot be derived from this class.
*/
class cVertex
{
public:
// LIFECYCLE
/**
* default constructor (initializes to zero)
*/
cVertex ()
{
ENTER_METHOD("cVertex::cVertex()");
SetZero ();
};
// copy construktor is provided by compiler
/**
* constructor accepting a vertex split into it's components
* @param vx n.x component
* @param vy n.y component
* @param vz n.z component
*/
cVertex (GLfloat vx, GLfloat vy, GLfloat vz)
{
ENTER_METHOD("cVertex::cVertex (vx,vy,vz)");
n.x = vx; n.y = vy; n.z = vz;
} ;
// destructor is provided by compiler
#if DEBUG
/**
* destructor (for debugging purposes only)
*/
~cVertex ()
{
ENTER_METHOD("cVertex::~cVertex()");
}
#endif
// OPERATORS
/**
* operator for scaling by a given value
* @param s scale factor
*/
inline cVertex &operator *= (const GLfloat s)
{
n.x *= s; n.y *= s; n.z *= s;
return *this;
};
/**
* operator for adding two cVertex objects
* @param v cVertex to add
*/
inline cVertex &operator += (const cVertex &v)
{
n.x += v.n.x; n.y += v.n.y; n.z += v.n.z;
return *this;
};
/**
* operator for subtracting two cVertex objects
* @param v cVertex to subtract
*/
inline cVertex &operator -= (const cVertex &v)
{
n.x -= v.n.x; n.y -= v.n.y; n.z -= v.n.z;
return *this;
};
/**
* operator for multiplying any cVertex with a scalar
* @param s value to scale by
*/
inline cVertex operator * (const GLfloat s) const
{
return cVertex (s*n.x, s*n.y, s*n.z);
};
/**
* operator to add two cVertex objects
* @param v cVertex object to add
*/
inline cVertex operator + (const cVertex &v) const
{
return cVertex(n.x+v.n.x, n.y+v.n.y, n.z+v.n.z);
};
/**
* operator for subtracting two cVertex objects
* @param v cVertex object to substract
*/
inline cVertex operator - (const cVertex &v) const
{
return cVertex(n.x-v.n.x, n.y-v.n.y, n.z-v.n.z);
};
/**
* operator to multiply two cVertex objects (dot product)
* @param v cVertex to calculate dot product with
*
* @return dot product of the two cVertex's
*/
inline GLfloat operator * (const cVertex &v) const // dot product
{
return (n.x*v.n.x + n.y*v.n.y + n.z*v.n.z);
}
/**
* operator to retrieve a component of an cVertex by index
* @param idx index of value (0 = x, 1 = y, 2 = z)
*/
inline GLfloat &operator[] (const int idx)
{
return a[idx];
}
/**
* converting to GLfloat *
*/
inline operator GLfloat *()
{
return (GLfloat *)&a;
}
// OPERATIONS
/**
* assign a new value to all three components (it's basically
* superfluous)
* @param vx n.x component
* @param vy n.y component
* @param vz n.z component
*/
inline cVertex Assign (GLfloat vx, GLfloat vy, GLfloat vz)
{
n.x = vx; n.y = vy; n.z = vz;
return *this;
};
/**
* normalize the vertex (make it length 1)
* @return reference to normalized cVertex
*/
inline cVertex &Normalize ()
{
const GLfloat l = GetLength ();
if (l == 0) return *this; // it's zero anyway, so don't touch it
// first calc 1/l
const GLfloat one_by_l = 1.0/l;
// then multiply (should actually save some cycles)
(*this) *= one_by_l;
return *this;
};
/**
* convenience function: translate by given vertex
* @param tx n.x component
* @param ty n.y component
* @param tz n.z component
*/
inline void Translate (GLfloat tx, GLfloat ty, GLfloat tz)
{
n.x += tx; n.y += ty; n.z += tz;
};
/**
* invert direction of vector by inverting all its components
* @returns reference to inverted cVertex
*/
inline cVertex &Invert ()
{
n.x = -n.x; n.y = -n.y; n.z = -n.z;
return *this;
}
/**
* calculate cross product of two given vertices
* @param v1 first vertex
* @param v2 second vertex
*
* @returns cVertex object
*/
inline cVertex CrossProd (const cVertex &v1, const cVertex &v2) const
{
return cVertex (v1.n.y*v2.n.z - v1.n.z*v2.n.y,
v1.n.z*v2.n.x - v1.n.x*v2.n.z,
v1.n.x*v2.n.y - v1.n.y*v2.n.x);
}
/**
* calculate cross product (does not change class)
* @param v vector to calculate cross product with
*
* @returns a cVertex object
*/
inline cVertex CrossProd (const cVertex &v) const
{
return cVertex (n.y*v.n.z - n.z*v.n.y,
n.z*v.n.x - n.x*v.n.z,
n.x*v.n.y - n.y*v.n.x);
}
// ACCESS
/**
* set vertex to zero vector
*/
inline void SetZero () { n.x = n.y = n.z = 0; };
/**
* query current x component of vector
* @returns GLfloat - value of x component
*/
inline GLfloat GetX () const {
return n.x;
}
/**
* query current y component of vector
* @returns GLfloat - value of y component
*/
inline GLfloat GetY () const {
return n.y;
}
/**
* query current z component of vector
* @returns GLfloat - value of z component
*/
inline GLfloat GetZ () const {
return n.z;
}
/**
* determine length of vertex
* @returns length of vertex
*/
inline GLfloat GetLength () const
{
return sqrt (n.x*n.x + n.y*n.y + n.z*n.z);
};
private:
// I was tempted to make this public but I decided against it for the
// sake of a cleander design. Sigh.
/**
* Anonymous union used to store the vector components.
* By using this union, we're able to access the vector by
* component names or component indices.*/
union {
struct {
GLfloat x, y, z;
} n;
GLfloat a[3];
};
};
#endif // ifndef cVertex_hh
/* vim:ts=4:smartindent:
*/
|