OpenWalnut  1.4.0
WMath.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WMATH_H
00026 #define WMATH_H
00027 
00028 #include <cmath>
00029 
00030 #include <boost/math/constants/constants.hpp>
00031 
00032 #include "WLine.h"
00033 #include "WPlane.h"
00034 #include "linearAlgebra/WPosition.h"
00035 
00036 /**
00037  * Classes and functions of math module of OpenWalnut.
00038  */
00039 
00040 // Pi constants - we don't use the macro M_PI, because it is not part of the C++-standard.
00041 // ref.: http://stackoverflow.com/questions/1727881/how-to-use-the-pi-constant-in-c
00042 /**
00043  * The pi constant in float format
00044  */
00045 const float piFloat = boost::math::constants::pi<float>();
00046 
00047 /**
00048  * The pi constant in double format
00049  */
00050 const double piDouble = boost::math::constants::pi<double>();
00051 
00052 /**
00053  * Checks if the triangle intersects with the given plane. If you are interested in the points of
00054  * intersection if any \see intersection().
00055  *
00056  * \param p1 first point of the triangle
00057  * \param p2 second point of the triangle
00058  * \param p3 third point of the triangle
00059  * \param p The plane to test with
00060  *
00061  * \return True if both intersects otherwise false.
00062  */
00063 bool testIntersectTriangle( const WPosition& p1, const WPosition& p2, const WPosition& p3, const WPlane& p );
00064 
00065 /**
00066  * Checks if the given segment intersects with the plane or not. Even if
00067  * just one endpoint intersects with the plane it should be returned as
00068  * point of intersection. If the segment is totally inside of that plane
00069  * the first endpoint (which was given: p1 ) should be returned in the
00070  * cutPoint parameter.
00071  *
00072  * \param p The plane to test with intersection
00073  * \param p1 The first endpoint of the line segment
00074  * \param p2 The second endpoint of the line segment
00075  * \param pointOfIntersection The point of intersection if any, otherwise 0,0,0
00076  *
00077  * \return True if an intersection was detected, false otherwise.
00078  */
00079 bool intersectPlaneSegment( const WPlane& p,
00080         const WPosition& p1,
00081         const WPosition& p2,
00082         boost::shared_ptr< WPosition > pointOfIntersection );
00083 
00084 /**
00085  * Checks a line (consecutive line segments) on intersection with a plane
00086  * and selects (if there are more than one point of intersection) the
00087  * closest to the base point of the plane.
00088  *
00089  * \param p The plane to test with intersection
00090  * \param l The line segments
00091  * \param cutPoint The return parameter for the point of intersection
00092  *
00093  * \return True if an intersection was detected, false otherwise.
00094  */
00095 bool intersectPlaneLineNearCP( const WPlane& p, const WLine& l, boost::shared_ptr< WPosition > cutPoint );
00096 
00097 /**
00098  * Computes the signum for the given value.
00099  *
00100  * \tparam Type for which must support operator< 0, and operator> 0
00101  * \param value To compute signum for
00102  *
00103  * \return The signum of the value so that signum( val ) * val == std::abs( val );
00104  */
00105 template< typename T > int signum( const T& value );
00106 
00107 /**
00108  * Calculates the odd factorial. This means 1*3*5* ... * border if border is odd, or 1*3*5* ... * (border-1) if border is even.
00109  * \param border the threshold for the factorial calculation.
00110  */
00111 inline unsigned int oddFactorial( unsigned int border )
00112 {
00113     unsigned int result = 1;
00114     for( unsigned int i = 3; i <= border; i+=2 )
00115     {
00116         result *= i;
00117     }
00118     return result;
00119 }
00120 
00121 /**
00122  * 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.
00123  * \param border the threshold for the factorial calculation.
00124  */
00125 inline unsigned int evenFactorial( unsigned int border )
00126 {
00127     unsigned int result = 1;
00128     for( unsigned int i = 2; i <= border; i+=2 )
00129     {
00130         result *= i;
00131     }
00132     return result;
00133 }
00134 
00135 /**
00136  * Calculates the factorial i! for positive i.
00137  *
00138  * \note For i < 0, the result is undefined.
00139  *
00140  * \tparam The type of i.
00141  * \param i The input.
00142  * \return i!.
00143  */
00144 template< typename T >
00145 T factorial( T i )
00146 {
00147     T res = static_cast< T >( 1 );
00148     if( i < res )
00149     {
00150         return res;
00151     }
00152     for( T k = res; k <= i; ++k )
00153     {
00154         res *= k;
00155     }
00156     return res;
00157 }
00158 
00159 /**
00160  * Checks if two values are equal within a given delta.
00161  *
00162  * \tparam The floating point type.
00163  * \param a The first value.
00164  * \param b The second value.
00165  * \param delta The tolerance parameter.
00166  * \return True if both values are equal within the delta, otherwise false.
00167  */
00168 template< typename T >
00169 T areEqual( T a, T b, T delta = T( 0 ) )
00170 {
00171     return ( std::fabs( a - b ) <= delta );
00172 }
00173 
00174 template< typename T > inline int signum( const T& value )
00175 {
00176     if( value < 0 )
00177     {
00178         return -1;
00179     }
00180     else if( value > 0 )
00181     {
00182         return 1;
00183     }
00184     return 0;
00185 }
00186 
00187 #endif  // WMATH_H