532 lines
20 KiB
C++
532 lines
20 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Paella
|
|
// Copyright (C) 2015 - Thomas FORGIONE, Emilie JALRAS, Marion LENFANT, Thierry MALON, Amandine PAILLOUX
|
|
// Authors :
|
|
// Thomas FORGIONE
|
|
// Emilie JALRAS
|
|
// Marion LENFANT
|
|
// Thierry MALON
|
|
// Amandine PAILLOUX
|
|
//
|
|
// This file is part of the project Paella
|
|
// This software is provided 'as-is', without any express or implied warranty.
|
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
//
|
|
// Permission is granted to anyone to use this software for any purpose,
|
|
// including commercial applications, and to alter it and redistribute it freely,
|
|
// subject to the following restrictions:
|
|
//
|
|
// 1. The origin of this software must not be misrepresented;
|
|
// you must not claim that you wrote the original software.
|
|
// If you use this software in a product, an acknowledgment
|
|
// in the product documentation would be appreciated but is not required.
|
|
//
|
|
// 2. Altered source versions must be plainly marked as such,
|
|
// and must not be misrepresented as being the original software.
|
|
//
|
|
// 3. This notice may not be removed or altered from any source distribution.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef VECTOR_HPP
|
|
#define VECTOR_HPP
|
|
|
|
#include <cmath>
|
|
#include <array>
|
|
#include <istream>
|
|
|
|
#include <Utility/VectorFunctions.hpp>
|
|
|
|
namespace geo
|
|
{
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
/// \ingroup geometry
|
|
/// \brief Utility template class for manipulating geometrics vector
|
|
///////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
class Vector
|
|
{
|
|
public:
|
|
//////////////////////////////////////////////////////////////////
|
|
/// \brief Default constructor
|
|
///
|
|
/// Calls the default constructor on each coordinates of the vector
|
|
//////////////////////////////////////////////////////////////////
|
|
Vector();
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
/// \brief Construct vector from its coordinates
|
|
///
|
|
/// \param l coordinates of the vector to construct
|
|
//////////////////////////////////////////////////////////////////
|
|
template<typename... Types>
|
|
constexpr Vector(Types... l);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Construct vector from another vector of the same size
|
|
///
|
|
/// \param v Vector to copy
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename U>
|
|
Vector(Vector<U,N> const& v);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Compute the square of the norm of a vector
|
|
/// \see norm
|
|
/// \return the square of the norm of the vector
|
|
/// Use this method when you need to compare vector sizes
|
|
/////////////////////////////////////////////////////////////////
|
|
T norm2() const;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Compute the norm of a vector
|
|
/// \return the norm of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
T norm() const;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Overload of the unary operator -
|
|
///
|
|
/// \return A new vector with opposite coordinates
|
|
/////////////////////////////////////////////////////////////////
|
|
Vector<T,N> operator-();
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Overload of the operator +=
|
|
///
|
|
/// \param v Vector by which *this is increased
|
|
///
|
|
/// \return A reference to *this
|
|
///
|
|
/// This operator sums both vectors, and assigns the result to *this
|
|
/////////////////////////////////////////////////////////////////
|
|
Vector<T,N>& operator+=(Vector<T,N> const& v);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Overload of the operator -=
|
|
///
|
|
/// \param v Vector by which *this is decreased
|
|
///
|
|
/// \return A reference to *this
|
|
///
|
|
/// This operator computes difference between the vectors, and assigns
|
|
/// the result to *this
|
|
/////////////////////////////////////////////////////////////////
|
|
Vector<T,N>& operator-=(Vector<T,N> const& v);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Overload of the operator *=
|
|
///
|
|
/// \param f Coefficient by which the vector is multiplied
|
|
///
|
|
/// \return A reference to *this
|
|
///
|
|
/// This operator multiplies each coordinate of *this by f, and returns
|
|
/// a reference to *this
|
|
/////////////////////////////////////////////////////////////////
|
|
Vector<T,N>& operator*=(float f);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Overload of the operator *=
|
|
///
|
|
/// \param f Coefficient by which the vector is divided
|
|
///
|
|
/// \return A reference to *this
|
|
///
|
|
/// This operator divides each coordinate of *this by f, and returns
|
|
/// a reference to *this
|
|
/////////////////////////////////////////////////////////////////
|
|
Vector<T,N>& operator/=(float f);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get x coordinate from the vector
|
|
///
|
|
/// \return A reference to the first coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 0
|
|
/////////////////////////////////////////////////////////////////
|
|
T& x() {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get y coordinate from the vector
|
|
///
|
|
/// \return A reference to the second coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 1
|
|
/////////////////////////////////////////////////////////////////
|
|
T& y() {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get z coordinate from the vector
|
|
///
|
|
/// \return A reference to the third coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 2
|
|
/////////////////////////////////////////////////////////////////
|
|
T& z() {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get t coordinate from the vector
|
|
///
|
|
/// \return A reference to the third coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 3
|
|
/////////////////////////////////////////////////////////////////
|
|
T& t() {static_assert(N > 2, "t() doesn't exist on Vector<T,3>"); return data[3]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get x coordinate from the vector
|
|
///
|
|
/// \return A const reference to the first coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 0
|
|
/////////////////////////////////////////////////////////////////
|
|
T const& x() const {static_assert(N > 0, "x() doesn't exist on Vector<T,0>"); return data[0]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get y coordinate from the vector
|
|
///
|
|
/// \return A const reference to the second coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 1
|
|
/////////////////////////////////////////////////////////////////
|
|
T const& y() const {static_assert(N > 1, "y() doesn't exist on Vector<T,1>"); return data[1]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get z coordinate from the vector
|
|
///
|
|
/// \return A const reference to the third coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 2
|
|
/////////////////////////////////////////////////////////////////
|
|
T const& z() const {static_assert(N > 2, "z() doesn't exist on Vector<T,2>"); return data[2]; };
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \brief Get t coordinate from the vector
|
|
///
|
|
/// \return A const reference to the third coordinate of the vector
|
|
///
|
|
/// This method is available only if the number of coodinates is higher
|
|
/// than 3
|
|
/////////////////////////////////////////////////////////////////
|
|
T const& t() const {static_assert(N > 2, "t() doesn't exist on Vector<T,3>"); return data[3]; };
|
|
|
|
std::array<T,N> data; ///< Array where the coordinates of the vector are stored
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Compares two vectors
|
|
/// \param l first vector
|
|
/// \param r second vector
|
|
/// \return True if each coordinate is the same in l and r
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
bool operator==(Vector<T,N> const& l, Vector<T,N> const& r);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Compares two vectors
|
|
/// \param l first vector
|
|
/// \param r second vector
|
|
/// \return True if at least one coordinate is not the same in l and r
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
bool operator!=(Vector<T,N> const& l, Vector<T,N> const& r);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator +
|
|
/// \param l first vector
|
|
/// \param r second vector
|
|
/// \return The sum of l and r
|
|
///
|
|
/// This operator sums both vectors, and returns the new vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
Vector<T,N> operator+(Vector<T,N> l, Vector<T,N> const& r);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator -
|
|
/// \param l first vector
|
|
/// \param r second vector
|
|
/// \return The difference between l and r
|
|
///
|
|
/// This operator computes the difference between the two vectors, and returns
|
|
/// the new vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
Vector<T,N> operator-(Vector<T,N> l, Vector<T,N> const& r);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator * between two vectors
|
|
///
|
|
/// \param l first Vector
|
|
//
|
|
/// \param r second vector
|
|
///
|
|
/// \return The dot product l and r
|
|
///
|
|
/// This operator computes the sum of the product of the coordinates of the vectors
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T operator*(Vector<T,N> const& l, Vector<T,N> const& r);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Compute the crossProduct between two vectors
|
|
///
|
|
/// \param v1 first Vector
|
|
//
|
|
/// \param v2 second vector
|
|
///
|
|
/// \return The cross product l and r
|
|
///
|
|
/// This function computes the cross product between the two vectors
|
|
/// This function is only available on vector of size 3
|
|
/////////////////////////////////////////////////////////////////
|
|
template <typename T>
|
|
Vector<T,3> crossProduct(Vector<T,3> const& v1, Vector<T,3> const& v2);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator *
|
|
///
|
|
/// \param l Vector to muliply
|
|
//
|
|
/// \param f float by which the Vector is multiplied
|
|
///
|
|
/// \return The product between l and f
|
|
///
|
|
/// This operator computes the product between the vector and the float, and
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
Vector<T,N> operator*(Vector<T,N> l, float f);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator /
|
|
///
|
|
/// \param l Vector to divide
|
|
//
|
|
/// \param f float by which the Vector is divided
|
|
///
|
|
/// \return The result of the division of l by f
|
|
///
|
|
/// This operator computes the division between the vector and the float, and
|
|
/// returns the new vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
Vector<T,N> operator/(Vector<T,N> l, float f);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator>>
|
|
///
|
|
/// \param stream Stream from which the vector is loaded
|
|
//
|
|
/// \param v Vector that will be loaded from the streeam
|
|
///
|
|
/// \return A reference to the stream
|
|
///
|
|
/// Each coordinate will be loaded from the stream in the increasing order
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
std::istream& operator>>(std::istream& stream, Vector<T,N>& v);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Overload of the operator<<
|
|
///
|
|
/// \param stream Stream where the Vector will be printed
|
|
//
|
|
/// \param v Vector that will be printed
|
|
///
|
|
/// \return A reference to the stream
|
|
///
|
|
/// Each coordinate will be printed, separeted by commas and surrounded by brackets
|
|
///
|
|
/// \code
|
|
/// geo::Vector<int,3> v{1,2,3};
|
|
/// std::cout << v << std::endl;
|
|
/// \endcode
|
|
///
|
|
/// will print [1, 2, 3]
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
std::ostream& operator<<(std::ostream& stream, Vector<T,N> const& v);
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the x coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a reference to the x coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T& get_x(Vector<T,N>& v) { return v.x(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the x coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a const reference to the x coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T const& get_x(Vector<T,N> const& v) { return v.x(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the y coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a reference to the y coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T& get_y(Vector<T,N>& v) { return v.y(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the y coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a const reference to the y coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T const& get_y(Vector<T,N> const& v) { return v.y(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the z coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a reference to the z coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T& get_z(Vector<T,N>& v) { return v.z(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Returns the z coordinate of the vector
|
|
/// \param v the vector
|
|
/// \return a const reference to the z coordinate of the vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
T const& get_z(Vector<T,N> const& v) { return v.z(); }
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Specialization of class vector_size
|
|
///
|
|
/// Gives constexpr access to the size of a vector
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T, std::size_t N>
|
|
struct vector_size<Vector<T,N>>
|
|
{
|
|
constexpr static std::size_t value = N; ///< Size of the vector
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 2 coordinates
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T>
|
|
using Vector2 = Vector<T,2>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 3 coordinates
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T>
|
|
using Vector3 = Vector<T,3>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 4 coordinates
|
|
/////////////////////////////////////////////////////////////////
|
|
template<typename T>
|
|
using Vector4 = Vector<T,4>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 2 int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector2i = Vector2<int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 2 unsigned int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector2u = Vector2<unsigned int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 2 float
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector2f = Vector2<float>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 2 double
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector2d = Vector2<double>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 3 int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector3i = Vector3<int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 3 unsigned int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector3u = Vector3<unsigned int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 3 float
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector3f = Vector3<float>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 3 double
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector3d = Vector3<double>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 4 int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector4i = Vector4<int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 4 unsigned int
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector4u = Vector4<unsigned int>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 4 float
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector4f = Vector4<float>;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/// \relates Vector
|
|
/// \brief Smaller name for Vector of 4 double
|
|
/////////////////////////////////////////////////////////////////
|
|
using Vector4d = Vector4<double>;
|
|
|
|
} // namespace geo
|
|
|
|
#include "Vector.inl"
|
|
|
|
#endif // VECTOR_HPP
|