00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_VECTOR_H
00024 #define LUX_VECTOR_H
00025
00026 #include "lux.h"
00027 #include <cmath>
00028 #include <iostream>
00029 using std::ostream;
00030 #include <boost/serialization/access.hpp>
00031
00032
00033 namespace lux
00034 {
00035
00036 class Point;
00037 class Normal;
00038
00039 class Vector {
00040 friend class boost::serialization::access;
00041 public:
00042
00043 Vector(float _x=0, float _y=0, float _z=0)
00044 : x(_x), y(_y), z(_z) {
00045 }
00046 explicit Vector(const Point &p);
00047 Vector operator+(const Vector &v) const {
00048 return Vector(x + v.x, y + v.y, z + v.z);
00049 }
00050
00051 Vector& operator+=(const Vector &v) {
00052 x += v.x; y += v.y; z += v.z;
00053 return *this;
00054 }
00055 Vector operator-(const Vector &v) const {
00056 return Vector(x - v.x, y - v.y, z - v.z);
00057 }
00058
00059 Vector& operator-=(const Vector &v) {
00060 x -= v.x; y -= v.y; z -= v.z;
00061 return *this;
00062 }
00063 bool operator==(const Vector &v) const {
00064 return x == v.x && y == v.y && z == v.z;
00065 }
00066 Vector operator*(float f) const {
00067 return Vector(f*x, f*y, f*z);
00068 }
00069
00070 Vector &operator*=(float f) {
00071 x *= f; y *= f; z *= f;
00072 return *this;
00073 }
00074 Vector operator/(float f) const {
00075
00076 float inv = 1.f / f;
00077 return Vector(x * inv, y * inv, z * inv);
00078 }
00079
00080 Vector &operator/=(float f) {
00081
00082 float inv = 1.f / f;
00083 x *= inv; y *= inv; z *= inv;
00084 return *this;
00085 }
00086 Vector operator-() const {
00087 return Vector(-x, -y, -z);
00088 }
00089 float operator[](int i) const {
00090
00091 return (&x)[i];
00092 }
00093
00094 float &operator[](int i) {
00095
00096 return (&x)[i];
00097 }
00098 float LengthSquared() const { return x*x + y*y + z*z; }
00099 float Length() const { return sqrtf(LengthSquared()); }
00100 explicit Vector(const Normal &n);
00101
00102 float x, y, z;
00103
00104 private:
00105 template<class Archive>
00106 void serialize(Archive & ar, const unsigned int version)
00107 {
00108 ar & x;
00109 ar & y;
00110 ar & z;
00111 }
00112 };
00113
00114 inline ostream &operator<<(ostream &os, const Vector &v) {
00115 os << v.x << ", " << v.y << ", " << v.z;
00116 return os;
00117 }
00118 inline Vector operator*(float f, const Vector &v) {
00119 return v*f;
00120 }
00121
00122 inline float Dot(const Vector &v1, const Vector &v2) {
00123 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
00124 }
00125
00126 inline float AbsDot(const Vector &v1, const Vector &v2) {
00127 return fabsf(Dot(v1, v2));
00128 }
00129
00130 inline Vector Cross(const Vector &v1, const Vector &v2) {
00131 return Vector((v1.y * v2.z) - (v1.z * v2.y),
00132 (v1.z * v2.x) - (v1.x * v2.z),
00133 (v1.x * v2.y) - (v1.y * v2.x));
00134 }
00135
00136 inline Vector Normalize(const Vector &v) {
00137 return v / v.Length();
00138 }
00139
00140 inline void CoordinateSystem(const Vector &v1, Vector *v2, Vector *v3) {
00141 if (fabsf(v1.x) > fabsf(v1.y)) {
00142 float invLen = 1.f / sqrtf(v1.x*v1.x + v1.z*v1.z);
00143 *v2 = Vector(-v1.z * invLen, 0.f, v1.x * invLen);
00144 } else {
00145 float invLen = 1.f / sqrtf(v1.y*v1.y + v1.z*v1.z);
00146 *v2 = Vector(0.f, v1.z * invLen, -v1.y * invLen);
00147 }
00148 *v3 = Cross(v1, *v2);
00149 }
00150
00151 inline Vector SphericalDirection(float sintheta, float costheta, float phi) {
00152 return Vector(sintheta * cosf(phi), sintheta * sinf(phi), costheta);
00153 }
00154
00155 inline Vector SphericalDirection(float sintheta, float costheta, float phi,
00156 const Vector &x, const Vector &y, const Vector &z) {
00157 return sintheta * cosf(phi) * x + sintheta * sinf(phi) * y +
00158 costheta * z;
00159 }
00160
00161 inline float SphericalTheta(const Vector &v) {
00162 return acosf(Clamp(v.z, -1.f, 1.f));
00163 }
00164
00165 inline float SphericalPhi(const Vector &v) {
00166 float p = atan2f(v.y, v.x);
00167 return (p < 0.f) ? p + 2.f*M_PI : p;
00168 }
00169
00170 }
00171
00172 #ifdef LUX_NORMAL_H
00173 #include "vector_normal.h"
00174 #endif
00175
00176 #endif //LUX_VECTOR_H