MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / findTwoLineSegmClosestPointsT

Function findTwoLineSegmClosestPointsT

source/MRMesh/MRTwoLineSegmDist.cpp:15–121  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

13// In Information Processing Letters, no. 21, pages 55-61, 1985.
14template<class T>
15TwoLineSegmClosestPoints<T> findTwoLineSegmClosestPointsT( const LineSegm3<T>& a, const LineSegm3<T>& b )
16{
17 TwoLineSegmClosestPoints<T> res;
18
19 const auto adir = a.dir();
20 const auto bdir = b.dir();
21
22 const auto aa = dot( adir, adir );
23 const auto bb = dot( bdir, bdir );
24 const auto ab = dot( adir, bdir );
25 const auto denom = aa * bb - ab * ab;
26
27 auto d = b.a - a.a;
28 const auto ad = dot( adir, d );
29 const auto bd = dot( bdir, d );
30
31 // compute t for the closest point on ray a to ray b
32 // t parameterizes ray a
33 auto t = ( ad * bb - bd * ab ) / denom;
34
35 // clamp result so t is on the segment a.a,adir
36
37 if ( ( t < 0 ) || std::isnan( t ) ) t = 0; else if ( t > 1 ) t = 1;
38
39 // find u for point on ray b closest to point ad t
40 // u parameterizes ray b
41 auto u = ( t * ab - bd ) / bb;
42
43 // if u is on segment b.a,bdir, t and u correspond to
44 // closest points, otherwise, clamp u, recompute and
45 // clamp t
46
47 if ( ( u <= 0 ) || std::isnan( u ) )
48 {
49 res.b = b.a;
50
51 t = ad / aa;
52
53 if ( ( t <= 0 ) || std::isnan( t ) )
54 {
55 res.a = a.a;
56 res.dir = b.a - a.a;
57 }
58 else if ( t >= 1 )
59 {
60 res.a = a.a + adir;
61 res.dir = b.a - res.a;
62 }
63 else
64 {
65 res.a = a.a + adir * t;
66 auto tmp = cross( d, adir );
67 res.dir = cross( adir, tmp );
68 }
69 }
70 else if ( u >= 1 )
71 {
72 res.b = b.a + bdir;

Callers 1

Calls 3

dirMethod · 0.80
dotFunction · 0.70
crossFunction · 0.70

Tested by

no test coverage detected