/******************************************************************************* * CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * * version 0.1 * * Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation; either version 2.1 of the License, or (at your * * option) any later version. * * * * This library is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this library; if not, write to the Free Software Foundation, * * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * Web site: https://iggservis.u-strasbg.fr/CGoGN/ * * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ #include namespace CGoGN { namespace Geom { template std::string Vector::CGoGNnameOfType() { std::stringstream ss ; ss << "Geom::Vector<" ; ss << DIM ; ss << "," ; ss << nameOfType(T()) ; ss << ">" ; return ss.str() ; } /**********************************************/ /* CONSTRUCTORS */ /**********************************************/ template Vector::Vector() { CGoGN_STATIC_ASSERT(DIM > 0, invalid_zero_dimensional_Vector) ; zero() ; } template Vector::Vector(const Vector& v) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] = v[i] ; } template Vector::Vector(T x, T y) { CGoGN_STATIC_ASSERT(DIM==2, incompatible_Vector_constructor_dimension) ; m_data[0] = x ; m_data[1] = y ; } template Vector::Vector(T x, T y, T z) { CGoGN_STATIC_ASSERT(DIM==3, incompatible_Vector_constructor_dimension) ; m_data[0] = x ; m_data[1] = y ; m_data[2] = z ; } template Vector::Vector(T x, T y, T z, T w) { CGoGN_STATIC_ASSERT(DIM==4, incompatible_Vector_constructor_dimension) ; m_data[0] = x ; m_data[1] = y ; m_data[2] = z ; m_data[3] = w ; } template Vector::Vector(T x) { set(x) ; } template inline void Vector::set(T a) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] = a ; } template inline void Vector::zero() { set(T(0)) ; } /**********************************************/ /* ACCESSORS */ /**********************************************/ template inline T& Vector::operator[](unsigned int index) { assert(index < DIM) ; return m_data[index] ; } template inline const T& Vector::operator[](unsigned int index) const { assert(index < DIM) ; return m_data[index] ; } template inline unsigned int Vector::dimension() const { return DIM ; } template inline T* Vector::data() { return m_data ; } template inline const T* Vector::data() const { return m_data ; } /**********************************************/ /* ARITHMETIC SELF-OPERATORS */ /**********************************************/ template inline Vector& Vector::operator+=(const Vector& v) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] += v[i] ; return *this ; } template inline Vector& Vector::operator-=(const Vector& v) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] -= v[i] ; return *this ; } template inline Vector Vector::operator*=(T a) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] *= a ; return *this ; } template inline Vector Vector::operator/=(T a) { for(unsigned int i = 0; i < DIM; ++i) m_data[i] /= a ; return *this ; } /**********************************************/ /* ARITHMETIC OPERATORS */ /**********************************************/ template inline Vector Vector::operator+(const Vector& v) const { Vector res ; for(unsigned int i = 0; i < DIM; ++i) res[i] = m_data[i] + v[i] ; return res ; } template inline Vector Vector::operator-(const Vector& v) const { Vector res ; for(unsigned int i = 0; i < DIM; ++i) res[i] = m_data[i] - v[i] ; return res ; } template inline Vector Vector::operator*(T a) const { Vector res ; for(unsigned int i = 0; i < DIM; ++i) res[i] = m_data[i] * a ; return res ; } template inline Vector Vector::operator/(T a) const { Vector res ; for(unsigned int i = 0; i < DIM; ++i) res[i] = m_data[i] / a ; return res ; } /**********************************************/ /* UTILITY FUNCTIONS */ /**********************************************/ template inline T Vector::norm2() const { T n(0) ; for(unsigned int i = 0; i < DIM; ++i) n += m_data[i] * m_data[i] ; return n ; } template inline double Vector::norm() const { return sqrt(norm2()) ; } template inline double Vector::normalize() { double n = norm() ; for(unsigned int i = 0; i < DIM; ++i) m_data[i] /= T(n) ; return n ; } template inline T Vector::operator*(const Vector v) const { T d(0) ; for(unsigned int i = 0; i < DIM; ++i) d += m_data[i] * v[i] ; return d ; } template inline Vector Vector::operator^(const Vector v) const { CGoGN_STATIC_ASSERT(DIM == 3, incompatible_Vector_cross_product_dimension) ; Vector c ; c[0] = m_data[1] * v[2] - m_data[2] * v[1] ; c[1] = m_data[2] * v[0] - m_data[0] * v[2] ; c[2] = m_data[0] * v[1] - m_data[1] * v[0] ; return c ; } template inline bool Vector::operator==(const Vector& v) const { for(unsigned int i = 0 ; i < DIM ; ++i) if(v[i] != m_data[i]) return false ; return true ; } template inline bool Vector::hasNan() const { for(unsigned int i = 0 ; i < DIM ; ++i) if(m_data[i] != m_data[i]) return true ; return false ; } /**********************************************/ /* STREAM OPERATORS */ /**********************************************/ template std::ostream& operator<<(std::ostream& out, const Vector& v) { for(unsigned int i = 0; i < DIM; ++i) out << v[i] << " " ; return out ; } template std::istream& operator>>(std::istream& in, Vector& v) { for(unsigned int i = 0; i < DIM; ++i) in >> v[i] ; return in ; } template inline Vector operator*(T a, const Vector& v) { return v * a ; } template inline Vector operator/(T a, const Vector& v) { return v / a ; } template inline T tripleProduct(const Vector& v1, const Vector& v2, const Vector& v3) { return v1 * (v2 ^ v3) ; } template inline Vector slerp(const Vector &v1, const Vector &v2, const T &t) { Vector res ; T omega = acos(v1 * v2); T den = sin(omega); if (-1e-8 < den || den < 1e-8) return v1; T f1 = sin(( T(1)-t ) * omega ) / den; T f2 = sin( t * omega ) / den; res += f1 * v1; res += f2 * v2; return res ; } } // namespace Geom } // namespace CGoGN