00001 #include <math.h>
00002 #include <stdio.h>
00003 #include "vuSpherical.h"
00004 #include "vuVector.h"
00005
00006
00007
00008 vuSpherical::vuSpherical()
00009 {
00010 val[0] = val[1] = val[2] = 0.0f;
00011 }
00012
00013
00014 vuSpherical::vuSpherical(const vuSpherical& v)
00015 {
00016 val[0] = v.val[0];
00017 val[1] = v.val[1];
00018 val[2] = v.val[2];
00019 }
00020
00021
00022 vuSpherical::vuSpherical(float longitude, float latitude, float radius)
00023 {
00024 val[0] = longitude;
00025 val[1] = latitude;
00026 val[2] = radius;
00027 }
00028
00029 vuSpherical::vuSpherical(const float* v)
00030 {
00031 val[0] = v[0];
00032 val[1] = v[1];
00033 val[2] = v[2];
00034 }
00035
00036 vuSpherical::vuSpherical(vuVector &vector)
00037 {
00038 float longitude = 0.0f;
00039 float latitude = 0.0f;
00040 float radius = vector.norm();
00041 float xx = vector[0];
00042 float yy = vector[1];
00043 float zz = vector[2];
00044
00045 if ((xx == 0.0f) && (yy == 0.0f)) {
00046 longitude = 0.0;
00047 latitude = (zz == 0) ? 0 : (zz > 0) ? M_PI : -M_PI;
00048 }
00049 else {
00050 latitude = acos(zz/radius);
00051 if (xx == 0.0f) {
00052 if (yy > 0)
00053 longitude = M_PI_2;
00054 else if (yy < 0)
00055 longitude = M_PI_2 + M_PI;
00056 else
00057 throw "this case is not possible";
00058 }
00059 else if (xx > 0.0f) {
00060 if (yy >= 0)
00061 longitude = atan(yy/xx);
00062 else
00063 longitude = 2*M_PI + atan(yy/xx);
00064 }
00065 else {
00066 longitude = M_PI + atan(yy/xx);
00067 }
00068 }
00069 val[0] = longitude;
00070 val[1] = latitude;
00071 val[2] = radius;
00072 }
00073
00074
00075 vuSpherical::~vuSpherical()
00076 {
00077 }
00078
00079
00080 vuSpherical& vuSpherical::operator=(const vuSpherical& v)
00081 {
00082 if (this != &v)
00083 {
00084 val[0] = v.val[0];
00085 val[1] = v.val[1];
00086 val[2] = v.val[2];
00087 }
00088 return *this;
00089 }
00090
00091
00092 const float& vuSpherical::operator[](dword index) const
00093 {
00094 return val[index];
00095 }
00096
00097 float const* vuSpherical::getData(void) const
00098 { return val; }
00099
00100
00101 float vuSpherical::norm(void) const
00102 {
00103 return val[2];
00104 }
00105
00106
00107 float vuSpherical::norm2(void) const
00108 {
00109 return val[2]*val[2];
00110 }
00111
00112
00113 vuSpherical& vuSpherical::makeUnit(void)
00114 {
00115 val[2] = 1.0f;
00116 return *this;
00117 }
00118
00119
00120 bool vuSpherical::operator==(const vuSpherical& v) const
00121 {
00122 return ((val[0]==v.val[0])&&(val[1]==v.val[1])&&(val[2]==v.val[2]));
00123 }
00124
00125
00126 bool vuSpherical::operator!=(const vuSpherical& v) const
00127 {
00128 return !(operator==(v));
00129 }
00130
00131 void vuSpherical::print()
00132 {
00133 printf("( %4.4f, %4.4f, %4.4f )\n", val[0], val[1], val[2]);
00134 }
00135
00136 ostream& operator<<(ostream& out,const vuSpherical& v)
00137 {
00138 out<<v.val[0]<<" "<<v.val[1]<<" "<<v.val[2]<<endl;
00139 return out;
00140 }
00141
00142 istream& operator>>(istream& in, vuSpherical& v)
00143 {
00144 in>>v.val[0];
00145 in>>v.val[1];
00146 in>>v.val[2];
00147 return in;
00148 }
00149
00150 vuVector vuSpherical::getVector()
00151 {
00152 float v[3];
00153 float sinLong = sin(v[0]);
00154 v[0] = val[2]*cos(val[1])*sinLong;
00155 v[1] = val[2]*sin(val[1])*sinLong;
00156 v[2] = val[2]*cos(val[0]);
00157
00158 return vuVector(v);
00159 }
00160
00161
00162
00163
00164
00165 inline void vuSpherical::ensure(float &longitude,
00166 float &latitude,
00167 float &radius)
00168 {
00169 if (longitude >= 2*M_PI) {
00170 while (longitude >= 2*M_PI) longitude -= 2*M_PI;
00171 }
00172 else if (longitude < 0.0f) {
00173 while (longitude < 0.0f) longitude += 2*M_PI;
00174 }
00175 }