OpenWalnut  1.5.0dev
WMath.cpp
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 #include <memory>
26 
27 #include "../WAssert.h"
28 #include "../WLimits.h"
29 #include "WMath.h"
30 #include "WPlane.h"
31 #include "linearAlgebra/WPosition.h"
32 #include "linearAlgebra/WVectorFixed.h"
33 
34 bool testIntersectTriangle( const WPosition& p1, const WPosition& p2, const WPosition& p3, const WPlane& p )
35 {
36  const WVector3d& normal = p.getNormal();
37  const WPosition& planePoint = p.getPosition();
38 
39  double r1 = dot( normal, p1 - planePoint );
40  double r2 = dot( normal, p2 - planePoint );
41  double r3 = dot( normal, p3 - planePoint );
42 
43  // TODO(math): use signum here!
44  if( std::abs( ( ( r1 > 0 ) - ( r1 < 0 ) ) + ( ( r2 > 0 ) - ( r2 < 0 ) ) + ( ( r3 > 0 ) - ( r3 < 0 ) ) ) == 3 )
45  {
46  return false;
47  }
48  return true;
49 }
50 
51 bool intersectPlaneSegment( const WPlane& p,
52  const WPosition& p1,
53  const WPosition& p2,
54  std::shared_ptr< WPosition > pointOfIntersection )
55 {
56  const WVector3d& normal = normalize( p.getNormal() );
57  double const d = dot( normal, p.getPosition() );
58  WAssert( pointOfIntersection.get(), "Place to store a point of intersection is not ready!" );
59  *pointOfIntersection = p.getPosition(); // otherwise it would be undefined
60 
61  // at least one point is in plane (maybe the whole segment)
62  if( std::abs( dot( normal, p1 - p.getPosition() ) ) <= 2 * wlimits::DBL_EPS )
63  {
64  *pointOfIntersection = p1;
65  return true;
66  }
67  else if( std::abs( dot( normal, p2 - p.getPosition() ) ) <= 2 * wlimits::DBL_EPS )
68  {
69  *pointOfIntersection = p2;
70  return true;
71  }
72 
73  if( std::abs( dot( normal, p1 - p2 ) ) < wlimits::DBL_EPS ) // plane and line are parallel
74  {
75  return false;
76  }
77 
78  double const t = ( d - dot( normal, p2 ) ) / ( dot( normal, p1 - p2 ) );
79 
80  *pointOfIntersection = p2 + t * ( p1 - p2 );
81 
82  if( t >= -wlimits::DBL_EPS && t <= ( 1.0 + wlimits::DBL_EPS ) )
83  {
84  return true;
85  }
86  return false;
87 }
88 
89 bool intersectPlaneLineNearCP( const WPlane& p, const WLine& l, std::shared_ptr< WPosition > cutPoint )
90 {
91  bool result = false;
92  double minDistance = wlimits::MAX_DOUBLE;
93  WAssert( cutPoint.get(), "Place to store a point of intersection is not ready!" );
94  *cutPoint = WPosition( 0, 0, 0 );
95  for( size_t i = 1; i < l.size(); ++i ) // test each segment
96  {
97  std::shared_ptr< WPosition > cP( new WPosition( 0, 0, 0 ) );
98  if( intersectPlaneSegment( p, l[i-1], l[i], cP ) )
99  {
100  result = true;
101  double dist = length2( *cP - p.getPosition() );
102  if( dist < minDistance )
103  {
104  minDistance = dist;
105  *cutPoint = *cP;
106  }
107  }
108  }
109  return result;
110 }
A line is an ordered sequence of WPositions.
Definition: WLine.h:42
size_type size() const
Wrapper around std::vector member function.
Definition: WMixinVector.h:267
Represents a plane with a normal vector and a position in space.
Definition: WPlane.h:39
const WPosition & getPosition() const
Returns a point in that plane.
Definition: WPlane.h:166
const WVector3d & getNormal() const
Returns the normal of the plane.
Definition: WPlane.h:171
This only is a 3d double vector.
const double MAX_DOUBLE
Maximum double value.
Definition: WLimits.cpp:31
const double DBL_EPS
Smallest double such: 1.0 + DBL_EPS == 1.0 is still true.
Definition: WLimits.cpp:46