MeshLib C++ Docs
Loading...
Searching...
No Matches
MRTriMath.h
Go to the documentation of this file.
1#pragma once
3
4#include "MRVector2.h"
5#include "MRVector3.h"
6#include "MRPch/MRBindingMacros.h"
7#include <algorithm>
8#include <cassert>
9#include <cmath>
10#include <limits>
11#include <optional>
12
13namespace MR
14{
17
18
21template <typename T>
22[[nodiscard]] T circumcircleDiameterSq( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
23{
24 const auto ab = ( b - a ).lengthSq();
25 const auto ca = ( a - c ).lengthSq();
26 const auto bc = ( c - b ).lengthSq();
27 if ( ab <= 0 )
28 return ca;
29 if ( ca <= 0 )
30 return bc;
31 if ( bc <= 0 )
32 return ab;
33 const auto f = cross( b - a, c - a ).lengthSq();
34 if ( f <= 0 )
35 return std::numeric_limits<T>::infinity();
36 return ab * ca * bc / f;
37}
38
39MR_BIND_TEMPLATE( float circumcircleDiameterSq( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
40MR_BIND_TEMPLATE( double circumcircleDiameterSq( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
41
44template <typename T>
45[[nodiscard]] inline T circumcircleDiameter( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
46{
47 return std::sqrt( circumcircleDiameterSq( a, b, c ) );
48}
49
50MR_BIND_TEMPLATE( float circumcircleDiameter( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
51MR_BIND_TEMPLATE( double circumcircleDiameter( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
52
56template <typename T>
57[[nodiscard]] T mincircleDiameterSq( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
58{
59 const auto ab = ( b - a ).lengthSq();
60 const auto ca = ( a - c ).lengthSq();
61 const auto bc = ( c - b ).lengthSq();
62 if ( ca >= bc + ab )
63 return ca;
64 if ( bc >= ab + ca )
65 return bc;
66 if ( ab >= ca + bc )
67 return ab;
68 const auto f = cross( b - a, c - a ).lengthSq();
69 assert( f > 0 );
70 return ab * ca * bc / f;
71}
72
73MR_BIND_TEMPLATE( float mincircleDiameterSq( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
74MR_BIND_TEMPLATE( double mincircleDiameterSq( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
75
79template <typename T>
80[[nodiscard]] T edgeCoveringRadiusSq( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
81{
82 const auto d = b - a;
83 const auto lSq = d.lengthSq();
84 if ( lSq <= 0 )
85 return T( 0 );
86 const auto ac = c - a;
87 const auto acSq = ac.lengthSq();
88 const auto p = dot( ac, d );
89
91 auto sqDistToNearest = [&]( T t )
92 {
93 t = std::clamp( t, T( 0 ), T( 1 ) );
94 return std::max( T( 0 ), std::min( { t * t * lSq, ( 1 - t ) * ( 1 - t ) * lSq,
95 acSq - 2 * t * p + t * t * lSq } ) );
96 };
98 auto res = sqDistToNearest( T( 0.5 ) );
99 if ( p > 0 )
100 res = std::max( res, sqDistToNearest( acSq / ( 2 * p ) ) );
101 if ( p < lSq )
102 res = std::max( res, sqDistToNearest( ( lSq - acSq ) / ( 2 * ( lSq - p ) ) ) );
103 return res;
104}
105
106MR_BIND_TEMPLATE( float edgeCoveringRadiusSq( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
107MR_BIND_TEMPLATE( double edgeCoveringRadiusSq( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
108
114template <typename T>
115[[nodiscard]] T coveringRadiusSq( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
116{
117 const auto ab = ( b - a ).lengthSq();
118 const auto ca = ( a - c ).lengthSq();
119 const auto bc = ( c - b ).lengthSq();
123 if ( ca < bc + ab && bc < ab + ca && ab < ca + bc )
124 return ab * ca * bc / ( 4 * cross( b - a, c - a ).lengthSq() );
128 if ( ab >= bc && ab >= ca )
129 return edgeCoveringRadiusSq( a, b, c );
130 if ( bc >= ca )
131 return edgeCoveringRadiusSq( b, c, a );
132 return edgeCoveringRadiusSq( c, a, b );
133}
134
135MR_BIND_TEMPLATE( float coveringRadiusSq( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
136MR_BIND_TEMPLATE( double coveringRadiusSq( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
137
139template <typename T>
140[[nodiscard]] Vector3<T> circumcircleCenter( const Vector3<T> & a, const Vector3<T> & b )
141{
142 const auto xabSq = cross( a, b ).lengthSq();
143 const auto aa = a.lengthSq();
144 const auto bb = b.lengthSq();
145 if ( xabSq <= 0 )
146 {
147 if ( aa <= 0 )
148 return b / T(2);
150 return a / T(2);
151 }
152 const auto ab = dot( a, b );
153 return ( bb * ( aa - ab ) * a + aa * ( bb - ab ) * b ) / ( 2 * xabSq );
154}
155
156MR_BIND_TEMPLATE( Vector3f circumcircleCenter( const Vector3f & a, const Vector3f & b ) );
157MR_BIND_TEMPLATE( Vector3d circumcircleCenter( const Vector3d & a, const Vector3d & b ) );
158
160template <typename T>
161[[nodiscard]] inline Vector3<T> circumcircleCenter( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
162{
163 return circumcircleCenter( a - c, b - c ) + c;
164}
165
166MR_BIND_TEMPLATE( Vector3f circumcircleCenter( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
167MR_BIND_TEMPLATE( Vector3d circumcircleCenter( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
168
171template <typename T>
172[[nodiscard]] bool circumballCenters( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c, T radius,
173 Vector3<T> & centerPos,
174 Vector3<T> & centerNeg )
175{
176 const auto rr = sqr( radius );
177 const auto circRadSq = circumcircleDiameterSq( a, b, c ) / T( 4 );
178 if ( rr < circRadSq )
179 return false;
180
181 const auto x = std::sqrt( rr - circRadSq );
182 const auto xn = x * normal( a, b, c );
183 const auto circCenter = circumcircleCenter( a, b, c );
184 centerPos = circCenter + xn;
185 centerNeg = circCenter - xn;
186
187 return true;
188}
189
190MR_BIND_TEMPLATE( bool circumballCenters( const Vector3f & a, const Vector3f & b, const Vector3f & c, float radius, Vector3f & centerPos, Vector3f & centerNeg ) );
191MR_BIND_TEMPLATE( bool circumballCenters( const Vector3d & a, const Vector3d & b, const Vector3d & c, double radius, Vector3d & centerPos, Vector3d & centerNeg ) );
192
195template <typename T>
196[[nodiscard]] T minTriangleAngleSin( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
197{
198 const auto ab = ( b - a ).length();
199 const auto ca = ( a - c ).length();
200 const auto bc = ( c - b ).length();
201 if ( ab <= 0 || ca <= 0 || bc <= 0 )
202 return 0;
203 const auto f = cross( b - a, c - a ).length();
204 return f * std::min( { ab, ca, bc } ) / ( ab * ca * bc );
205}
206
207MR_BIND_TEMPLATE( float minTriangleAngleSin( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
208MR_BIND_TEMPLATE( double minTriangleAngleSin( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
209
210template <typename T>
211[[nodiscard]] T minTriangleAngle( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
212{
213 return std::asin( minTriangleAngleSin( a, b, c ) );
214}
215
216MR_BIND_TEMPLATE( float minTriangleAngle( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
217MR_BIND_TEMPLATE( double minTriangleAngle( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
218
221template<typename T>
222[[nodiscard]] T triangleAspectRatio( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
223{
224 const auto bc = ( c - b ).length();
225 const auto ca = ( a - c ).length();
226 const auto ab = ( b - a ).length();
227 auto halfPerimeter = ( bc + ca + ab ) / 2;
228 auto den = 8 * ( halfPerimeter - bc ) * ( halfPerimeter - ca ) * ( halfPerimeter - ab );
229 if ( den <= 0 )
230 return std::numeric_limits<T>::max();
231
232 return bc * ca * ab / den;
233}
234
235MR_BIND_TEMPLATE( float triangleAspectRatio( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
236MR_BIND_TEMPLATE( double triangleAspectRatio( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
237
239template<typename T>
240[[nodiscard]] inline Vector3<T> dirDblArea( const Triangle3<T> & t )
241{
242 return cross( t[1] - t[0], t[2] - t[0] );
243}
244
245MR_BIND_TEMPLATE( Vector3f dirDblArea( const Triangle3f & t ) );
246MR_BIND_TEMPLATE( Vector3d dirDblArea( const Triangle3d & t ) );
247
249template<typename T>
250[[nodiscard]] inline Vector3<T> dirDblArea( const Vector3<T> & q, const Vector3<T> & r )
251{
252 return cross( q, r );
253}
254
255MR_BIND_TEMPLATE( Vector3f dirDblArea( const Vector3f & a, const Vector3f & b ) );
256MR_BIND_TEMPLATE( Vector3d dirDblArea( const Vector3d & a, const Vector3d & b ) );
257
259template<typename T>
260[[nodiscard]] inline Vector3<T> dirDblArea( const Vector3<T> & p, const Vector3<T> & q, const Vector3<T> & r )
261{
262 return cross( q - p, r - p );
263}
264
265MR_BIND_TEMPLATE( Vector3f dirDblArea( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
266MR_BIND_TEMPLATE( Vector3d dirDblArea( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
267
269template<typename T>
270[[nodiscard]] inline Vector3<T> normal( const Vector3<T> & q, const Vector3<T> & r )
271{
272 return dirDblArea( q, r ).normalized();
273}
274
275MR_BIND_TEMPLATE( Vector3f normal( const Vector3f & a, const Vector3f & b ) );
276MR_BIND_TEMPLATE( Vector3d normal( const Vector3d & a, const Vector3d & b ) );
277
279template<typename T>
280[[nodiscard]] inline Vector3<T> normal( const Vector3<T> & p, const Vector3<T> & q, const Vector3<T> & r )
281{
282 return normal( q - p, r - p );
283}
284
285MR_BIND_TEMPLATE( Vector3f normal( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
286MR_BIND_TEMPLATE( Vector3d normal( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
287
289template<typename T>
290[[nodiscard]] inline Vector3<T> normal( const Triangle3<T> & t )
291{
292 return normal( t[1] - t[0], t[2] - t[0] );
293}
294
295MR_BIND_TEMPLATE( Vector3f normal( const Triangle3f & t ) );
296MR_BIND_TEMPLATE( Vector3d normal( const Triangle3d & t ) );
297
299template<typename T>
300[[nodiscard]] inline T dblAreaSq( const Vector3<T> & p, const Vector3<T> & q, const Vector3<T> & r )
301{
302 return dirDblArea( p, q, r ).lengthSq();
303}
304
305MR_BIND_TEMPLATE( float dblAreaSq( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
306MR_BIND_TEMPLATE( double dblAreaSq( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
307
309template<typename T>
310[[nodiscard]] inline T dblArea( const Triangle3<T> & t )
311{
312 return dirDblArea( t ).length();
313}
314
315MR_BIND_TEMPLATE( float dblArea( const Triangle3f & t ) );
316MR_BIND_TEMPLATE( double dblArea( const Triangle3d & t ) );
317
319template<typename T>
320[[nodiscard]] inline T dblArea( const Vector3<T> & p, const Vector3<T> & q, const Vector3<T> & r )
321{
322 return dirDblArea( p, q, r ).length();
323}
324
325MR_BIND_TEMPLATE( float dblArea( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
326MR_BIND_TEMPLATE( double dblArea( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
327
329template<typename T>
330[[nodiscard]] inline T area( const Vector3<T> & p, const Vector3<T> & q, const Vector3<T> & r )
331{
332 return dblArea( p, q, r ) / 2;
333}
334
335MR_BIND_TEMPLATE( float area( const Vector3f & a, const Vector3f & b, const Vector3f & c ) );
336MR_BIND_TEMPLATE( double area( const Vector3d & a, const Vector3d & b, const Vector3d & c ) );
337
339template<typename T>
340[[nodiscard]] inline T dblArea( const Vector2<T> & p, const Vector2<T> & q, const Vector2<T> & r )
341{
342 return std::abs( cross( q - p, r - p ) );
343}
344
345MR_BIND_TEMPLATE( float dblArea( const Vector2f & a, const Vector2f & b, const Vector2f & c ) );
346MR_BIND_TEMPLATE( double dblArea( const Vector2d & a, const Vector2d & b, const Vector2d & c ) );
347
349template<typename T>
350[[nodiscard]] inline T area( const Vector2<T> & p, const Vector2<T> & q, const Vector2<T> & r )
351{
352 return dblArea( p, q, r ) / 2;
353}
354
355MR_BIND_TEMPLATE( float area( const Vector2f & a, const Vector2f & b, const Vector2f & c ) );
356MR_BIND_TEMPLATE( double area( const Vector2d & a, const Vector2d & b, const Vector2d & c ) );
357
359template <typename T>
360[[nodiscard]] Triangle3<T> makeDegenerate( const Triangle3<T> & t )
361{
362 const auto c = ( t[0] + t[1] + t[2] ) / T(3);
363 int longest = 0;
364 T longestSq = 0;
365 for ( int i = 0; i < 3; ++i )
366 {
367 const auto sq = ( t[i] - c ).lengthSq();
368 if ( longestSq >= sq )
369 continue;
370 longest = i;
371 longestSq = sq;
372 }
373 const auto d = ( t[longest] - c ).normalized();
374
376 Triangle3<T> res;
377 for ( int i = 0; i < 3; ++i )
378 res[i] = c + d * dot( d, t[i] - c );
379 return res;
380}
381
384
387template <typename T>
388[[nodiscard]] Triangle3<T> triangleWithNormal( const Triangle3<T> & t, const Vector3<T> & n )
389{
390 const auto c = ( t[0] + t[1] + t[2] ) / T(3);
391 Triangle3<T> res;
392 for ( int i = 0; i < 3; ++i )
393 res[i] = t[i] - n * dot( n, t[i] - c );
394
395 if ( dot( n, dirDblArea( res ) ) < 0 )
396 res = makeDegenerate( res );
397 return res;
398}
399
400MR_BIND_TEMPLATE( Triangle3f triangleWithNormal( const Triangle3f & t, const Vector3f & n ) );
401MR_BIND_TEMPLATE( Triangle3d triangleWithNormal( const Triangle3d & t, const Vector3d & n ) );
402
408template <typename T>
409[[nodiscard]] T dihedralAngleSin( const Vector3<T>& leftNorm, const Vector3<T>& rightNorm, const Vector3<T>& edgeVec )
410{
411 auto edgeDir = edgeVec.normalized();
412 return dot( edgeDir, cross( leftNorm, rightNorm ) );
413}
414
415MR_BIND_TEMPLATE( float dihedralAngleSin( const Vector3f&, const Vector3f&, const Vector3f& ) );
416MR_BIND_TEMPLATE( double dihedralAngleSin( const Vector3d&, const Vector3d&, const Vector3d& ) );
417
423template <typename T>
424[[nodiscard]] T dihedralAngleCos( const Vector3<T>& leftNorm, const Vector3<T>& rightNorm )
425{
426 return dot( leftNorm, rightNorm );
427}
428
429MR_BIND_TEMPLATE( float dihedralAngleCos( const Vector3f&, const Vector3f& ) );
430MR_BIND_TEMPLATE( double dihedralAngleCos( const Vector3d&, const Vector3d& ) );
431
438template <typename T>
439[[nodiscard]] T dihedralAngle( const Vector3<T>& leftNorm, const Vector3<T>& rightNorm, const Vector3<T>& edgeVec )
440{
441 auto sin = dihedralAngleSin( leftNorm, rightNorm, edgeVec );
442 auto cos = dihedralAngleCos( leftNorm, rightNorm );
443 return std::atan2( sin, cos );
444}
445
446MR_BIND_TEMPLATE( float dihedralAngle( const Vector3f&, const Vector3f&, const Vector3f& ) );
447MR_BIND_TEMPLATE( double dihedralAngle( const Vector3d&, const Vector3d&, const Vector3d& ) );
448
452template <typename T>
453[[nodiscard]] std::optional<Vector2<T>> posFromTriEdgeLengths( T a, T b, T c )
454{
455 if ( c == 0 )
456 {
457 if ( a == b )
458 return Vector2<T>{ a, 0 };
459 else
460 return {};
461 }
462 const auto aa = sqr( a );
463 const auto y = ( aa - sqr( b ) + sqr( c ) ) / ( 2 * c );
464 const auto yy = sqr( y );
465 if ( yy > aa )
466 return {};
467 const auto x = std::sqrt( aa - yy );
468 return Vector2<T>{ x, y };
469}
470
471MR_BIND_TEMPLATE( std::optional<Vector2f> posFromTriEdgeLengths( float, float, float ) );
472MR_BIND_TEMPLATE( std::optional<Vector2d> posFromTriEdgeLengths( double, double, double ) );
473
477template <typename T>
478[[nodiscard]] std::optional<T> quadrangleOtherDiagonal( T a, T b, T c, T a1, T b1 )
479{
480 const auto p = posFromTriEdgeLengths( a, b, c );
481 if ( !p )
482 return {};
483 auto p1 = posFromTriEdgeLengths( a1, b1, c );
484 if ( !p1 )
485 return {};
486 p1->x = -p1->x;
488 auto y = ( p->x * p1->y - p1->x * p->y ) / ( p->x - p1->x );
489 if ( y < 0 || y > c )
490 return {};
491 return ( *p - *p1 ).length();
492}
493
494MR_BIND_TEMPLATE( std::optional<float > quadrangleOtherDiagonal( float, float, float, float, float ) );
495MR_BIND_TEMPLATE( std::optional<double> quadrangleOtherDiagonal( double, double, double, double, double ) );
496
500template <typename T>
501[[nodiscard]] inline T tanSqOfHalfAngle( T a, T b, T c )
502{
503 const T den = ( a + b + c ) * ( b + c - a );
504 if ( den <= 0 )
505 return std::numeric_limits<T>::infinity();
506 const T num = ( a + c - b ) * ( a + b - c );
507 if ( num <= 0 )
508 return 0;
509 return num / den;
510}
511
512MR_BIND_TEMPLATE( float tanSqOfHalfAngle( float, float, float ) );
513MR_BIND_TEMPLATE( double tanSqOfHalfAngle( double, double, double ) );
514
517template <typename T>
518[[nodiscard]] inline T cotan( const Triangle3<T> & t, T absMaxVal = std::numeric_limits<T>::max() )
519{
520 auto a = t[0] - t[2];
521 auto b = t[1] - t[2];
522 auto nom = dot( a, b );
523 auto den = cross( a, b ).length();
524 if ( fabs( nom ) >= absMaxVal * den )
525 return absMaxVal * sgn( nom );
526 return nom / den;
527}
528
529MR_BIND_TEMPLATE( float cotan( const Triangle3f&, float ) );
530MR_BIND_TEMPLATE( double cotan( const Triangle3d&, double ) );
531
535template <typename T>
536[[nodiscard]] inline T cotan( T a, T b, T c )
537{
538 const T den = ( a + b + c ) * ( b + c - a );
539 if ( den <= 0 )
540 return -std::numeric_limits<T>::infinity();
541 const T num = ( a + c - b ) * ( a + b - c );
542 if ( num <= 0 )
543 return std::numeric_limits<T>::infinity();
544 const auto tanSq = num / den;
545 return ( 1 - tanSq ) / ( 2 * std::sqrt( tanSq ) );
546}
547
548MR_BIND_TEMPLATE( float cotan( float, float, float ) );
549MR_BIND_TEMPLATE( double cotan( double, double, double ) );
550
553template <typename T>
554[[nodiscard]] std::optional<Vector3<T>> gradientInTri( const Vector3<T> & b, const Vector3<T> & c, T vb, T vc )
555{
556 const auto bb = dot( b, b );
557 const auto bc = dot( b, c );
558 const auto cc = dot( c, c );
559 const auto det = bb * cc - bc * bc;
560 if ( det <= 0 )
561 return {};
562 const auto kb = ( 1 / det ) * ( cc * vb - bc * vc );
563 const auto kc = ( 1 / det ) * (-bc * vb + bb * vc );
564 return kb * b + kc * c;
565}
566
567MR_BIND_TEMPLATE( std::optional<Vector3f> gradientInTri( const Vector3f&, const Vector3f&, float, float ) );
568MR_BIND_TEMPLATE( std::optional<Vector3d> gradientInTri( const Vector3d&, const Vector3d&, double, double ) );
569
572template <typename T>
573[[nodiscard]] std::optional<Vector3<T>> gradientInTri( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c, T va, T vb, T vc )
574{
575 return gradientInTri( b - a, c - a, vb - va, vc - va );
576}
577
578MR_BIND_TEMPLATE( std::optional<Vector3f> gradientInTri( const Vector3f&, const Vector3f&, const Vector3f&, float, float, float ) );
579MR_BIND_TEMPLATE( std::optional<Vector3d> gradientInTri( const Vector3d&, const Vector3d&, const Vector3d&, double, double, double ) );
580
583template <typename T>
584[[nodiscard]] std::optional<T> findTriExitPos( const Vector3<T> & b, const Vector3<T> & c, const Vector3<T> & grad )
585{
586 const auto gradSq = grad.lengthSq();
587 if ( gradSq <= 0 )
588 return {};
589 const auto d = c - b;
591 const auto gort = d - ( dot( d, grad ) / gradSq ) * grad;
592 const auto god = dot( gort, d );
593 if ( god <= 0 )
594 return {};
595 const auto gob = -dot( gort, b );
596 if ( gob <= 0 || gob >= god )
597 return {};
598 const auto a = gob / god;
599 assert( a < std::numeric_limits<T>::max() );
600 const auto ip = a * c + ( 1 - a ) * b;
601 if ( dot( grad, ip ) >= 0 )
602 return {};
603 return a;
604}
605
606MR_BIND_TEMPLATE( std::optional<float > findTriExitPos( const Vector3f&, const Vector3f&, const Vector3f& ) );
607MR_BIND_TEMPLATE( std::optional<double> findTriExitPos( const Vector3d&, const Vector3d&, const Vector3d& ) );
608
615template <typename T>
616[[nodiscard]] std::optional<Vector3<T>> tangentPlaneNormalToSpheres( const Vector3<T> & b, const Vector3<T> & c, T rb, T rc )
617{
618 auto grad = gradientInTri( b, c, rb, rc );
619 if ( !grad.has_value() )
620 return {};
621 auto gradSq = grad->lengthSq();
622 if ( gradSq >= 1 )
623 return {};
624 return sqrt( 1 - gradSq ) * normal( b, c ) - *grad;
625}
626
627MR_BIND_TEMPLATE( std::optional<Vector3f> tangentPlaneNormalToSpheres( const Vector3f&, const Vector3f&, float, float ) );
628MR_BIND_TEMPLATE( std::optional<Vector3d> tangentPlaneNormalToSpheres( const Vector3d&, const Vector3d&, double, double ) );
629
636template <typename T>
637[[nodiscard]] std::optional<Plane3<T>> tangentPlaneToSpheres( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c, T ra, T rb, T rc )
638{
639 if ( auto n = tangentPlaneNormalToSpheres( b - a, c - a, rb - ra, rc - ra ) )
640 return Plane3<T>( *n, dot( *n, a ) + ra );
641 return {};
642}
643
644MR_BIND_TEMPLATE( std::optional<Plane3f> tangentPlaneToSpheres( const Vector3f&, const Vector3f&, const Vector3f&, float, float, float ) );
645MR_BIND_TEMPLATE( std::optional<Plane3d> tangentPlaneToSpheres( const Vector3d&, const Vector3d&, const Vector3d&, double, double, double ) );
646
647}
Plane3
Definition MRMeshFwd.h:390
float area(const MeshTopology &topology, const VertCoords &points, FaceId f)
returns the area of given face
Definition MRMeshMath.h:168
float dihedralAngleSin(const MeshTopology &topology, const VertCoords &points, UndirectedEdgeId e)
constexpr auto sqr(T x) noexcept -> decltype(x *x)
squared value; the result type is the type of x*x, which is int for small integer types (char,...
Definition MRMeshFwd.h:769
auto dot(const Matrix2< T > &a, const Matrix2< T > &b) -> decltype(dot(a.x, b.x))
double-dot product: x = a : b
Definition MRMatrix2.h:142
Vector3< T > circumcircleCenter(const Vector3< T > &a, const Vector3< T > &b)
Computes the center of the the triangle's 0AB circumcircle.
Definition MRTriMath.h:140
auto lengthSq() const -> decltype(std::declval< T >() *std::declval< T >())
Definition MRVector3.h:68
std::optional< T > findTriExitPos(const Vector3< T > &b, const Vector3< T > &c, const Vector3< T > &grad)
Definition MRTriMath.h:584
std::optional< T > quadrangleOtherDiagonal(T a, T b, T c, T a1, T b1)
Definition MRTriMath.h:478
Triangle3< T > makeDegenerate(const Triangle3< T > &t)
make degenerate triangle (all 3 points on a line) that maximally resembles the input one and has the ...
Definition MRTriMath.h:360
float triangleAspectRatio(const MeshTopology &topology, const VertCoords &points, FaceId f)
returns aspect ratio of given mesh triangle equal to the ratio of the circum-radius to twice its in-r...
T tanSqOfHalfAngle(T a, T b, T c)
Definition MRTriMath.h:501
Triangle3< T > triangleWithNormal(const Triangle3< T > &t, const Vector3< T > &n)
Definition MRTriMath.h:388
Vector3f dirDblArea(const MeshTopology &topology, const VertCoords &points, FaceId f)
computes directed double area for a triangular face from its vertices
Definition MRMeshMath.h:153
float dihedralAngleCos(const MeshTopology &topology, const VertCoords &points, UndirectedEdgeId e)
constexpr int sgn(T x) noexcept
sign of given value in { -1, 0, 1 }
Definition MRMeshFwd.h:773
std::optional< Vector3< T > > gradientInTri(const Vector3< T > &b, const Vector3< T > &c, T vb, T vc)
Definition MRTriMath.h:554
Triangle3< double > Triangle3d
Definition MRMeshFwd.h:467
float circumcircleDiameter(const MeshTopology &topology, const VertCoords &points, FaceId f)
returns circumcircle diameter of given mesh triangle
std::optional< Plane3< T > > tangentPlaneToSpheres(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, T ra, T rb, T rc)
Definition MRTriMath.h:637
bool circumballCenters(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, T radius, Vector3< T > &centerPos, Vector3< T > &centerNeg)
ball's center from the negative side of triangle
Definition MRTriMath.h:172
std::optional< Vector3< T > > tangentPlaneNormalToSpheres(const Vector3< T > &b, const Vector3< T > &c, T rb, T rc)
Definition MRTriMath.h:616
Vector3 normalized() const MR_REQUIRES_IF_SUPPORTED(std
Definition MRVector3.h:77
float dblArea(const MeshTopology &topology, const VertCoords &points, FaceId f)
returns twice the area of given face
Definition MRMeshMath.h:162
MR_BIND_TEMPLATE(std::pair< Vector3f, TriPointf > closestPointInTriangle(const Vector3f &p, const Vector3f &a, const Vector3f &b, const Vector3f &c))
T minTriangleAngle(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Definition MRTriMath.h:211
Triangle3< float > Triangle3f
Definition MRMeshFwd.h:466
std::optional< Vector2< T > > posFromTriEdgeLengths(T a, T b, T c)
Definition MRTriMath.h:453
float circumcircleDiameterSq(const MeshTopology &topology, const VertCoords &points, FaceId f)
returns squared circumcircle diameter of given mesh triangle
float cotan(const MeshTopology &topology, const VertCoords &points, UndirectedEdgeId ue)
Definition MRMeshMath.h:315
float dihedralAngle(const MeshTopology &topology, const VertCoords &points, UndirectedEdgeId e)
T dblAreaSq(const Vector3< T > &p, const Vector3< T > &q, const Vector3< T > &r)
computes the square of double area of given triangle
Definition MRTriMath.h:300
length
Definition MRObjectDimensionsEnum.h:17
@ normal
Definition MRUnits.h:45
T mincircleDiameterSq(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Definition MRTriMath.h:57
T edgeCoveringRadiusSq(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Definition MRTriMath.h:80
T coveringRadiusSq(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Definition MRTriMath.h:115
T minTriangleAngleSin(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
Definition MRTriMath.h:196
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MRVector2.h:29
auto cross(const Vector2< T > &a, const Vector2< T > &b) -> decltype(a.x *b.x)
cross product
Definition MRVector2.h:160
Definition MRVector3.h:33