Page MenuHomec4science

svector.h
No OneTemporary

File Metadata

Created
Tue, Jul 22, 20:09

svector.h

#ifndef __STATIC_VECTOR_H__
#define __STATIC_VECTOR_H__
#include <initializer_list>
#include <array>
#include <cmath> // needed for sqrt
template<std::size_t N>
class SVector
{
public:
typedef std::size_t size_t;
/* Constructors */
SVector()
{
this->components.fill(0);
}
SVector(const std::initializer_list<double> &init)
{
if (init.size() != N)
return; // TODO throw exception
/* copy init list without include <algorithm> */
size_t index = 0;
for (auto c : init)
this->components[index++] = c;
}
SVector(const SVector<N>& init)
{
*this = init;
}
/* Assignment operator */
SVector<N>& operator=(const SVector<N>& cpy)
{
size_t index = 0;
for (auto c : cpy)
this->components[index++] = c;
return *this;
}
/* For auto implementation */
/* it allows to loop through components
*
* for (auto comp : v)
* {
* // loop content
* }
*/
typedef typename std::array<double, N>::iterator iterator;
typedef typename std::array<double, N>::const_iterator const_iterator;
iterator begin() { return components.begin(); }
iterator end() { return components.end(); }
const_iterator begin() const { return components.begin(); }
const_iterator end() const { return components.end(); }
/* Reduce to module = 1 */
SVector<N> unit() const
{
return *this / this->module();
}
size_t size() const
{
return N; // quite basic
}
double& operator[](size_t i) { return components[i]; }
const double& operator[](size_t i) const { return components[i]; }
bool operator==(const SVector<N>& v) const
{
for (size_t i = 0; i < N; ++i)
{
if (components[i] != v[i])
return false;
}
return true;
}
bool operator!=(const SVector<N>& v) const
{
return !(*this == v);
}
/* Plus / minus */
SVector<N>& operator+=(const SVector<N>& v)
{
for (size_t i = 0; i < N; ++i)
components[i] += v[i];
return *this;
}
SVector<N>& operator-=(const SVector<N>& v)
{
for (size_t i = 0; i < N; ++i)
components[i] -= v[i];
return *this;
}
SVector<N> operator+(const SVector& v) const
{
SVector u = *this;
return u += v;
}
SVector<N> operator-(const SVector& v) const
{
SVector u = *this;
return u -= v;
}
/* Scalar multiplication / division */
SVector<N>& operator*=(double k)
{
for (size_t i = 0; i < N; ++i)
components[i] *= k;
return *this;
}
SVector<N>& operator/=(double k)
{
for (size_t i = 0; i < N; ++i)
components[i] /= k;
return *this;
}
SVector<N> operator*(double k) const
{
SVector u = *this;
return u *= k;
}
SVector<N> operator/(double k) const
{
SVector u = *this;
return u /= k;
}
/* Dot product */
double operator*(const SVector<N>& v) const
{
double x = 0;
for (size_t i = 0; i < N; ++i)
x += this->components[i] * v[i];
return x;
}
/* Return the module */
double module() const
{
return sqrt(this->sq_module());
}
double sq_module() const
{
double x;
for (auto c : components)
x += c * c;
return x;
}
static const SVector<N> nullv;
private:
std::array<double, N> components;
};
#ifdef STATIC_VECTOR_IO
template <std::size_t N>
std::ostream& operator<<(std::ostream& os, const SVector<N> &v)
{
os << "(";
for (auto comp : v)
{
os << comp << ", ";
}
os << ")";
return os;
}
#endif
/*
* Prototipe for cross product
* Implementation in vector.cpp
*/
SVector<3> operator^(const SVector<3>&, const SVector<3>&);
template <std::size_t N>
SVector<N> apply_matrix(const double (&matrix)[N][N], const SVector<N>& v)
{
SVector<N> out;
for (std::size_t i = 0; i < N; ++i)
{
for (std::size_t j = 0; j < N; ++j)
out[i] += matrix[i][j] * v[j];
}
return out;
}
template <std::size_t N>
SVector<N> apply_homo_matrix(const double (&matrix)[N+1][N+1], const SVector<N>& v)
{
SVector<N> out;
for (std::size_t i = 0; i < N; ++i)
{
for (std::size_t j = 0; j < N; ++j)
out[i] += matrix[i][j] * v[j];
/* homogene component */
out[i] += matrix[i][N];
}
return out;
}
#endif

Event Timeline