30 #ifndef WFMATH_VECTOR_FUNCS_H
31 #define WFMATH_VECTOR_FUNCS_H
33 #include <wfmath/vector.h>
34 #include <wfmath/rotmatrix.h>
35 #include <wfmath/zero.h>
46 for(
int i = 0; i < dim; ++i) {
47 m_elem[i] = v.m_elem[i];
54 for(
int i = 0; i < dim; ++i) {
55 m_elem[i] = p.elements()[i];
72 for(
int i = 0; i < dim; ++i) {
73 m_elem[i] = v.m_elem[i];
80 bool Vector<dim>::isEqualTo(
const Vector<dim>& v,
double epsilon)
const
82 double delta = _ScaleEpsilon(m_elem, v.m_elem, dim, epsilon);
84 for(
int i = 0; i < dim; ++i) {
85 if(fabs(m_elem[i] - v.m_elem[i]) > delta) {
94 Vector<dim>& operator+=(Vector<dim>& v1,
const Vector<dim>& v2)
96 v1.m_valid = v1.m_valid && v2.m_valid;
98 for(
int i = 0; i < dim; ++i) {
99 v1.m_elem[i] += v2.m_elem[i];
106 Vector<dim>& operator-=(Vector<dim>& v1,
const Vector<dim>& v2)
108 v1.m_valid = v1.m_valid && v2.m_valid;
110 for(
int i = 0; i < dim; ++i) {
111 v1.m_elem[i] -= v2.m_elem[i];
118 Vector<dim>& operator*=(Vector<dim>& v,
CoordType d)
120 for(
int i = 0; i < dim; ++i) {
128 Vector<dim>& operator/=(Vector<dim>& v,
CoordType d)
130 for(
int i = 0; i < dim; ++i) {
138 Vector<dim> operator+(
const Vector<dim>& v1,
const Vector<dim>& v2)
148 Vector<dim> operator-(
const Vector<dim>& v1,
const Vector<dim>& v2)
178 Vector<dim> operator/(
const Vector<dim>& v,
CoordType d)
188 Vector<dim> operator-(
const Vector<dim>& v)
192 ans.m_valid = v.m_valid;
194 for(
int i = 0; i < dim; ++i) {
195 ans.m_elem[i] = -v.m_elem[i];
206 assert(
"need nonzero length vector" && mag > norm / WFMATH_MAX);
208 return (*
this *= norm / mag);
216 for(
int i = 0; i < dim; ++i) {
240 assert(axis1 >= 0 && axis2 >= 0 && axis1 < dim && axis2 < dim && axis1 != axis2);
242 CoordType tmp1 = m_elem[axis1], tmp2 = m_elem[axis2];
244 ctheta = std::cos(theta);
246 m_elem[axis1] = tmp1 * ctheta - tmp2 * stheta;
247 m_elem[axis2] = tmp2 * ctheta + tmp1 * stheta;
257 return operator=(
Prod(*
this, m.
rotation(v1, v2, theta)));
263 return *
this =
Prod(*
this, m);
272 double delta = _ScaleEpsilon(v1.m_elem, v2.m_elem, dim);
276 for(
int i = 0; i < dim; ++i) {
277 ans += v1.m_elem[i] * v2.m_elem[i];
280 return (fabs(ans) >= delta) ? ans : 0;
288 for(
int i = 0; i < dim; ++i) {
290 ans += m_elem[i] * m_elem[i];
301 same_dir = (dot > 0);
317 double max1 = 0, max2 = 0;
319 for(
int i = 0; i < dim; ++i) {
320 double val1 = fabs(v1[i]), val2 = fabs(v2[i]);
331 (void) frexp(max1, &exp1);
332 (void) frexp(max2, &exp2);
334 return fabs(Dot(v1, v2)) < ldexp(WFMATH_EPSILON, exp1 + exp2);
346 return (CoordType) 1.082392200292393968799446410733;
350 const CoordType Vector<3>::sloppyMagMax()
352 return (CoordType) 1.145934719303161490541433900265;
356 const CoordType Vector<1>::sloppyMagMaxSqrt()
358 return (CoordType) 1;
362 const CoordType Vector<2>::sloppyMagMaxSqrt()
364 return (CoordType) 1.040380795811030899095785063701;
368 const CoordType Vector<3>::sloppyMagMaxSqrt()
370 return (CoordType) 1.070483404496847625250328653179;
386 template<> Vector<2>& Vector<2>::polar(CoordType r, CoordType theta);
387 template<>
void Vector<2>::asPolar(CoordType& r, CoordType& theta)
const;
389 template<> Vector<3>& Vector<3>::polar(CoordType r, CoordType theta,
391 template<>
void Vector<3>::asPolar(CoordType& r, CoordType& theta,
393 template<> Vector<3>& Vector<3>::spherical(CoordType r, CoordType theta,
395 template<>
void Vector<3>::asSpherical(CoordType& r, CoordType& theta,
396 CoordType& phi)
const;
398 template<>
CoordType Vector<2>::sloppyMag()
const;
399 template<>
CoordType Vector<3>::sloppyMag()
const;
401 template<>
CoordType Vector<1>::sloppyMag()
const
402 {
return std::fabs(m_elem[0]);}
404 template<> Vector<2>::Vector(CoordType x, CoordType y) : m_valid(true)
405 {m_elem[0] = x; m_elem[1] = y;}
406 template<> Vector<3>::Vector(CoordType x, CoordType y, CoordType z) : m_valid(true)
407 {m_elem[0] = x; m_elem[1] = y; m_elem[2] = z;}
409 template<> Vector<2>& Vector<2>::rotate(CoordType theta)
410 {
return rotate(0, 1, theta);}
412 template<> Vector<3>& Vector<3>::rotateX(CoordType theta)
413 {
return rotate(1, 2, theta);}
414 template<> Vector<3>& Vector<3>::rotateY(CoordType theta)
415 {
return rotate(2, 0, theta);}
416 template<> Vector<3>& Vector<3>::rotateZ(CoordType theta)
417 {
return rotate(0, 1, theta);}
422 #endif // WFMATH_VECTOR_FUNCS_H