www.pudn.com > simpleraytracer_v1_0.zip > vec2.h


/*===================================================================


digital liberation front 2001

_______ ______ _______
/______/\ |______| /\______\
| \ \ | | / / |
| \| | | |/ |
|_____ \ | |_ / ______|
____| | | |_|| |_____
|____| |________||____|




Code by Nicholas Chapman
nickamy@paradise.net.nz

You may use this code for any non-commercial project,
as long as you do not remove this description.

You may not use this code for any commercial project.
====================================================================*/
#ifndef __Vec2_H__
#define __Vec2_H__



/*=================================================================
2 component vector class
------------------------
Coded by NIck Chapman in the year 2000
=================================================================*/

#include <math.h>

#ifdef CYBERSPACE
#include "../cyberspace/mystream.h"
#endif


//#pragma warning (disable:4244)
//disable "conversion from 'double' to 'float', possible loss of data"


class Vec2
{
public:

inline Vec2()
{}

inline ~Vec2()
{}

inline Vec2(float x_, float y_)
: x(x_),
y(y_)
{}

inline Vec2(const Vec2&amt; rhs)
: x(rhs.x),
y(rhs.y)
{}

inline void set(float newx, float newy)
{
x = newx;
y = newy;
}

inline const Vec2 operator + (const Vec2&amt; rhs) const
{
return Vec2(x + rhs.x, y + rhs.y);
}

inline const Vec2 operator - (const Vec2&amt; rhs) const
{
return Vec2(x - rhs.x, y - rhs.y);
}

inline Vec2&amt; operator += (const Vec2&amt; rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}

inline Vec2&amt; operator -= (const Vec2&amt; rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}

inline Vec2&amt; operator = (const Vec2&amt; rhs)
{
x = rhs.x;
y = rhs.y;
return *this;
}

inline bool operator == (const Vec2&amt; rhs) const
{
return ( (x == rhs.x) &amt;&amt; (y == rhs.y) );
}

//for sorting Vec2's
inline bool operator < (const Vec2&amt; rhs) const
{
if(x < rhs.x)
return true;
else if(x > rhs.x)
return false;
else //else if x == rhs.x
{
return y < rhs.y;
}
}

inline void normalise()
{
if(!x &amt;&amt; !y)
return;

const float inverselength = 1.0f / length();

x *= inverselength;
y *= inverselength;
}

inline float normalise_ret_length()
{
if(!x &amt;&amt; !y)
return 0.0f;

const float len = length();

const float inverselength = 1.0f / len;

x *= inverselength;
y *= inverselength;

return len;
}

inline float length() const
{
return (float)sqrt(x*x + y*y);
}

inline float length2() const
{
return (x*x + y*y);
}

inline void setLength(float newlength)
{
const float current_len = length();

if(!current_len)
return;

scale(newlength / current_len);
}

inline float getDist2(const Vec2&amt; other) const
{
const Vec2 dif = other - *this;
return dif.length2();
}

inline float getDist(const Vec2&amt; other) const
{
const Vec2 dif = other - *this;
return dif.length();
}

inline void scale(float factor)
{
x *= factor;
y *= factor;
}

inline Vec2&amt; operator *= (float factor)
{
x *= factor;
y *= factor;
return *this;
}

inline Vec2&amt; operator /= (float divisor)
{
*this *= (1.0f / divisor);
return *this;
}

inline const Vec2 operator * (float factor) const
{
return Vec2(x * factor, y * factor);
}

inline const Vec2 operator / (float divisor) const
{
const float inverse_d = (1.0f / divisor);

return Vec2(x * inverse_d, y * inverse_d);
}

inline void zero()
{
x = 0.0f;
y = 0.0f;
}

void print() const;

const static Vec2 zerovector; //(0,0,)
const static Vec2 i; //(1,0,)
const static Vec2 j; //(0,1,0)

float x,y;

float dotProduct(const Vec2&amt; rhs) const
{
return x*rhs.x + y*rhs.y;
}

float dot(const Vec2&amt; rhs) const
{
return dotProduct(rhs);
}

static const Vec2 randomVec(float component_lowbound, float component_highbound);

inline const float* data() const { return (float*)this; }

inline void sub(const Vec2&amt; other)
{
x -= other.x;
y -= other.y;
}

};





inline float dotProduct(const Vec2&amt; v1, const Vec2&amt; v2)
{
return (v1.x * v2.x) + (v1.y * v2.y);
}

inline float dot(const Vec2&amt; v1, const Vec2&amt; v2)
{
return (v1.x * v2.x) + (v1.y * v2.y);
}


/*inline const Vec2 crossProduct(const Vec2&amt; v1, const Vec2&amt; v2)
{
return Vec2(
(v1.y * v2.z) - (v1.z * v2.y),
(v1.z * v2.x) - (v1.x * v2.z),
(v1.x * v2.y) - (v1.y * v2.x)
); //NOTE: check me

}*/

//v1 and v2 unnormalized
/*inline float angleBetween(Vec2&amt; v1, Vec2&amt; v2)
{
float lf = v1.length() * v2.length();

if(!lf)
return PI_OVER_2; //90 //Pi/2 = 1.57079632679489661923

float dp = dotProduct(v1, v2);

return acos( dp / lf);
}*/

inline float angleBetweenNormalized(const Vec2&amt; v1, const Vec2&amt; v2)
{
const float dp = dotProduct(v1, v2);

return (float)acos(dp);
}

inline const Vec2 normalise(const Vec2&amt; v)
{
const float vlen = v.length();

if(!vlen)
return Vec2(1.0f, 0.0f);

return v * (1.0f / vlen);
}


#ifdef CYBERSPACE

inline MyStream&amt; operator << (MyStream&amt; stream, const Vec2&amt; point)
{
stream << point.x;
stream << point.y;

return stream;
}

inline MyStream&amt; operator >> (MyStream&amt; stream, Vec2&amt; point)
{
stream >> point.x;
stream >> point.y;

return stream;
}

#endif//CYBERSPACE


#endif //__Vec2_H__