00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "math/vector.hpp"
00035 #include "math/units.hpp"
00036 #include "data/string.hpp"
00037 #include "data/list.hpp"
00038
00039 #include <cmath>
00040 #include <cstring>
00041
00042 namespace gsgl
00043 {
00044
00045 namespace math
00046 {
00047
00048 const vector vector::ZERO(0, 0, 0);
00049 const vector vector::X_AXIS(1, 0, 0);
00050 const vector vector::Y_AXIS(0, 1, 0);
00051 const vector vector::Z_AXIS(0, 0, 1);
00052 const vector vector::NEG_X_AXIS(-1, 0, 0);
00053 const vector vector::NEG_Y_AXIS(0, -1, 0);
00054 const vector vector::NEG_Z_AXIS(0, 0, -1);
00055
00056 vector::vector(gsgl::real_t x, gsgl::real_t y, gsgl::real_t z)
00057 : matrix<4,1,gsgl::real_t>()
00058 {
00059 data[0] = x;
00060 data[1] = y;
00061 data[2] = z;
00062 data[3] = 1;
00063 }
00064
00065 vector::vector(const gsgl::real_t *ptr)
00066 : matrix<4,1,gsgl::real_t>(ptr)
00067 {
00068 }
00069
00070 vector::vector(const vector & v)
00071 : matrix<4,1,gsgl::real_t>(v)
00072 {
00073 }
00074
00075 vector::vector(const matrix<4,1,gsgl::real_t> & v)
00076 : matrix<4,1,gsgl::real_t>(v)
00077 {
00078 if (data[3] != static_cast<gsgl::real_t>(1))
00079 normalize_h();
00080 }
00081
00082 vector & vector::operator= (const vector & v)
00083 {
00084 ::memcpy(data, v.data, sizeof(gsgl::real_t) * 4);
00085 return *this;
00086 }
00087
00088 vector & vector::operator= (const matrix<4,1,gsgl::real_t> & m)
00089 {
00090 ::memcpy(data, m.ptr(), sizeof(gsgl::real_t) * 4);
00091 return *this;
00092 }
00093
00094 vector::~vector()
00095 {
00096 }
00097
00098 vector::vector(const string & s)
00099 : matrix<4,1,gsgl::real_t>()
00100 {
00101 data[3] = 1;
00102
00103 data::list<string> components = s.split(L" ");
00104 int index = 0;
00105 for (data::list<string>::iterator i = components.iter(); i.is_valid(); ++i)
00106 {
00107 if (i->size())
00108 data[index++] = static_cast<gsgl::real_t>(i->to_double());
00109 if (index == 4)
00110 break;
00111 }
00112 }
00113
00114 void vector::normalize()
00115 {
00116 gsgl::real_t m = mag();
00117 if (m > 0)
00118 {
00119 data[0] /= m;
00120 data[1] /= m;
00121 data[2] /= m;
00122 }
00123 }
00124
00125 void vector::normalize_h()
00126 {
00127 gsgl::real_t m = data[3];
00128 if (m > 0)
00129 {
00130 data[0] /= m;
00131 data[1] /= m;
00132 data[2] /= m;
00133 data[3] /= m;
00134 }
00135 }
00136
00137
00138 gsgl::real_t vector::mag() const
00139 {
00140 gsgl::real_t result = 0.0;
00141 for (size_t i = 0; i < 3; ++i)
00142 result += data[i]*data[i];
00143 return ::sqrt(result);
00144 }
00145
00146
00147 gsgl::real_t vector::mag2() const
00148 {
00149 gsgl::real_t result = 0.0;
00150 for (size_t i = 0; i < 3; ++i)
00151 result += data[i]*data[i];
00152 return result;
00153 }
00154
00155
00156
00157 vector vector::operator- () const
00158 {
00159 return vector(-data[0], -data[1], -data[2]);
00160 }
00161
00162
00163 vector vector::operator+ (const vector & v) const
00164 {
00165 return vector(data[0] + v.data[0], data[1] + v.data[1], data[2] + v.data[2]);
00166 }
00167
00168
00169 vector vector::operator- (const vector & v) const
00170 {
00171 return vector(data[0] - v.data[0], data[1] - v.data[1], data[2] - v.data[2]);
00172 }
00173
00174
00175
00176 vector & vector::operator+= (const vector & v)
00177 {
00178 for (int i = 0; i < 3; ++i)
00179 data[i] += v.data[i];
00180 return *this;
00181 }
00182
00183
00184
00185 vector & vector::operator-= (const vector & v)
00186 {
00187 for (int i = 0; i < 3; ++i)
00188 data[i] -= v.data[i];
00189 return *this;
00190 }
00191
00192
00193
00194 vector & vector::operator*= (const gsgl::real_t n)
00195 {
00196 data[0] *= n;
00197 data[1] *= n;
00198 data[2] *= n;
00199 return *this;
00200 }
00201
00202
00203
00204 vector vector::operator* (const gsgl::real_t n)
00205 {
00206 return vector(data[0]*n, data[1]*n, data[2]*n);
00207 }
00208
00209
00210 gsgl::real_t vector::dot(const vector & v) const
00211 {
00212 gsgl::real_t result = 0.0;
00213 for (size_t i = 0; i < 3; ++i)
00214 result += data[i]*v.data[i];
00215 return result;
00216 }
00217
00218 vector vector::cross(const vector & v) const
00219 {
00220 return vector(data[1]*v.data[2] - data[2]*v.data[1],
00221 data[2]*v.data[0] - data[0]*v.data[2],
00222 data[0]*v.data[1] - data[1]*v.data[0]);
00223 }
00224
00225
00226 vector vector::interpolate(const vector & start, const vector & end, const gsgl::real_t & percent)
00227 {
00228 return start + (end - start) * percent;
00229 }
00230
00231
00232 vector vector::parse(const string & str)
00233 {
00234 vector res(vector::ZERO);
00235
00236 data::list<string> tokens = str.split(L" ,\t");
00237
00238 int num = 0;
00239 for (data::list<string>::iterator i = tokens.iter(); i.is_valid(); ++i)
00240 {
00241 if (!i->is_empty())
00242 res.data[num++] = units::parse(*i);
00243 }
00244
00245 return res;
00246 }
00247
00248 }
00249
00250 }