WMath.h 6.06 KB
Newer Older
1 2
//---------------------------------------------------------------------------
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
4
//
5 6
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
//
// 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 <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#ifndef WMATH_H
#define WMATH_H

28 29
#include <cmath>

30 31
#include <boost/math/constants/constants.hpp>

Mathias Goldau's avatar
Mathias Goldau committed
32 33
#include "WLine.h"
#include "WPlane.h"
34
#include "linearAlgebra/WPosition.h"
35

36
/**
37
 * Classes and functions of math module of OpenWalnut.
38
 */
Mathias Goldau's avatar
Mathias Goldau committed
39 40

/**
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
 * 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.
Mathias Goldau's avatar
Mathias Goldau committed
60
 */
61
#define piDouble pi( double() )
Mathias Goldau's avatar
Mathias Goldau committed
62 63

/**
64 65
 * 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.
Mathias Goldau's avatar
Mathias Goldau committed
66
 */
67
#define piFloat pi( float() )
Mathias Goldau's avatar
Mathias Goldau committed
68 69 70 71 72 73 74 75 76 77 78 79

/**
 * 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.
 */
80
bool testIntersectTriangle( const WPosition& p1, const WPosition& p2, const WPosition& p3, const WPlane& p );
Mathias Goldau's avatar
Mathias Goldau committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

/**
 * 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.
 */
96
bool intersectPlaneSegment( const WPlane& p,
97 98 99
        const WPosition& p1,
        const WPosition& p2,
        boost::shared_ptr< WPosition > pointOfIntersection );
Mathias Goldau's avatar
Mathias Goldau committed
100 101 102 103 104 105 106 107 108 109 110 111

/**
 * 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.
 */
112
bool intersectPlaneLineNearCP( const WPlane& p, const WLine& l, boost::shared_ptr< WPosition > cutPoint );
Mathias Goldau's avatar
Mathias Goldau committed
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

/**
 * 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.
 */
128
inline unsigned int oddFactorial( unsigned int border )
Mathias Goldau's avatar
Mathias Goldau committed
129 130
{
    unsigned int result = 1;
131
    for( unsigned int i = 3; i <= border; i+=2 )
132
    {
Mathias Goldau's avatar
Mathias Goldau committed
133
        result *= i;
134
    }
Mathias Goldau's avatar
Mathias Goldau committed
135 136
    return result;
}
137

Mathias Goldau's avatar
Mathias Goldau committed
138 139 140 141
/**
 * 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.
 */
142
inline unsigned int evenFactorial( unsigned int border )
Mathias Goldau's avatar
Mathias Goldau committed
143 144
{
    unsigned int result = 1;
145
    for( unsigned int i = 2; i <= border; i+=2 )
146
    {
Mathias Goldau's avatar
Mathias Goldau committed
147
        result *= i;
148
    }
Mathias Goldau's avatar
Mathias Goldau committed
149 150
    return result;
}
151

Mathias Goldau's avatar
Mathias Goldau committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165
/**
 * 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 )
166 167 168
    {
        return res;
    }
Mathias Goldau's avatar
Mathias Goldau committed
169 170 171 172 173
    for( T k = res; k <= i; ++k )
    {
        res *= k;
    }
    return res;
174 175
}

Stefan Philips's avatar
Stefan Philips committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
/**
 * 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 );
}

Mathias Goldau's avatar
Mathias Goldau committed
191
template< typename T > inline int signum( const T& value )
192
{
193 194 195 196 197 198 199 200 201
    if( value < 0 )
    {
        return -1;
    }
    else if( value > 0 )
    {
        return 1;
    }
    return 0;
202 203 204
}

#endif  // WMATH_H