MeshLib Documentation
Loading...
Searching...
No Matches
MRClosestPointInTriangle.h
Go to the documentation of this file.
1// ======================================================================== //
2// Copyright 2009-2020 Intel Corporation //
3// //
4// Licensed under the Apache License, Version 2.0 (the "License"); //
5// you may not use this file except in compliance with the License. //
6// You may obtain a copy of the License at //
7// //
8// http://www.apache.org/licenses/LICENSE-2.0 //
9// //
10// Unless required by applicable law or agreed to in writing, software //
11// distributed under the License is distributed on an "AS IS" BASIS, //
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
13// See the License for the specific language governing permissions and //
14// limitations under the License. //
15// ======================================================================== //
16#pragma once
17
18#include "MRVector3.h"
19#include "MRTriPoint.h"
20
21namespace MR
22{
23
24template <typename T>
25static std::pair<Vector3<T>, TriPoint<T>> closestPointInTriangle( const Vector3<T>& p, const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& c )
26{
27 // https://stackoverflow.com/a/74395029/7325599
28 const Vector3<T> ab = b - a;
29 const Vector3<T> ac = c - a;
30 const Vector3<T> ap = p - a;
31
32 const T d1 = dot( ab, ap );
33 const T d2 = dot( ac, ap );
34 if ( d1 <= 0 && d2 <= 0 )
35 return { a, { 0, 0 } }; //#1
36
37 const Vector3<T> bp = p - b;
38 const T d3 = dot( ab, bp );
39 const T d4 = dot( ac, bp );
40 if ( d3 >= 0 && d4 <= d3 )
41 return { b, { 1, 0 } }; //#2
42
43 const Vector3<T> cp = p - c;
44 const T d5 = dot( ab, cp );
45 const T d6 = dot( ac, cp );
46 if ( d6 >= 0 && d5 <= d6 )
47 return { c, { 0, 1 } }; //#3
48
49 const T vc = d1 * d4 - d3 * d2;
50 if ( vc <= 0 && d1 >= 0 && d3 <= 0 )
51 {
52 const T v = d1 / ( d1 - d3 );
53 return { a + v * ab, { v, 0 } }; //#4
54 }
55
56 const T vb = d5 * d2 - d1 * d6;
57 if ( vb <= 0 && d6 <= 0 )
58 {
59 assert( d2 >= 0 );
60 const T v = d2 / ( d2 - d6 );
61 return { a + v * ac, { 0, v } }; //#5
62 }
63
64 const T va = d3 * d6 - d5 * d4;
65 if ( va <= 0 )
66 {
67 // d4-d3 = dot(bc,bp) >= 0 in #6
68 if ( d4 < d3 ) // floating-point rounding errors
69 return { b, { 1, 0 } }; //#2
70
71 // d5-d6 = dot(cb,cp) >= 0 in #6
72 if ( d5 < d6 ) // floating-point rounding errors
73 return { c, { 0, 1 } }; //#3
74
75 // ( d4 - d3 ) + ( d5 - d6 ) = bc^2 >= 0
76 const T v = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );
77 return { b + v * ( c - b ), { 1 - v, v } }; //#6
78 }
79
80 assert( va > 0 && vb > 0 && vc > 0 );
81 const T denom = 1 / ( va + vb + vc );
82 const T v = vb * denom;
83 const T w = vc * denom;
84 return { a + v * ab + w * ac, { v, w } }; //#0
85}
86
87} //namespace MR
constexpr auto dot(A a, A b)
Definition MRImGuiVectorOperators.h:129
Definition MRCameraOrientationPlugin.h:8
MRMESH_CLASS Vector3
Definition MRMesh/MRMeshFwd.h:137