00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _LUXRAYS_VECTOR_H
00023 #define _LUXRAYS_VECTOR_H
00024
00025 #include <cmath>
00026 #include <ostream>
00027 #include <functional>
00028 #include <limits>
00029 #include <algorithm>
00030
00031 #include "luxrays/core/utils.h"
00032
00033 namespace luxrays {
00034
00035 class Point;
00036 class Normal;
00037
00038 class Vector {
00039 public:
00040
00041
00042 Vector(float _x = 0.f, float _y = 0.f, float _z = 0.f) :
00043 x(_x), y(_y), z(_z) {
00044 }
00045 explicit Vector(const Point &p);
00046
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;
00053 y += v.y;
00054 z += v.z;
00055 return *this;
00056 }
00057
00058 Vector operator-(const Vector &v) const {
00059 return Vector(x - v.x, y - v.y, z - v.z);
00060 }
00061
00062 Vector & operator-=(const Vector &v) {
00063 x -= v.x;
00064 y -= v.y;
00065 z -= v.z;
00066 return *this;
00067 }
00068
00069 bool operator==(const Vector &v) const {
00070 return x == v.x && y == v.y && z == v.z;
00071 }
00072
00073 Vector operator*(float f) const {
00074 return Vector(f*x, f*y, f * z);
00075 }
00076
00077 Vector & operator*=(float f) {
00078 x *= f;
00079 y *= f;
00080 z *= f;
00081 return *this;
00082 }
00083
00084 Vector operator/(float f) const {
00085 float inv = 1.f / f;
00086 return Vector(x * inv, y * inv, z * inv);
00087 }
00088
00089 Vector & operator/=(float f) {
00090 float inv = 1.f / f;
00091 x *= inv;
00092 y *= inv;
00093 z *= inv;
00094 return *this;
00095 }
00096
00097 Vector operator-() const {
00098 return Vector(-x, -y, -z);
00099 }
00100
00101 float operator[](int i) const {
00102 return (&x)[i];
00103 }
00104
00105 float &operator[](int i) {
00106 return (&x)[i];
00107 }
00108
00109 float LengthSquared() const {
00110 return x * x + y * y + z*z;
00111 }
00112
00113 float Length() const {
00114 return sqrtf(LengthSquared());
00115 }
00116 explicit Vector(const Normal &n);
00117
00118
00119 float x, y, z;
00120 };
00121
00122 inline std::ostream &operator<<(std::ostream &os, const Vector &v) {
00123 os << "Vector[" << v.x << ", " << v.y << ", " << v.z << "]";
00124 return os;
00125 }
00126
00127 inline Vector operator*(float f, const Vector &v) {
00128 return v*f;
00129 }
00130
00131 inline float Dot(const Vector &v1, const Vector &v2) {
00132 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
00133 }
00134
00135 inline float AbsDot(const Vector &v1, const Vector &v2) {
00136 return fabsf(Dot(v1, v2));
00137 }
00138
00139 inline Vector Cross(const Vector &v1, const Vector &v2) {
00140 return Vector((v1.y * v2.z) - (v1.z * v2.y),
00141 (v1.z * v2.x) - (v1.x * v2.z),
00142 (v1.x * v2.y) - (v1.y * v2.x));
00143 }
00144
00145 inline Vector Normalize(const Vector &v) {
00146 return v / v.Length();
00147 }
00148
00149 inline void CoordinateSystem(const Vector &v1, Vector *v2, Vector *v3) {
00150 if (fabsf(v1.x) > fabsf(v1.y)) {
00151 float invLen = 1.f / sqrtf(v1.x * v1.x + v1.z * v1.z);
00152 *v2 = Vector(-v1.z * invLen, 0.f, v1.x * invLen);
00153 } else {
00154 float invLen = 1.f / sqrtf(v1.y * v1.y + v1.z * v1.z);
00155 *v2 = Vector(0.f, v1.z * invLen, -v1.y * invLen);
00156 }
00157 *v3 = Cross(v1, *v2);
00158 }
00159
00160 inline Vector SphericalDirection(float sintheta, float costheta, float phi) {
00161 return Vector(sintheta * cosf(phi), sintheta * sinf(phi), costheta);
00162 }
00163
00164 inline Vector SphericalDirection(float sintheta, float costheta, float phi,
00165 const Vector &x, const Vector &y, const Vector &z) {
00166 return sintheta * cosf(phi) * x + sintheta * sinf(phi) * y +
00167 costheta * z;
00168 }
00169
00170 inline float SphericalTheta(const Vector &v) {
00171 return acosf(Clamp(v.z, -1.f, 1.f));
00172 }
00173
00174 inline float SphericalPhi(const Vector &v) {
00175 float p = atan2f(v.y, v.x);
00176 return (p < 0.f) ? p + 2.f * M_PI : p;
00177 }
00178
00179 inline float CosTheta(const Vector &w) {
00180 return w.z;
00181 }
00182
00183 inline float SinTheta(const Vector &w) {
00184 return sqrtf(Max(0.f, 1.f - w.z * w.z));
00185 }
00186
00187 inline float SinTheta2(const Vector &w) {
00188 return 1.f - CosTheta(w) * CosTheta(w);
00189 }
00190
00191 inline float CosPhi(const Vector &w) {
00192 return w.x / SinTheta(w);
00193 }
00194
00195 inline float SinPhi(const Vector &w) {
00196 return w.y / SinTheta(w);
00197 }
00198
00199 inline bool SameHemisphere(const Vector &w,
00200 const Vector &wp) {
00201 return w.z * wp.z > 0.f;
00202 }
00203
00204 }
00205
00206 #endif