Free Electron
PointTriangleNearest.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __geometry_PointTriangleNearest_h__
8 #define __geometry_PointTriangleNearest_h__
9 
10 #define FE_PTN_DEBUG FALSE
11 
12 namespace fe
13 {
14 namespace ext
15 {
16 
17 /**************************************************************************//**
18  @brief Find point nearest to a triangle
19 
20  @ingroup geometry
21 *//***************************************************************************/
22 template <typename T>
24 {
25  public:
26 static T solve(const Vector<3,T>& vert0,
27  const Vector<3,T>& vert1,
28  const Vector<3,T>& vert2,
29  const Vector<3,T>& origin,
30  Vector<3,T>& direction,
31  Vector<3,T>& intersection,
32  Barycenter<T>& barycenter);
33 
34 };
35 
36 template <typename T>
37 inline T PointTriangleNearest<T>::solve(const Vector<3,T>& vert0,
38  const Vector<3,T>& vert1,
39  const Vector<3,T>& vert2,
40  const Vector<3,T>& origin,
41  Vector<3,T>& direction,
42  Vector<3,T>& intersection,
43  Barycenter<T>& barycenter)
44 {
45 #if FE_PTN_DEBUG
46  feLog("\nPointTriangleNearest<T>\n");
47  feLog("vert0 %s\n",c_print(vert0));
48  feLog("vert1 %s\n",c_print(vert1));
49  feLog("vert2 %s\n",c_print(vert2));
50  feLog("origin %s\n",c_print(origin));
51 #endif
52  const Vector<3,T> perp=cross(vert1-vert0,vert2-vert0);
53  if(magnitudeSquared(perp)<fe::tol*fe::tol)
54  {
55 #if FE_PTN_DEBUG
56  feLog("cross mag %.6G below tolerance %.6G\n",magnitude(perp),fe::tol);
57 #endif
58  return T(-1);
59  }
60  const Vector<3,T> normal=unit(cross(vert1-vert0,vert2-vert0));
61  const Vector<3,T> to_origin=origin-vert0;
62  const T displacement=dot(normal,to_origin);
63  intersection=origin-normal*displacement;
64 
65  barycenter.solve(vert0,vert1,vert2,intersection);
66 
67 #if FE_PTN_DEBUG
68  feLog("normal %s\n",c_print(normal));
69  feLog("intersection %s\n",c_print(intersection));
70  feLog("barycenter %s\n",c_print(barycenter));
71 #endif
72 
73  //* clamp to triangle
74  barycenter.clamp(vert0,vert1,vert2);
75 
76  intersection=location(barycenter,vert0,vert1,vert2);
77 
78  direction=intersection-origin;
79  T range=magnitude(direction);
80  if(range>T(0))
81  {
82  direction*=T(1)/range;
83  }
84 
85 #if FE_PTN_DEBUG
86  feLog("intersection %s\n",c_print(intersection));
87  feLog("direction %s\n",c_print(direction));
88  feLog("barycenter %s\n",c_print(barycenter));
89  feLog("range %.6G\n",range);
90 #endif
91 
92  return range;
93 }
94 
95 } /* namespace ext */
96 } /* namespace fe */
97 
98 #endif /* __geometry_PointTriangleNearest_h__ */
99 
100 
101 
kernel
Definition: namespace.dox:3
Barycentric coordinates for a triangle.
Definition: Barycenter.h:26
Find point nearest to a triangle.
Definition: PointTriangleNearest.h:23