paella/Code/include/Geometry/Vector.hpp

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