Give vector and point templated dimension size
This commit is contained in:
parent
a195f47bdf
commit
40c40507f9
40
matrix.cpp
40
matrix.cpp
@ -103,18 +103,24 @@ matrix::operator* (const matrix &rhs) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::point
|
util::point<3>
|
||||||
matrix::to_local (const util::point &p) const {
|
matrix::to_local (const util::point<3> &p) const {
|
||||||
CHECK_SOFT (is_affine ());
|
CHECK_SOFT (is_affine ());
|
||||||
|
|
||||||
return { p.x * values[0][0] + p.y * values[0][1] + p.z * values[0][2] + values[0][3],
|
return { p.x * values[0][0] +
|
||||||
p.x * values[1][0] + p.y * values[1][1] + p.z * values[1][2] + values[1][3],
|
p.y * values[0][1] +
|
||||||
p.x * values[2][0] + p.y * values[2][1] + p.z * values[2][2] + values[2][3] };
|
p.z * values[0][2] + values[0][3],
|
||||||
|
p.x * values[1][0] +
|
||||||
|
p.y * values[1][1] +
|
||||||
|
p.z * values[1][2] + values[1][3],
|
||||||
|
p.x * values[2][0] +
|
||||||
|
p.y * values[2][1] +
|
||||||
|
p.z * values[2][2] + values[2][3] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::point
|
util::point<3>
|
||||||
matrix::to_global (const util::point &p) const {
|
matrix::to_global (const util::point<3> &p) const {
|
||||||
return inverse ().to_local (p);
|
return inverse ().to_local (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +151,22 @@ matrix::ZEROES = { { { 0.0, 0.0, 0.0, 0.0 },
|
|||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
operator<< (std::ostream &os, const matrix &m) {
|
operator<< (std::ostream &os, const matrix &m) {
|
||||||
os << "{ {" << m.values[0][0] << ", " << m.values[0][1] << ", " << m.values[0][2] << ", " << m.values[0][3] << "}, "
|
os << "{ {" << m.values[0][0] << ", "
|
||||||
<< "{" << m.values[1][0] << ", " << m.values[1][1] << ", " << m.values[1][2] << ", " << m.values[1][3] << "}, "
|
<< m.values[0][1] << ", "
|
||||||
<< "{" << m.values[2][0] << ", " << m.values[2][1] << ", " << m.values[2][2] << ", " << m.values[2][3] << "}, "
|
<< m.values[0][2] << ", "
|
||||||
<< "{" << m.values[3][0] << ", " << m.values[3][1] << ", " << m.values[3][2] << ", " << m.values[3][3] << "} }";
|
<< m.values[0][3] << "}, "
|
||||||
|
<< "{" << m.values[1][0] << ", "
|
||||||
|
<< m.values[1][1] << ", "
|
||||||
|
<< m.values[1][2] << ", "
|
||||||
|
<< m.values[1][3] << "}, "
|
||||||
|
<< "{" << m.values[2][0] << ", "
|
||||||
|
<< m.values[2][1] << ", "
|
||||||
|
<< m.values[2][2] << ", "
|
||||||
|
<< m.values[2][3] << "}, "
|
||||||
|
<< "{" << m.values[3][0] << ", "
|
||||||
|
<< m.values[3][1] << ", "
|
||||||
|
<< m.values[3][2] << ", "
|
||||||
|
<< m.values[3][3] << "} }";
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ namespace util {
|
|||||||
|
|
||||||
matrix operator* (const matrix&) const;
|
matrix operator* (const matrix&) const;
|
||||||
|
|
||||||
point to_local (const point &p) const;
|
point<3> to_local (const point<3> &p) const;
|
||||||
point to_global (const point &p) const;
|
point<3> to_global (const point<3> &p) const;
|
||||||
|
|
||||||
bool is_affine (void) const;
|
bool is_affine (void) const;
|
||||||
|
|
||||||
|
122
point.cpp
122
point.cpp
@ -24,79 +24,129 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace util;
|
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
util::point<S>::point ()
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
point::distance (const point &other) const {
|
util::point<S>::distance (const util::point<S> &other) const {
|
||||||
return sqrt (distance2 (other));
|
return sqrt (distance2 (other));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
point::distance2 (const point &other) const {
|
util::point<S>::distance2 (const util::point<S> &other) const {
|
||||||
return (x - other.x) * (x - other.x) +
|
double total = 0.0;
|
||||||
(y - other.y) * (y - other.y) +
|
|
||||||
(z - other.z) * (z - other.z);
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
total += pow2 (this->data[i] - other.data[i]);
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
point::manhattan (const point &other) const {
|
util::point<S>::manhattan (const util::point<S> &other) const {
|
||||||
return fabs (x - other.x) +
|
double total = 0.0;
|
||||||
fabs (y - other.y) +
|
|
||||||
fabs (z - other.z);
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
total += fabs (this->data[i] - other.data[i]);
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
point&
|
template <size_t S>
|
||||||
point::operator*= (double f) {
|
util::point<S>&
|
||||||
x *= f;
|
util::point<S>::operator*= (double f) {
|
||||||
y *= f;
|
for (double &i: this->data)
|
||||||
z *= f;
|
i *= f;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
point
|
template <size_t S>
|
||||||
point::operator* (double f) const {
|
util::point<S>
|
||||||
return { x * f, y * f, z * f };
|
util::point<S>::operator* (double f) const {
|
||||||
|
util::point<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] * f;
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
point
|
template <size_t S>
|
||||||
point::operator+ (const vector &rhs) const {
|
util::point<S>
|
||||||
return { x + rhs.x, y + rhs.y, z + rhs.z };
|
util::point<S>::operator+ (const util::vector<S> &rhs) const {
|
||||||
|
util::point<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] + rhs.data[i];
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
point&
|
template <size_t S>
|
||||||
point::operator+= (const vector &rhs) {
|
util::point<S>&
|
||||||
x += rhs.x;
|
util::point<S>::operator+= (const util::vector<S> &rhs) {
|
||||||
y += rhs.y;
|
for (size_t i = 0; i < S; ++i)
|
||||||
z += rhs.z;
|
this->data[i] += rhs.data[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::vector
|
template <size_t S>
|
||||||
point::operator- (const point &rhs) const {
|
util::point<S>
|
||||||
return { x - rhs.x, y - rhs.y, z - rhs.z };
|
util::point<S>::operator- (const util::point<S> &rhs) const {
|
||||||
|
util::point<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] - rhs.data[i];
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
util::vector<S>
|
||||||
|
util::point<S>::to (const util::point<S> &rhs) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = rhs.data[i] - this->data[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
void
|
void
|
||||||
point::sanity (void) const {
|
util::point<S>::sanity (void) const {
|
||||||
CHECK_SOFT (!std::isnan (x));
|
CHECK_SOFT (std::all_of (begin (this->data),
|
||||||
CHECK_SOFT (!std::isnan (y));
|
end (this->data),
|
||||||
CHECK_SOFT (!std::isnan (z));
|
[] (double i) { return !std::isnan (i); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
operator<< (std::ostream &os, const point &p) {
|
util::operator<< (std::ostream &os, const util::point<S> &p) {
|
||||||
os << "point(" << p.x << ", " << p.y << ", " << p.z << ")";
|
os << "point" << S << "(";
|
||||||
|
os << p.data[0];
|
||||||
|
|
||||||
|
for (size_t i = 1; i < S; ++i)
|
||||||
|
os << ", " << p.data[i];
|
||||||
|
|
||||||
|
os << ")";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template struct util::point<1>;
|
||||||
|
template struct util::point<2>;
|
||||||
|
template struct util::point<3>;
|
||||||
|
40
point.hpp
40
point.hpp
@ -20,31 +20,49 @@
|
|||||||
#ifndef __UTIL_POINT_HPP
|
#ifndef __UTIL_POINT_HPP
|
||||||
#define __UTIL_POINT_HPP
|
#define __UTIL_POINT_HPP
|
||||||
|
|
||||||
|
#include "vector.hpp"
|
||||||
|
#include "detail/coord.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <initializer_list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "vector.hpp"
|
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
/// A three dimensional position in space.
|
/// An n-dimensional position in space.
|
||||||
struct point {
|
template <size_t S>
|
||||||
double x, y, z;
|
struct point : public detail::coord_data<S> {
|
||||||
|
static_assert (S > 0, "point dimensions must be strictly positive.");
|
||||||
|
|
||||||
|
point ();
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
point (T ...t): detail::coord_data<S> {std::forward<T> (t)...} { ; }
|
||||||
|
|
||||||
double distance (const point &) const;
|
double distance (const point &) const;
|
||||||
double distance2 (const point &) const;
|
double distance2 (const point &) const;
|
||||||
double manhattan (const point &) const;
|
double manhattan (const point &) const;
|
||||||
|
|
||||||
point& operator*= (double);
|
point<S>& operator*= (double);
|
||||||
point operator* (double) const;
|
point<S> operator* (double) const;
|
||||||
|
point<S> operator- (const point<S>&) const;
|
||||||
|
|
||||||
point operator+ (const vector&) const;
|
point<S> operator+ (const util::vector<S>&) const;
|
||||||
point& operator+= (const vector&);
|
point<S>& operator+= (const util::vector<S>&);
|
||||||
vector operator- (const point&) const;
|
|
||||||
|
util::vector<S> to (const point<S>&) const;
|
||||||
|
|
||||||
|
template <size_t D> point<D> redim (void);
|
||||||
|
|
||||||
void sanity (void) const;
|
void sanity (void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef point<2> point2;
|
||||||
|
typedef point<3> point3;
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
std::ostream& operator<< (std::ostream&, const util::point<S>&);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream&, const util::point&);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __UTIL_POINT_HPP
|
#endif // __UTIL_POINT_HPP
|
||||||
|
14
region.cpp
14
region.cpp
@ -41,7 +41,7 @@ region<T>::region (T _x, T _y, T _w, T _h):
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
region<T>&
|
region<T>&
|
||||||
region<T>::operator+= (const vector &rhs) {
|
region<T>::operator+= (const vector<2> &rhs) {
|
||||||
x += rhs.x;
|
x += rhs.x;
|
||||||
y += rhs.y;
|
y += rhs.y;
|
||||||
|
|
||||||
@ -69,25 +69,25 @@ region<T>::empty (void) const
|
|||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
point
|
point<2>
|
||||||
region<T>::base (void) const {
|
region<T>::base (void) const {
|
||||||
return { static_cast<double> (x), static_cast<double> (y), 0.0 };
|
return { static_cast<double> (x), static_cast<double> (y) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
point
|
point<2>
|
||||||
region<T>::centre (void) const {
|
region<T>::centre (void) const {
|
||||||
double cx = x + static_cast<T>(w / 2.0),
|
double cx = x + static_cast<T>(w / 2.0),
|
||||||
cy = y + static_cast<T>(h / 2.0);
|
cy = y + static_cast<T>(h / 2.0);
|
||||||
|
|
||||||
return { cx, cy, 0.0 };
|
return { cx, cy };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool
|
bool
|
||||||
region<T>::includes (const point &p) const {
|
region<T>::includes (const point<2> &p) const {
|
||||||
return p.x >= x &&
|
return p.x >= x &&
|
||||||
p.y >= y &&
|
p.y >= y &&
|
||||||
p.x <= x + w &&
|
p.x <= x + w &&
|
||||||
@ -97,7 +97,7 @@ region<T>::includes (const point &p) const {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool
|
bool
|
||||||
region<T>::contains (const point& p) const {
|
region<T>::contains (const point<2> &p) const {
|
||||||
return p.x > x &&
|
return p.x > x &&
|
||||||
p.y > y &&
|
p.y > y &&
|
||||||
p.x < x + w &&
|
p.x < x + w &&
|
||||||
|
10
region.hpp
10
region.hpp
@ -34,18 +34,18 @@ namespace util {
|
|||||||
|
|
||||||
region (T _x, T _y, T _w, T _h);
|
region (T _x, T _y, T _w, T _h);
|
||||||
|
|
||||||
region& operator +=(const vector& rhs);
|
region& operator +=(const vector<2>& rhs);
|
||||||
|
|
||||||
T area (void) const;
|
T area (void) const;
|
||||||
T diameter (void) const;
|
T diameter (void) const;
|
||||||
|
|
||||||
bool empty (void) const;
|
bool empty (void) const;
|
||||||
|
|
||||||
point base (void) const;
|
point<2> base (void) const;
|
||||||
point centre (void) const;
|
point<2> centre (void) const;
|
||||||
|
|
||||||
bool includes (const point&) const; // inclusive of borders
|
bool includes (const point<2>&) const; // inclusive of borders
|
||||||
bool contains (const point&) const; // exclusive of borders
|
bool contains (const point<2>&) const; // exclusive of borders
|
||||||
bool overlaps (const region<T>&) const; // exclusive of borders
|
bool overlaps (const region<T>&) const; // exclusive of borders
|
||||||
|
|
||||||
region overlap (const region<T>&) const;
|
region overlap (const region<T>&) const;
|
||||||
|
285
vector.cpp
285
vector.cpp
@ -29,141 +29,193 @@
|
|||||||
|
|
||||||
|
|
||||||
using namespace util;
|
using namespace util;
|
||||||
|
using std::begin;
|
||||||
|
using std::end;
|
||||||
|
|
||||||
util::vector
|
|
||||||
util::vector::operator* (double rhs) const {
|
template <size_t S>
|
||||||
return { rhs * x, rhs * y, rhs * z };
|
util::vector<S>::vector ()
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//template <size_t S>
|
||||||
|
//util::vector<S>::vector (const std::initializer_list<double> &_data) {
|
||||||
|
// CHECK (_data.size () == S);
|
||||||
|
//
|
||||||
|
// std::copy (std::begin (_data),
|
||||||
|
// std::end (_data),
|
||||||
|
// std::begin (this->data));
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
util::vector<S>
|
||||||
|
util::vector<S>::operator* (double rhs) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] * rhs;
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector&
|
template <size_t S>
|
||||||
vector::operator*= (double rhs) {
|
util::vector<S>&
|
||||||
x *= rhs;
|
util::vector<S>::operator*= (double rhs) {
|
||||||
y *= rhs;
|
for (double &i: this->data)
|
||||||
z *= rhs;
|
i *= rhs;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::vector
|
template <size_t S>
|
||||||
util::vector::operator* (const vector &rhs) const {
|
util::vector<S>
|
||||||
return { x * rhs.x, y * rhs.y, z * rhs.z };
|
util::vector<S>::operator* (const util::vector<S> &rhs) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] * rhs.data[i];
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::vector&
|
template <size_t S>
|
||||||
util::vector::operator*= (const vector &rhs) {
|
util::vector<S>&
|
||||||
x *= rhs.x;
|
util::vector<S>::operator*= (const util::vector<S> &rhs) {
|
||||||
y *= rhs.y;
|
for (size_t i = 0; i < S; ++i)
|
||||||
z *= rhs.z;
|
this->data[i] *= rhs.data[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
template <size_t S>
|
||||||
vector::operator+ (const vector &rhs) const {
|
util::vector<S>
|
||||||
return { x + rhs.x, y + rhs.y, z + rhs.z };
|
util::vector<S>::operator+ (const util::vector<S> &rhs) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] + rhs.data[i];
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
template <size_t S>
|
||||||
vector::operator- (void) const {
|
util::vector<S>
|
||||||
return { -x, -y, -z };
|
util::vector<S>::operator- (void) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = -this->data[i];
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
template <size_t S>
|
||||||
vector::operator- (const vector &rhs) const
|
util::vector<S>
|
||||||
{ return { x - rhs.x, y - rhs.y, z - rhs.z }; }
|
util::vector<S>::operator- (const util::vector<S> &rhs) const {
|
||||||
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] - rhs.data[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
vector&
|
template <size_t S>
|
||||||
vector::operator-= (const vector &rhs) {
|
util::vector<S>&
|
||||||
x -= rhs.x;
|
util::vector<S>::operator-= (const util::vector<S> &rhs) {
|
||||||
y -= rhs.y;
|
for (size_t i = 0; i < S; ++i)
|
||||||
z -= rhs.z;
|
this->data[i] -= rhs.data[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector&
|
template <size_t S>
|
||||||
vector::operator+= (const vector &rhs) {
|
util::vector<S>&
|
||||||
x += rhs.x;
|
util::vector<S>::operator+= (const util::vector<S> &rhs) {
|
||||||
y += rhs.y;
|
for (size_t i = 0; i < S; ++i)
|
||||||
z += rhs.z;
|
this->data[i] += rhs.data[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector&
|
template <size_t S>
|
||||||
vector::operator= (const vector &rhs) {
|
util::vector<S>&
|
||||||
x = rhs.x;
|
util::vector<S>::operator= (const util::vector<S> &rhs) {
|
||||||
y = rhs.y;
|
std::copy (begin (rhs.data), end (rhs.data), begin (this->data));
|
||||||
z = rhs.z;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
bool
|
bool
|
||||||
vector::operator== (const vector &rhs) const {
|
util::vector<S>::operator== (const util::vector<S> &rhs) const {
|
||||||
return almost_equal (x, rhs.x) &&
|
for (size_t i = 0; i < S; ++i)
|
||||||
almost_equal (y, rhs.y) &&
|
if (!almost_equal (this->data[i], rhs.data[i]))
|
||||||
almost_equal (z, rhs.z);
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
vector::magnitude (void) const {
|
util::vector<S>::magnitude (void) const {
|
||||||
return sqrt (x * x + y * y + z * z);
|
return sqrt (magnitude2 ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
vector::magnitude2 (void) const {
|
util::vector<S>::magnitude2 (void) const {
|
||||||
return x * x + y * y + z * z;
|
double total = 0.0;
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
total += pow2 (this->data[i]);
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
double
|
double
|
||||||
vector::dot (const vector &rhs) const {
|
util::vector<S>::dot (const util::vector<S> &rhs) const {
|
||||||
return x * rhs.x + y * rhs.y + z * rhs.z;
|
double total = 0.0;
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
total += this->data[i] + rhs.data[i];
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
template <size_t S>
|
||||||
vector::cross (const vector &rhs) const {
|
util::vector<S>&
|
||||||
return { y * rhs.z - z * rhs.y,
|
util::vector<S>::normalise (void) {
|
||||||
z * rhs.x - x * rhs.z,
|
|
||||||
x * rhs.y - y * rhs.x };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector&
|
|
||||||
vector::normalise (void) {
|
|
||||||
double mag = magnitude ();
|
double mag = magnitude ();
|
||||||
|
|
||||||
x /= mag;
|
for (size_t i = 0; i < S; ++i)
|
||||||
y /= mag;
|
this->data[i] /= mag;
|
||||||
z /= mag;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
template <size_t S>
|
||||||
vector::normalised (void) const {
|
util::vector<S>
|
||||||
|
util::vector<S>::normalised (void) const {
|
||||||
double mag = magnitude ();
|
double mag = magnitude ();
|
||||||
return { x / mag, y / mag, z / mag };
|
util::vector<S> out;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
|
out.data[i] = this->data[i] / mag;
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
util::vector<3>
|
||||||
vector::spherical_to_cartesian (const vector &s) {
|
util::spherical_to_cartesian (const util::vector<3> &s) {
|
||||||
return {
|
return {
|
||||||
s.x * sin (s.y) * cos (s.z),
|
s.x * sin (s.y) * cos (s.z),
|
||||||
s.x * sin (s.y) * sin (s.z),
|
s.x * sin (s.y) * sin (s.z),
|
||||||
@ -172,8 +224,8 @@ vector::spherical_to_cartesian (const vector &s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector
|
util::vector<3>
|
||||||
vector::cartesian_to_spherical (const vector &c) {
|
util::cartesian_to_spherical (const util::vector<3> &c) {
|
||||||
double mag = c.magnitude ();
|
double mag = c.magnitude ();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -184,58 +236,81 @@ vector::cartesian_to_spherical (const vector &c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
bool
|
bool
|
||||||
vector::is_zero (void) const {
|
util::vector<S>::is_zero (void) const {
|
||||||
return almost_equal (x, 0.0) &&
|
return std::all_of (begin (this->data),
|
||||||
almost_equal (y, 0.0) &&
|
end (this->data),
|
||||||
almost_equal (z, 0.0);
|
[] (double i) { return almost_zero (i); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
void
|
void
|
||||||
vector::sanity (void) const {
|
util::vector<S>::sanity (void) const {
|
||||||
CHECK_SOFT (!std::isnan (x));
|
CHECK_SOFT (std::all_of (begin (this->data),
|
||||||
CHECK_SOFT (!std::isnan (y));
|
end (this->data),
|
||||||
CHECK_SOFT (!std::isnan (z));
|
[] (double i) { return !std::isnan (i); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
util::vector
|
util::vector<3>
|
||||||
util::operator* (double a, const util::vector &b)
|
util::cross (const util::vector<3> &a, const util::vector<3> &b) {
|
||||||
|
return { a.y * b.z - a.z * b.y,
|
||||||
|
a.z * b.x - a.x * b.z,
|
||||||
|
a.x * b.y - a.y * b.x };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
util::vector<S>
|
||||||
|
util::operator* (double a, const util::vector<S> &b)
|
||||||
{ return b * a; }
|
{ return b * a; }
|
||||||
|
|
||||||
|
|
||||||
|
template util::vector<1> util::operator* (double, const util::vector<1>&);
|
||||||
|
template util::vector<2> util::operator* (double, const util::vector<2>&);
|
||||||
|
template util::vector<3> util::operator* (double, const util::vector<3>&);
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
util::operator<< (std::ostream &os, const util::vector &v) {
|
util::operator<< (std::ostream &os, const util::vector<S> &v) {
|
||||||
os << "vec(" << v.x << ", " << v.y << ", " << v.z << ")";
|
os << "vec" << S << "(" << v.data[0];
|
||||||
|
for (double i: v.data)
|
||||||
|
os << ", " << i;
|
||||||
|
os << ")";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template std::ostream& util::operator<< (std::ostream&, const util::vector<1> &v);
|
||||||
|
template std::ostream& util::operator<< (std::ostream&, const util::vector<2> &v);
|
||||||
|
template std::ostream& util::operator<< (std::ostream&, const util::vector<3> &v);
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
const json::node&
|
const json::node&
|
||||||
util::operator>> (const json::node &node, util::vector &v) {
|
util::operator>> (const json::node &node, util::vector<S> &v) {
|
||||||
const json::array &array = node.as_array ();
|
const json::array &array = node.as_array ();
|
||||||
|
if (array.size () != S)
|
||||||
|
throw std::runtime_error ("Invalid dimensionality for json-to-vector");
|
||||||
|
|
||||||
switch (array.size ()) {
|
std::transform (begin (array),
|
||||||
case 1:
|
end (array),
|
||||||
v.x = array[0].as_number ();
|
begin (v.data),
|
||||||
v.y = std::numeric_limits<double>::quiet_NaN ();
|
[] (const json::node &n) {
|
||||||
v.z = std::numeric_limits<double>::quiet_NaN ();
|
return n.as_number ().native ();
|
||||||
return node;
|
});
|
||||||
|
return node;
|
||||||
case 2: v.y = array[1].as_number ();
|
|
||||||
v.x = array[0].as_number ();
|
|
||||||
v.y = array[1].as_number ();
|
|
||||||
v.z = std::numeric_limits<double>::quiet_NaN ();
|
|
||||||
return node;
|
|
||||||
|
|
||||||
case 3: v.z = array[2].as_number ();
|
|
||||||
v.x = array[0].as_number ();
|
|
||||||
v.y = array[1].as_number ();
|
|
||||||
v.z = array[2].as_number ();
|
|
||||||
return node;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error ("Invalid dimensionality for json-to-vector");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template const json::node& util::operator>> (const json::node&, util::vector<1>&);
|
||||||
|
template const json::node& util::operator>> (const json::node&, util::vector<2>&);
|
||||||
|
template const json::node& util::operator>> (const json::node&, util::vector<3>&);
|
||||||
|
|
||||||
|
|
||||||
|
template struct util::vector<1>;
|
||||||
|
template struct util::vector<2>;
|
||||||
|
template struct util::vector<3>;
|
||||||
|
64
vector.hpp
64
vector.hpp
@ -21,50 +21,70 @@
|
|||||||
#define __UTIL_VECTOR_HPP
|
#define __UTIL_VECTOR_HPP
|
||||||
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "detail/coord.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
struct vector {
|
template <size_t S>
|
||||||
double x, y, z;
|
struct vector : public detail::coord_data<S> {
|
||||||
|
static_assert (S > 0, "vector dimensions must be strictly positive");
|
||||||
|
|
||||||
vector operator* (double) const;
|
vector ();
|
||||||
vector& operator*=(double);
|
|
||||||
vector operator* (const vector&) const;
|
|
||||||
vector& operator*=(const vector&);
|
|
||||||
|
|
||||||
vector operator+ (const vector&) const;
|
template <typename... T>
|
||||||
vector& operator+=(const vector&);
|
vector (T ...t): detail::coord_data<S> {std::forward<T> (t)...} { ; }
|
||||||
|
|
||||||
vector operator- (void) const;
|
util::vector<S> operator* (double) const;
|
||||||
vector operator- (const vector&) const;
|
util::vector<S>& operator*=(double);
|
||||||
vector& operator-=(const vector&);
|
util::vector<S> operator* (const util::vector<S>&) const;
|
||||||
|
util::vector<S>& operator*=(const util::vector<S>&);
|
||||||
|
|
||||||
vector& operator =(const vector &);
|
util::vector<S> operator+ (const util::vector<S>&) const;
|
||||||
|
util::vector<S>& operator+=(const util::vector<S>&);
|
||||||
|
|
||||||
bool operator== (const vector &) const;
|
util::vector<S> operator- (void) const;
|
||||||
|
util::vector<S> operator- (const util::vector<S>&) const;
|
||||||
|
util::vector<S>& operator-=(const util::vector<S>&);
|
||||||
|
|
||||||
|
util::vector<S>& operator =(const util::vector <S>&);
|
||||||
|
|
||||||
|
bool operator== (const util::vector <S>&) const;
|
||||||
|
|
||||||
double magnitude (void) const;
|
double magnitude (void) const;
|
||||||
double magnitude2 (void) const;
|
double magnitude2 (void) const;
|
||||||
|
|
||||||
double dot (const vector&) const;
|
double dot (const util::vector<S>&) const;
|
||||||
vector cross (const vector&) const;
|
|
||||||
|
|
||||||
vector& normalise (void);
|
util::vector<S>& normalise (void);
|
||||||
vector normalised (void) const;
|
util::vector<S> normalised (void) const;
|
||||||
|
|
||||||
static vector spherical_to_cartesian (const vector &);
|
|
||||||
static vector cartesian_to_spherical (const vector &);
|
|
||||||
|
|
||||||
bool is_zero (void) const;
|
bool is_zero (void) const;
|
||||||
|
|
||||||
void sanity (void) const;
|
void sanity (void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
util::vector operator* (double, const util::vector&);
|
vector<3> cross (const vector<3>&, const vector<3>&);
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream&, const util::vector&);
|
vector<3> spherical_to_cartesian (const util::vector <3>&);
|
||||||
const json::node& operator>> (const json::node&, util::vector&);
|
vector<3> cartesian_to_spherical (const util::vector <3>&);
|
||||||
|
|
||||||
|
|
||||||
|
typedef vector<2> vector2;
|
||||||
|
typedef vector<3> vector3;
|
||||||
|
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
util::vector<S> operator* (double, const util::vector<S>&);
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
std::ostream& operator<< (std::ostream&, const util::vector<S>&);
|
||||||
|
|
||||||
|
template <size_t S>
|
||||||
|
const json::node& operator>> (const json::node&, util::vector<S>&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user