00001 #ifndef _Homogenous_H_
00002 #define _Homogenous_H_
00003
00004 #include "../../include/fv_limits.h"
00005 #include <float.h>
00006 #include <iostream>
00007 #include <cmath>
00008
00009 class Homogenous
00010 {
00011 public:
00012
00013 float x, y, z, w;
00014
00015
00016 Homogenous(): x(0.0), y(0.0), z(0.0), w(1.0) {}
00017
00018
00019 Homogenous(float x, float y, float z = 0.0, float w = 1.0): x(x), y(y), z(z), w(w) {}
00020
00021
00022 Homogenous operator + (const Homogenous &hc) const
00023 {
00024 float x1 = x, y1 = y, z1 = z;
00025 if (w)
00026 {
00027 x1 /= w;
00028 y1 /= w;
00029 z1 /= w;
00030 }
00031
00032 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00033 if (hc.w)
00034 {
00035 x2 /= hc.w;
00036 y2 /= hc.w;
00037 z2 /= hc.w;
00038 }
00039
00040 return Homogenous(x1 + x2, y1 + y2, z1 + z2, (w == 0.0 || hc.w == 0.0) ? 0.0f : 1.0f);
00041 }
00042
00043
00044 Homogenous operator - (const Homogenous &hc) const
00045 {
00046 float x1 = x, y1 = y, z1 = z;
00047 if (w)
00048 {
00049 x1 /= w;
00050 y1 /= w;
00051 z1 /= w;
00052 }
00053
00054 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00055 if (hc.w)
00056 {
00057 x2 /= hc.w;
00058 y2 /= hc.w;
00059 z2 /= hc.w;
00060 }
00061
00062 return Homogenous(x1 - x2, y1 - y2, z1 - z2, (w == 0.0 || hc.w == 0.0) ? 0.0f : 1.0f);
00063 }
00064
00065
00066 float operator * (const Homogenous &hc) const
00067 {
00068 if (w == 0.0 || hc.w == 0.0)
00069 return FLT_MAX;
00070
00071 float x1 = x, y1 = y, z1 = z;
00072 x1 /= w;
00073 y1 /= w;
00074 z1 /= w;
00075
00076 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00077 x2 /= hc.w;
00078 y2 /= hc.w;
00079 z2 /= hc.w;
00080
00081 return x1 * x2 + y1 * y2 + z1 * z2;
00082 }
00083
00084
00085 Homogenous operator % (const Homogenous &hc) const
00086 {
00087 float x1 = x, y1 = y, z1 = z;
00088 if (w)
00089 {
00090 x1 /= w;
00091 y1 /= w;
00092 z1 /= w;
00093 }
00094
00095 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00096 if (hc.w)
00097 {
00098 x2 /= hc.w;
00099 y2 /= hc.w;
00100 z2 /= hc.w;
00101 }
00102
00103 return Homogenous(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2, (w == 0.0 || hc.w == 0.0) ? 0.0f : 1.0f);
00104 }
00105
00106
00107 Homogenous& operator += (const Homogenous &hc)
00108 {
00109 float x1 = x, y1 = y, z1 = z;
00110 if (w)
00111 {
00112 x1 /= w;
00113 y1 /= w;
00114 z1 /= w;
00115 }
00116
00117 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00118 if (hc.w)
00119 {
00120 x2 /= hc.w;
00121 y2 /= hc.w;
00122 z2 /= hc.w;
00123 }
00124
00125 x = x1 + x2;
00126 y = y1 + y2;
00127 z = z1 + z2;
00128 w = (w == 0.0 || hc.w == 0.0) ? 0.0f : 1.0f;
00129
00130 return *this;
00131 }
00132
00133
00134 Homogenous& operator -= (const Homogenous &hc)
00135 {
00136 float x1 = x, y1 = y, z1 = z;
00137 if (w)
00138 {
00139 x1 /= w;
00140 y1 /= w;
00141 z1 /= w;
00142 }
00143
00144 float x2 = hc.x, y2 = hc.y, z2 = hc.z;
00145 if (hc.w)
00146 {
00147 x2 /= hc.w;
00148 y2 /= hc.w;
00149 z2 /= hc.w;
00150 }
00151
00152 x = x1 - x2;
00153 y = y1 - y2;
00154 z = z1 - z2;
00155 w = (w == 0.0 || hc.w == 0.0) ? 0.0f : 1.0f;
00156
00157 return *this;
00158 }
00159
00160
00161 Homogenous& operator *= (float lambda_xyz)
00162 {
00163 x *= lambda_xyz;
00164 y *= lambda_xyz;
00165 z *= lambda_xyz;
00166 return *this;
00167 }
00168
00169
00170 Homogenous& operator /= (float lambda_xyz)
00171 {
00172 x /= lambda_xyz;
00173 y /= lambda_xyz;
00174 z /= lambda_xyz;
00175 return *this;
00176 }
00177
00178
00179 Homogenous& operator %= (const Homogenous &hc)
00180 {
00181 float x1 = x, y1 = y, z1 = z;
00182 x = y1*hc.z - z1*hc.y;
00183 y = z1*hc.x - x1*hc.z;
00184 z = x1*hc.y - y1*hc.x;
00185 return(*this);
00186 }
00187
00188
00189 float Magnitude() const
00190 {
00191 if (w == 0.0)
00192 return FLT_MAX;
00193
00194 float w2 = w * w;
00195 return sqrt((x * x + y * y + z * z) / w2);
00196 }
00197
00198
00199 void Normalize()
00200 {
00201 float length = Magnitude();
00202 x /= length;
00203 y /= length;
00204 z /= length;
00205 }
00206 };
00207
00208
00209 inline Homogenous operator * (float lhs, const Homogenous &rhs)
00210 {
00211 return Homogenous(lhs*rhs.x, lhs*rhs.y, lhs*rhs.z, lhs*rhs.w);
00212 }
00213
00214
00215 inline Homogenous operator * (const Homogenous &lhs, float rhs)
00216 {
00217 return Homogenous(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs, lhs.w*rhs);
00218 }
00219
00220
00221 inline std::ostream& operator << (std::ostream &lhs, const Homogenous &hc)
00222 {
00223 return lhs << hc.x << " " << hc.y << " " << hc.z << " " << hc.w;
00224 }
00225
00226
00227
00228
00229
00230 #endif