//--------------------------------------------------------------------------- // // Project: OpenWalnut ( http://www.openwalnut.org ) // // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS // For more information see http://www.openwalnut.org/copying // // This file is part of OpenWalnut. // // OpenWalnut 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 3 of the License, or // (at your option) any later version. // // OpenWalnut 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 OpenWalnut. If not, see . // //--------------------------------------------------------------------------- #ifndef WMATH_H #define WMATH_H #include #include #include "WLine.h" #include "WPlane.h" #include "linearAlgebra/WPosition.h" /** * Classes and functions of math module of OpenWalnut. */ /** * Get a PI constant in an arbitrary type. * * \tparam T the desired type * \param T the parameter is only needed for deducing T. This is needed since C++ < C++11 does not allow default template types in function templates. * You need to set this parameter to an example value of the desired type T for pi. Usually, the default constructor will do well. * * \example pi( int() ) will return 3. * * \return pi in the desired type. */ template< typename T > T pi( T = double() ) { return boost::math::constants::pi< T >(); } /** * For the lazy programmer and backwards compatibility, define piDouble to be PI as double. Since defines are usually a bad idea (for aliasing), you * should avoid using this. Use the \ref pi function directly. */ #define piDouble pi( double() ) /** * For the lazy programmer and backwards compatibility, define piFloat to be PI as float. Since defines are usually a bad idea (for aliasing), you * should avoid using this. Use the \ref pi function directly. */ #define piFloat pi( float() ) /** * Checks if the triangle intersects with the given plane. If you are interested in the points of * intersection if any \see intersection(). * * \param p1 first point of the triangle * \param p2 second point of the triangle * \param p3 third point of the triangle * \param p The plane to test with * * \return True if both intersects otherwise false. */ bool testIntersectTriangle( const WPosition& p1, const WPosition& p2, const WPosition& p3, const WPlane& p ); /** * Checks if the given segment intersects with the plane or not. Even if * just one endpoint intersects with the plane it should be returned as * point of intersection. If the segment is totally inside of that plane * the first endpoint (which was given: p1 ) should be returned in the * cutPoint parameter. * * \param p The plane to test with intersection * \param p1 The first endpoint of the line segment * \param p2 The second endpoint of the line segment * \param pointOfIntersection The point of intersection if any, otherwise 0,0,0 * * \return True if an intersection was detected, false otherwise. */ bool intersectPlaneSegment( const WPlane& p, const WPosition& p1, const WPosition& p2, boost::shared_ptr< WPosition > pointOfIntersection ); /** * Checks a line (consecutive line segments) on intersection with a plane * and selects (if there are more than one point of intersection) the * closest to the base point of the plane. * * \param p The plane to test with intersection * \param l The line segments * \param cutPoint The return parameter for the point of intersection * * \return True if an intersection was detected, false otherwise. */ bool intersectPlaneLineNearCP( const WPlane& p, const WLine& l, boost::shared_ptr< WPosition > cutPoint ); /** * Computes the signum for the given value. * * \tparam Type for which must support operator< 0, and operator> 0 * \param value To compute signum for * * \return The signum of the value so that signum( val ) * val == std::abs( val ); */ template< typename T > int signum( const T& value ); /** * Calculates the odd factorial. This means 1*3*5* ... * border if border is odd, or 1*3*5* ... * (border-1) if border is even. * \param border the threshold for the factorial calculation. */ inline unsigned int oddFactorial( unsigned int border ) { unsigned int result = 1; for( unsigned int i = 3; i <= border; i+=2 ) { result *= i; } return result; } /** * Calculates the even factorial. This means 2*4*6 ... * \param border if border is even, or 2*4*6* ... * ( \param border - 1 ) if border is odd. * \param border the threshold for the factorial calculation. */ inline unsigned int evenFactorial( unsigned int border ) { unsigned int result = 1; for( unsigned int i = 2; i <= border; i+=2 ) { result *= i; } return result; } /** * Calculates the factorial i! for positive i. * * \note For i < 0, the result is undefined. * * \tparam The type of i. * \param i The input. * \return i!. */ template< typename T > T factorial( T i ) { T res = static_cast< T >( 1 ); if( i < res ) { return res; } for( T k = res; k <= i; ++k ) { res *= k; } return res; } /** * Checks if two values are equal within a given delta. * * \tparam The floating point type. * \param a The first value. * \param b The second value. * \param delta The tolerance parameter. * \return True if both values are equal within the delta, otherwise false. */ template< typename T > T areEqual( T a, T b, T delta = T( 0 ) ) { return ( std::fabs( a - b ) <= delta ); } template< typename T > inline int signum( const T& value ) { if( value < 0 ) { return -1; } else if( value > 0 ) { return 1; } return 0; } #endif // WMATH_H