/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef VECTOR3_H_ #define VECTOR3_H_ #include #include /** * Traits class for VECTOR2. */ template struct VECTOR3_TRAITS { ///< extended range/precision types used by operations involving multiple ///< multiplications to prevent overflow. typedef T extended_type; }; template <> struct VECTOR3_TRAITS { typedef int64_t extended_type; }; /** * Define a general 3D-vector. * * This class uses templates to be universal. Several operators are provided to help * easy implementing of linear algebra equations. * */ template class VECTOR3 { public: typedef typename VECTOR3_TRAITS::extended_type extended_type; typedef T coord_type; static constexpr extended_type ECOORD_MAX = std::numeric_limits::max(); static constexpr extended_type ECOORD_MIN = std::numeric_limits::min(); T x{}; T y{}; T z{}; /// Construct a 3D-vector with x, y, z = 0 VECTOR3() = default; /// Construct a vector with given components x, y, z VECTOR3( T x, T y, T z ); /// Initializes a vector from another specialization. Beware of rounding /// issues. template VECTOR3( const VECTOR3& aVec ); /** * Compute cross product of self with \a aVector */ VECTOR3 Cross( const VECTOR3& aVector ) const; /** * Compute the dot product of self with \a aVector */ VECTOR3::extended_type Dot( const VECTOR3& aVector ) const; /** * Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2). * * It is used to calculate the length of the vector. * * @return Scalar, the euclidean norm */ T EuclideanNorm() const; /** * Compute the normalized vector. */ VECTOR3 Normalize(); ///< Equality operator bool operator==( const VECTOR3& aVector ) const; ///< Not equality operator bool operator!=( const VECTOR3& aVector ) const; }; template VECTOR3::VECTOR3( T aX, T aY, T aZ ) : x( aX ), y( aY ), z( aZ ) { } template template VECTOR3::VECTOR3( const VECTOR3& aVec ) : x( aVec.x ), y( aVec.y ), z( aVec.z ) { } template VECTOR3 VECTOR3::Cross( const VECTOR3& aVector ) const { return VECTOR3( ( y * aVector.z ) - ( z * aVector.y ), ( z * aVector.x ) - ( x * aVector.z ), ( x * aVector.y ) - ( y * aVector.x ) ); } template typename VECTOR3::extended_type VECTOR3::Dot( const VECTOR3& aVector ) const { return extended_type{x} * extended_type{aVector.x} + extended_type{y} * extended_type{aVector.y} + extended_type{z} * extended_type{aVector.z}; } template T VECTOR3::EuclideanNorm() const { return sqrt( (extended_type) x * x + (extended_type) y * y + (extended_type) z * z ); } template VECTOR3 VECTOR3::Normalize() { T norm = EuclideanNorm(); wxCHECK_MSG( norm > T( 0 ), *this, wxT( "Invalid element length 0" ) ); x /= norm; y /= norm; z /= norm; return *this; } template bool VECTOR3::operator==( VECTOR3 const& aVector ) const { return ( aVector.x == x ) && ( aVector.y == y ) && ( aVector.z == z ); } template bool VECTOR3::operator!=( VECTOR3 const& aVector ) const { return ( aVector.x != x ) || ( aVector.y != y ) || ( aVector.z != z ); } /* Default specializations */ typedef VECTOR3 VECTOR3D; typedef VECTOR3 VECTOR3I; typedef VECTOR3 VECTOR3U; #endif // VECTOR3_H_