OpenWalnut  1.5.0dev
WMath.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WMATH_H
26 #define WMATH_H
27 
28 #include <cmath>
29 #include <memory>
30 
31 #include <boost/math/constants/constants.hpp>
32 
33 #include "WLine.h"
34 #include "WPlane.h"
35 #include "linearAlgebra/WPosition.h"
36 
37 /**
38  * Classes and functions of math module of OpenWalnut.
39  */
40 
41 /**
42  * Get a PI constant in an arbitrary type.
43  *
44  * \tparam T the desired type
45  *
46  * \return pi in the desired type.
47  */
48 template< typename T >
49 T pi()
50 {
51  return boost::math::constants::pi< T >();
52 }
53 
54 /**
55  * Get a PI constant as double.
56  *
57  * \return pi as double.
58  */
59 inline double pi()
60 {
61  return boost::math::constants::pi< double >();
62 }
63 
64 /**
65  * For the lazy programmer and backwards compatibility, define pi() to be PI as double. Since defines are usually a bad idea (for aliasing), you
66  * should avoid using this. Use the \ref pi function directly.
67  */
68 #define piDouble pi()
69 
70 /**
71  * For the lazy programmer and backwards compatibility, define piFloat to be PI as float. Since defines are usually a bad idea (for aliasing), you
72  * should avoid using this. Use the \ref pi function directly.
73  */
74 #define piFloat pi< float >()
75 
76 /**
77  * Checks if the triangle intersects with the given plane. If you are interested in the points of
78  * intersection if any \see intersection().
79  *
80  * \param p1 first point of the triangle
81  * \param p2 second point of the triangle
82  * \param p3 third point of the triangle
83  * \param p The plane to test with
84  *
85  * \return True if both intersects otherwise false.
86  */
87 bool testIntersectTriangle( const WPosition& p1, const WPosition& p2, const WPosition& p3, const WPlane& p );
88 
89 /**
90  * Checks if the given segment intersects with the plane or not. Even if
91  * just one endpoint intersects with the plane it should be returned as
92  * point of intersection. If the segment is totally inside of that plane
93  * the first endpoint (which was given: p1 ) should be returned in the
94  * cutPoint parameter.
95  *
96  * \param p The plane to test with intersection
97  * \param p1 The first endpoint of the line segment
98  * \param p2 The second endpoint of the line segment
99  * \param pointOfIntersection The point of intersection if any, otherwise 0,0,0
100  *
101  * \return True if an intersection was detected, false otherwise.
102  */
103 bool intersectPlaneSegment( const WPlane& p,
104  const WPosition& p1,
105  const WPosition& p2,
106  std::shared_ptr< WPosition > pointOfIntersection );
107 
108 /**
109  * Checks a line (consecutive line segments) on intersection with a plane
110  * and selects (if there are more than one point of intersection) the
111  * closest to the base point of the plane.
112  *
113  * \param p The plane to test with intersection
114  * \param l The line segments
115  * \param cutPoint The return parameter for the point of intersection
116  *
117  * \return True if an intersection was detected, false otherwise.
118  */
119 bool intersectPlaneLineNearCP( const WPlane& p, const WLine& l, std::shared_ptr< WPosition > cutPoint );
120 
121 /**
122  * Computes the signum for the given value.
123  *
124  * \tparam Type for which must support operator< 0, and operator> 0
125  * \param value To compute signum for
126  *
127  * \return The signum of the value so that signum( val ) * val == std::abs( val );
128  */
129 template< typename T > int signum( const T& value );
130 
131 /**
132  * Calculates the odd factorial. This means 1*3*5* ... * border if border is odd, or 1*3*5* ... * (border-1) if border is even.
133  * \param border the threshold for the factorial calculation.
134  */
135 inline unsigned int oddFactorial( unsigned int border )
136 {
137  unsigned int result = 1;
138  for( unsigned int i = 3; i <= border; i+=2 )
139  {
140  result *= i;
141  }
142  return result;
143 }
144 
145 /**
146  * 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.
147  * \param border the threshold for the factorial calculation.
148  */
149 inline unsigned int evenFactorial( unsigned int border )
150 {
151  unsigned int result = 1;
152  for( unsigned int i = 2; i <= border; i+=2 )
153  {
154  result *= i;
155  }
156  return result;
157 }
158 
159 /**
160  * Calculates the factorial i! for positive i.
161  *
162  * \note For i < 0, the result is undefined.
163  *
164  * \tparam The type of i.
165  * \param i The input.
166  * \return i!.
167  */
168 template< typename T >
169 T factorial( T i )
170 {
171  T res = static_cast< T >( 1 );
172  if( i < res )
173  {
174  return res;
175  }
176  for( T k = res; k <= i; ++k )
177  {
178  res *= k;
179  }
180  return res;
181 }
182 
183 /**
184  * Checks if two values are equal within a given delta.
185  *
186  * \tparam The floating point type.
187  * \param a The first value.
188  * \param b The second value.
189  * \param delta The tolerance parameter.
190  * \return True if both values are equal within the delta, otherwise false.
191  */
192 template< typename T >
193 T areEqual( T a, T b, T delta = T( 0 ) )
194 {
195  return ( std::fabs( a - b ) <= delta );
196 }
197 
198 template< typename T > inline int signum( const T& value )
199 {
200  if( value < 0 )
201  {
202  return -1;
203  }
204  else if( value > 0 )
205  {
206  return 1;
207  }
208  return 0;
209 }
210 
211 #endif // WMATH_H
A line is an ordered sequence of WPositions.
Definition: WLine.h:42
Represents a plane with a normal vector and a position in space.
Definition: WPlane.h:39
This only is a 3d double vector.