RINGMesh  Version 5.0.0
A programming library for geological model meshes
geometry.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #pragma once
37 
38 #include <array>
39 
40 #include <ringmesh/basic/common.h>
41 
47 namespace RINGMesh
48 {
49  template < index_t DIMENSION >
50  bool operator==( const vecn< DIMENSION >& u, const vecn< DIMENSION >& v )
51  {
52  for( auto i : range( DIMENSION ) )
53  {
54  if( u[i] != v[i] )
55  return false;
56  }
57  return true;
58  }
59 
60  template < index_t DIMENSION >
61  bool operator!=( const vecn< DIMENSION >& u, const vecn< DIMENSION >& v )
62  {
63  return !( u == v );
64  }
65 
66  template < index_t DIMENSION >
68  const vecn< DIMENSION >& v2,
69  double epsilon )
70  {
71  return length( v2 - v1 ) < epsilon;
72  }
73 
74  double RINGMESH_API dot_perp( const vec2& v0, const vec2& v1 );
75 
76  /* @warning Duplicate from Geogram/basic/numeric.h */
77  enum Sign
78  {
79  NEGATIVE = -1,
80  ZERO = 0,
82  };
83  /* @warning Duplicate from Geogram/basic/numeric.h */
84  template < typename T >
85  Sign sign( T x )
86  {
87  return ( x > 0 ) ? POSITIVE : ( ( x < 0 ) ? NEGATIVE : ZERO );
88  }
89 
90  namespace Geometry
91  {
92  template < index_t DIMENSION >
95 
96  template < index_t DIMENSION >
97  struct Segment
98  {
99  Segment() = default;
101  : p0( std::move( p0 ) ), p1( std::move( p1 ) )
102  {
103  }
109  {
110  return normalize( p1 - p0 );
111  }
113  {
114  return ( p1 + p0 ) / 2.;
115  }
116  double length() const
117  {
118  return ( p1 - p0 ).length();
119  }
122  };
124 
125  template < index_t DIMENSION >
126  struct Line
127  {
128  Line() = default;
130  : origin( std::move( origin ) ),
131  direction( normalize( direction ) )
132  {
133  }
134  explicit Line( Segment< DIMENSION > segment )
135  : Line( segment.direction(), std::move( segment.p0 ) )
136  {
137  }
140  };
142 
143  struct Plane
144  {
145  Plane() = default;
146  Plane( const vec3& normal, vec3 origin )
147  : normal( normalize( normal ) ), origin( std::move( origin ) )
148  {
149  }
150  double plane_constant() const
151  {
152  double plane_constant{ 0.0 };
153  for( auto i : range( 3 ) )
154  {
155  plane_constant -= origin[i] * normal[i];
156  }
157  return plane_constant;
158  }
159  vec3 normal{};
160  vec3 origin{};
161  };
162 
163  template < index_t DIMENSION >
164  struct Triangle
165  {
166  Triangle() = default;
169  vecn< DIMENSION > p2 )
170  : p0( std::move( p0 ) ),
171  p1( std::move( p1 ) ),
172  p2( std::move( p2 ) )
173  {
174  }
178  };
179  template <>
180  struct Triangle< 3 >
181  {
182  Triangle() = default;
184  : p0( std::move( p0 ) ),
185  p1( std::move( p1 ) ),
186  p2( std::move( p2 ) )
187  {
188  }
189  Plane plane() const
190  {
191  return { cross( p1 - p0, p2 - p0 ), p0 };
192  }
193  vec3 p0{};
194  vec3 p1{};
195  vec3 p2{};
196  };
198 
199  struct Tetra
200  {
201  Tetra() = default;
202  Tetra( vec3 p0, vec3 p1, vec3 p2, vec3 p3 )
203  : p0( std::move( p0 ) ),
204  p1( std::move( p1 ) ),
205  p2( std::move( p2 ) ),
206  p3( std::move( p3 ) )
207  {
208  }
209  vec3 p0{};
210  vec3 p1{};
211  vec3 p2{};
212  vec3 p3{};
213  };
214 
215  struct Sphere
216  {
217  Sphere() = default;
218  Sphere( vec3 origin, double radius )
219  : origin( std::move( origin ) ), radius( std::move( radius ) )
220  {
221  }
222  vec3 origin{};
223  double radius{ 0 };
224  };
225 
226  using Ball = Sphere;
227 
228  struct Circle
229  {
230  Circle() = default;
231  Circle( Plane plane, double radius )
232  : plane( std::move( plane ) ), radius( std::move( radius ) )
233  {
234  }
236  double radius{ 0 };
237  };
238 
239  using Disk = Circle;
240  } // namespace Geometry
241 
242  namespace Distance
243  {
250  template < index_t DIMENSION >
251  std::tuple< double, vecn< DIMENSION > > point_to_segment(
252  const Geometry::Point< DIMENSION >& point,
253  const Geometry::Segment< DIMENSION >& segment );
254 
261  template < index_t DIMENSION >
262  std::tuple< double, vecn< DIMENSION > > point_to_triangle(
263  const Geometry::Point< DIMENSION >& point,
264  const Geometry::Triangle< DIMENSION >& triangle );
265 
272  std::tuple< double, vec3 > RINGMESH_API point_to_tetra(
273  const Geometry::Point3D& point, const Geometry::Tetra& tetra );
280  std::tuple< double, vec3 > RINGMESH_API point_to_plane(
281  const Geometry::Point3D& point, const Geometry::Plane& plane );
282  } // namespace Distance
283 
284  namespace Intersection
285  {
292  std::tuple< bool, vec3 > RINGMESH_API line_plane(
293  const Geometry::Line3D& line, const Geometry::Plane& plane );
294 
301  std::tuple< bool, std::vector< vec3 > > RINGMESH_API line_sphere(
302  const Geometry::Line3D& line, const Geometry::Sphere& sphere );
303 
310  std::tuple< bool, std::vector< vec3 > > RINGMESH_API segment_sphere(
311  const Geometry::Segment3D& segment,
312  const Geometry::Sphere& sphere );
313 
320  std::tuple< bool, vec3 > RINGMESH_API segment_plane(
321  const Geometry::Segment3D& segment, const Geometry::Plane& plane );
322 
329  std::tuple< bool, vec3 > RINGMESH_API segment_triangle(
330  const Geometry::Segment3D& segment,
331  const Geometry::Triangle3D& triangle );
332 
339  std::tuple< bool, std::vector< vec3 > > RINGMESH_API circle_plane(
340  const Geometry::Circle& circle, const Geometry::Plane& plane );
341 
348  std::tuple< bool, vec3 > RINGMESH_API segment_disk(
349  const Geometry::Segment3D& segment, const Geometry::Disk& disk );
350 
357  std::tuple< bool, std::vector< vec3 > > RINGMESH_API triangle_circle(
358  const Geometry::Triangle3D& triangle,
359  const Geometry::Circle& circle );
360 
367  std::tuple< bool, Geometry::Line3D > RINGMESH_API plane_plane(
368  const Geometry::Plane& plane0, const Geometry::Plane& plane1 );
369 
376  std::tuple< bool, vec2 > RINGMESH_API line_line(
377  const Geometry::Line2D& line0, const Geometry::Line2D& line1 );
378 
385  std::tuple< bool, vec2 > RINGMESH_API segment_segment(
386  const Geometry::Segment2D& segment0,
387  const Geometry::Segment2D& segment1 );
388 
395  std::tuple< bool, vec2 > RINGMESH_API segment_line(
396  const Geometry::Segment2D& segment, const Geometry::Line2D& line );
397  } // namespace Intersection
398 
399  namespace Position
400  {
405  bool RINGMESH_API point_inside_segment( const Geometry::Point3D& point,
406  const Geometry::Segment3D& segment );
407 
413  template < index_t DIMENSION >
415  const Geometry::Triangle< DIMENSION >& triangle );
416 
421  bool RINGMESH_API point_inside_tetra(
422  const Geometry::Point3D& point, const Geometry::Tetra& tetra );
423 
427  Sign RINGMESH_API point_side_to_segment( const Geometry::Point2D& point,
428  const Geometry::Segment2D& segment );
429 
433  Sign RINGMESH_API point_side_to_plane(
434  const Geometry::Point3D& point, const Geometry::Plane& plane );
435 
436  } // namespace Position
437 
438  double RINGMESH_API triangle_signed_area( const vec3& p0,
439  const vec3& p1,
440  const vec3& p2,
441  const vec3& triangle_normal );
442 
452  template < index_t DIMENSION >
453  std::tuple< bool, vecn< DIMENSION > > point_segment_projection(
454  const vecn< DIMENSION >& p,
455  const vecn< DIMENSION >& p0,
456  const vecn< DIMENSION >& p1 );
457 
470  std::tuple< bool, std::array< double, 4 > >
471  RINGMESH_API tetra_barycentric_coordinates( const vec3& p,
472  const vec3& p0,
473  const vec3& p1,
474  const vec3& p2,
475  const vec3& p3 );
476 
488  std::tuple< bool, std::array< double, 3 > >
490  const vec3& p, const vec3& p0, const vec3& p1, const vec3& p2 );
491 
503  std::tuple< bool, std::array< double, 3 > >
505  const vec2& p, const vec2& p0, const vec2& p1, const vec2& p2 );
506 
522  GEO::Matrix< 4, double > RINGMESH_API rotation_matrix_about_arbitrary_axis(
523  const vec3& origin, const vec3& axis, double theta, bool degrees );
524 
525 } // namespace RINGMesh
std::tuple< bool, vecn< DIMENSION > > point_segment_projection(const vecn< DIMENSION > &p, const vecn< DIMENSION > &p0, const vecn< DIMENSION > &p1)
Definition: geometry.cpp:161
GEO::vecng< DIMENSION, double > vecn
Definition: types.h:74
std::tuple< double, vec3 > RINGMESH_API point_to_tetra(const Geometry::Point3D &point, const Geometry::Tetra &tetra)
Plane(const vec3 &normal, vec3 origin)
Definition: geometry.h:146
std::tuple< double, vecn< DIMENSION > > point_to_triangle(const Geometry::Point< DIMENSION > &point, const Geometry::Triangle< DIMENSION > &triangle)
vecn< 3 > vec3
Definition: types.h:76
Line(Segment< DIMENSION > segment)
Definition: geometry.h:134
Sphere(vec3 origin, double radius)
Definition: geometry.h:218
double RINGMESH_API triangle_signed_area(const vec3 &p0, const vec3 &p1, const vec3 &p2, const vec3 &triangle_normal)
Definition: geometry.cpp:66
double RINGMESH_API dot_perp(const vec2 &v0, const vec2 &v1)
Definition: geometry.cpp:61
bool RINGMESH_API point_inside_segment(const Geometry::Point3D &point, const Geometry::Segment3D &segment)
Tests if a point is on a segment.
Tetra(vec3 p0, vec3 p1, vec3 p2, vec3 p3)
Definition: geometry.h:202
std::tuple< bool, std::array< double, 4 > > RINGMESH_API tetra_barycentric_coordinates(const vec3 &p, const vec3 &p0, const vec3 &p1, const vec3 &p2, const vec3 &p3)
Definition: geometry.cpp:90
bool operator==(const vecn< DIMENSION > &u, const vecn< DIMENSION > &v)
Definition: geometry.h:50
bool operator!=(const vecn< DIMENSION > &u, const vecn< DIMENSION > &v)
Definition: geometry.h:61
std::tuple< bool, std::array< double, 3 > > RINGMESH_API triangle_barycentric_coordinates(const vec3 &p, const vec3 &p0, const vec3 &p1, const vec3 &p2)
Definition: geometry.cpp:118
Triangle(vecn< DIMENSION > p0, vecn< DIMENSION > p1, vecn< DIMENSION > p2)
Definition: geometry.h:167
std::tuple< bool, vec3 > RINGMESH_API segment_disk(const Geometry::Segment3D &segment, const Geometry::Disk &disk)
std::tuple< bool, vec2 > RINGMESH_API segment_line(const Geometry::Segment2D &segment, const Geometry::Line2D &line)
vecn< 2 > vec2
Definition: types.h:78
std::tuple< bool, Geometry::Line3D > RINGMESH_API plane_plane(const Geometry::Plane &plane0, const Geometry::Plane &plane1)
GEO::Matrix< 4, double > RINGMESH_API rotation_matrix_about_arbitrary_axis(const vec3 &origin, const vec3 &axis, double theta, bool degrees)
Builds a rotational matrix about an arbitrary axis.
Definition: geometry.cpp:202
Line(const vecn< DIMENSION > &direction, vecn< DIMENSION > origin)
Definition: geometry.h:129
std::tuple< bool, std::vector< vec3 > > RINGMESH_API line_sphere(const Geometry::Line3D &line, const Geometry::Sphere &sphere)
Triangle(vec3 p0, vec3 p1, vec3 p2)
Definition: geometry.h:183
Sign RINGMESH_API point_side_to_segment(const Geometry::Point2D &point, const Geometry::Segment2D &segment)
std::tuple< bool, std::vector< vec3 > > RINGMESH_API triangle_circle(const Geometry::Triangle3D &triangle, const Geometry::Circle &circle)
std::tuple< double, vec3 > RINGMESH_API point_to_plane(const Geometry::Point3D &point, const Geometry::Plane &plane)
Sign RINGMESH_API point_side_to_plane(const Geometry::Point3D &point, const Geometry::Plane &plane)
std::tuple< bool, vec3 > RINGMESH_API segment_plane(const Geometry::Segment3D &segment, const Geometry::Plane &plane)
double length() const
Definition: geometry.h:116
vecn< DIMENSION > direction() const
Definition: geometry.h:108
std::tuple< bool, std::vector< vec3 > > RINGMESH_API segment_sphere(const Geometry::Segment3D &segment, const Geometry::Sphere &sphere)
std::tuple< bool, vec3 > RINGMESH_API segment_triangle(const Geometry::Segment3D &segment, const Geometry::Triangle3D &triangle)
double plane_constant() const
Definition: geometry.h:150
bool point_inside_triangle(const Geometry::Point< DIMENSION > &point, const Geometry::Triangle< DIMENSION > &triangle)
Tests if a point is inside a triangle.
Sign sign(T x)
Definition: geometry.h:85
std::tuple< bool, vec2 > RINGMESH_API line_line(const Geometry::Line2D &line0, const Geometry::Line2D &line1)
std::tuple< bool, vec2 > RINGMESH_API segment_segment(const Geometry::Segment2D &segment0, const Geometry::Segment2D &segment1)
vecn< DIMENSION > barycenter() const
Definition: geometry.h:112
Circle(Plane plane, double radius)
Definition: geometry.h:231
vecn< DIMENSION > p0
Definition: geometry.h:120
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
vecn< DIMENSION > p1
Definition: geometry.h:121
std::tuple< bool, vec3 > RINGMESH_API line_plane(const Geometry::Line3D &line, const Geometry::Plane &plane)
Segment(vecn< DIMENSION > p0, vecn< DIMENSION > p1)
Definition: geometry.h:100
std::tuple< bool, std::vector< vec3 > > RINGMESH_API circle_plane(const Geometry::Circle &circle, const Geometry::Plane &plane)
vecn< DIMENSION > Point
Definition: geometry.h:93
bool RINGMESH_API point_inside_tetra(const Geometry::Point3D &point, const Geometry::Tetra &tetra)
bool inexact_equal(const vecn< DIMENSION > &v1, const vecn< DIMENSION > &v2, double epsilon)
Definition: geometry.h:67
std::tuple< double, vecn< DIMENSION > > point_to_segment(const Geometry::Point< DIMENSION > &point, const Geometry::Segment< DIMENSION > &segment)