Trax3 3.1.0
trax track library
Loading...
Searching...
No Matches
Frame.h
1// trax track library
2// AD 2013
3//
4// "Hojotoh! Hojotoh! Hoooo! Hojohoooo!"
5//
6// Richard Wagner
7//
8// Copyright (c) 2025 Trend Redaktions- und Verlagsgesellschaft mbH
9// Copyright (c) 2019 Marc-Michael Horstmann
10//
11// Permission is hereby granted to any person obtaining a copy of this software
12// and associated source code (the "Software"), to use, view, and study the
13// Software for personal or internal business purposes, subject to the following
14// conditions:
15//
16// 1. Redistribution, modification, sublicensing, or commercial use of the
17// Software is NOT permitted without prior written consent from the copyright
18// holder.
19//
20// 2. The Software is provided "AS IS", without warranty of any kind, express
21// or implied.
22//
23// 3. All copies of the Software must retain this license notice.
24//
25// For further information, please contact: horstmann.marc@trendverlag.de
26
27#pragma once
28
29#include "Position.h"
30#include "Vector.h"
31#include "Box.h"
32#include "Sphere.h"
33
34#include <cmath>
35
36namespace spat{
37
38 template<typename,typename> struct VectorBundle;
39 template<typename,typename> struct VectorBundle2;
40
41 template<typename> class Rotation;
42 template<typename,const unsigned short,const unsigned short> class Matrix;
43
50 template<typename Valtype,typename ValtypeT = Valtype>
51 struct Frame
52 {
57
58
74 constexpr Frame() noexcept = default;
75 constexpr Frame( Valtype px, Valtype py, Valtype pz,
76 ValtypeT tx, ValtypeT ty, ValtypeT tz,
77 ValtypeT nx, ValtypeT ny, ValtypeT nz,
78 ValtypeT bx, ValtypeT by, ValtypeT bz ) noexcept;
79 explicit constexpr Frame( const VectorBundle2<Valtype,ValtypeT>& vb2 ) noexcept;
80 Frame( const VectorBundle<Valtype,ValtypeT>& vb, const Vector<ValtypeT>& up ) noexcept;
81 explicit constexpr Frame( const Position<Valtype>& pos ) noexcept;
82 constexpr Frame( const Position<Valtype>& pos,
83 const Vector<ValtypeT>& tan,
84 const Vector<ValtypeT>& nor,
85 const Vector<ValtypeT>& bin ) noexcept;
86 Frame( const Position<Valtype>& pos,
87 const Rotation<ValtypeT>& rot ) noexcept;
88 explicit Frame( const Rotation<ValtypeT>& rot ) noexcept;
89 template<typename Valtype2>
90 explicit Frame( const Matrix<Valtype2,4,4>& trans ) noexcept;
91 template<typename Valtype2>
92 explicit Frame( const Valtype2* pVal ) noexcept;
94
95
102 // no assignment for VectorBundle because its behaviour would not be obvious...
103 Frame& operator=( const VectorBundle2<Valtype,ValtypeT>& vb2 ) noexcept;
104
105 Frame& operator=( const Rotation<ValtypeT>& rot ) noexcept;
106
107 template<typename Valtype2>
108 Frame& operator=( const Matrix<Valtype2,4,4>& trans ) noexcept;
109
110 template<typename Valtype2>
111 Frame& operator=( const Valtype2* pVal ) noexcept;
113
114
118 operator VectorBundle2<Valtype,ValtypeT>() const noexcept;
119
120 operator VectorBundle<Valtype,ValtypeT>() const noexcept;
122
123
125 Valtype* ptr() noexcept;
126
127
129 const Valtype* ptr() const noexcept;
130
131
135 Frame& Init() noexcept;
136
137 Frame& Init( const Position<Valtype>& pos ) noexcept;
139
144 Frame& Init( const VectorBundle<Valtype,ValtypeT>& vb, const Vector<ValtypeT>& up ) noexcept;
145
146
149 Frame& Init( const VectorBundle2<Valtype,ValtypeT>& vb2 ) noexcept;
150
151
152 // use Matrix.h Invert( Frame<Valtype,ValtypeT>& frame )
156
157
166 Frame& LookAt( const Vector<ValtypeT>& reference, const Vector<ValtypeT>& dir ) noexcept;
167
168 Frame& LookTAt( const Vector<ValtypeT>& dir ) noexcept;
169
170 Frame& LookTAt( const Vector<ValtypeT>& dir, const Vector<ValtypeT>& up ) noexcept;
171
172 Frame& LookNAt( const Vector<ValtypeT>& dir ) noexcept;
173
174 Frame& LookBAt( const Vector<ValtypeT>& dir ) noexcept;
176
177
192 Frame& AircraftPrincipalAxes( ValtypeT yaw, ValtypeT pitch, ValtypeT roll );
193
194 Frame& AircraftPrincipalAxes( const Position<ValtypeT>& angles );
195
196 Position<ValtypeT> AircraftPrincipalAxes( ValtypeT epsilon = std::numeric_limits<ValtypeT>::epsilon() ) const;
198
199
201 Frame& Normalize() noexcept;
202
203
207
208
212 bool IsOrthoNormal( ValtypeT epsilon_length = 2*std::numeric_limits<ValtypeT>::epsilon(), ValtypeT epsilon_angle = 2*std::numeric_limits<ValtypeT>::epsilon() ) const noexcept;
213
214
222 template<typename Valtype2>
223 Position<Valtype2>& ToParent( Position<Valtype2>& p ) const noexcept;
224
225 template<typename Valtype2>
226 Vector<Valtype2>& ToParent( Vector<Valtype2>& v ) const noexcept;
227
228 template<typename Valtype2>
229 Vector<Valtype2>& NormalToParent( Vector<Valtype2>& normal ) const noexcept;
230
231 template<typename Valtype2,typename ValtypeT2>
232 VectorBundle<Valtype2,ValtypeT2>& ToParent( VectorBundle<Valtype2,ValtypeT2>& v ) const noexcept;
233
234 template<typename Valtype2,typename ValtypeT2>
235 VectorBundle2<Valtype2,ValtypeT2>& ToParent( VectorBundle2<Valtype2,ValtypeT2>& v ) const noexcept;
236
237 template<typename Valtype2,typename ValtypeT2>
238 Frame<Valtype2,ValtypeT2>& ToParent( Frame<Valtype2,ValtypeT2>& frame ) const noexcept;
239
240 template<typename Valtype2>
241 Box<Valtype2>& ToParent( Box<Valtype2>& box ) const noexcept;
242
243 template<typename Valtype2>
244 Sphere<Valtype2>& ToParent( Sphere<Valtype2>& sphere ) const noexcept;
246
247
256 template<typename Valtype2>
257 Position<Valtype2>& FromParent( Position<Valtype2>& p ) const noexcept;
258
259 template<typename Valtype2>
260 Vector<Valtype2>& FromParent( Vector<Valtype2>& v ) const noexcept;
261
262 template<typename Valtype2,typename ValtypeT2>
263 VectorBundle<Valtype2,ValtypeT2>& FromParent( VectorBundle<Valtype2,ValtypeT2>& b ) const noexcept;
264
265 template<typename Valtype2,typename ValtypeT2>
266 VectorBundle2<Valtype2,ValtypeT2>& FromParent( VectorBundle2<Valtype2,ValtypeT2>& b ) const noexcept;
267
268 template<typename Valtype2,typename ValtypeT2>
269 Frame<Valtype2,ValtypeT2>& FromParent( Frame<Valtype2,ValtypeT2>& frame ) const noexcept;
271
272
275 Frame& TransportTo( Valtype d ) noexcept;
276
277
281 Frame& TransportBy( const Vector<Valtype>& v ) noexcept;
282
283
286 Frame& TransportTo( const Position<Valtype>& p ) noexcept;
287
288
291 Frame& TransportTan( Valtype d ) noexcept;
292
293
296 Frame& TransportNor( Valtype d ) noexcept;
297
298
301 Frame& TransportBin( Valtype d ) noexcept;
302
303
305 Frame& FlipTan() noexcept;
306
307
309 Frame& FlipNor() noexcept;
310
311
313 Frame& FlipBin() noexcept;
314
315
317 Frame& Rotate( const Vector<ValtypeT>& nr, ValtypeT angle ) noexcept;
318
319
321 Frame& Rotate( const Vector<ValtypeT>& r ) noexcept;
322
323
327 template<typename Valtype2>
328 Frame& Rotate( const VectorBundle<Valtype,Valtype2>& axis ) noexcept;
329
330
335 template<typename Valtype2>
336 Frame& Rotate( const VectorBundle<Valtype,Valtype2>& axis, Valtype2 angle ) noexcept;
337
338
341 Frame& RotateTan( ValtypeT angle ) noexcept;
342
343
345 Frame& RotateTan( const Vector<ValtypeT>& up ) noexcept;
346
347
350 Frame& RotateNor( ValtypeT angle ) noexcept;
351
352
355 Frame& RotateBin( ValtypeT angle ) noexcept;
356
357
369 constexpr bool Equals( const Frame& frame,
370 Valtype epsilon_length = std::numeric_limits<Valtype>::epsilon(),
371 ValtypeT epsilon_lengthT = std::numeric_limits<ValtypeT>::epsilon() ) const noexcept;
372
373
375 Frame& Round( int toDigit ) noexcept;
376 };
377
379 template<typename Valtype,typename ValtypeT = Valtype>
380 using VectorBundle3 = Frame<Valtype,ValtypeT>;
381
382
384 template<typename Valtype,typename ValtypeT=Valtype>
385 constexpr Frame<Valtype,ValtypeT> Identity{ Origin3D<Valtype>, Ex<ValtypeT>, Ey<ValtypeT>, Ez<ValtypeT> };
386
388 template<typename Valtype,typename ValtypeT=Valtype,typename Valtype2=Valtype,typename ValtypeT2=Valtype>
389 Frame<Valtype,ValtypeT>& spatial_cast( Frame<Valtype2,ValtypeT2>& from ) noexcept;
390
392 template<typename Valtype,typename ValtypeT=Valtype,typename Valtype2=Valtype,typename ValtypeT2=Valtype>
393 const Frame<Valtype,ValtypeT>& spatial_cast( const Frame<Valtype2,ValtypeT2>& from ) noexcept;
394
397 template<typename Valtype,typename ValtypeT=Valtype> constexpr
398 bool operator==( const Frame<Valtype,ValtypeT>& frame1, const Frame<Valtype,ValtypeT>& frame2 ) noexcept;
399
400
403 template<typename Valtype,typename ValtypeT=Valtype> constexpr
404 bool operator!=( const Frame<Valtype,ValtypeT>& frame1, const Frame<Valtype,ValtypeT>& frame2 ) noexcept;
405
406
417
419 template<typename Valtype1,typename ValtypeT1,typename Valtype2>
420 Position<Valtype2> operator*( const Frame<Valtype1,ValtypeT1>& frame, const Position<Valtype2>& p ) noexcept;
421
422 template<typename Valtype1,typename ValtypeT1,typename ValtypeT2>
423 Vector<ValtypeT2> operator*( const Frame<Valtype1,ValtypeT1>& frame, const Vector<ValtypeT2>& v ) noexcept;
424
425 template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
426 VectorBundle<Valtype2,ValtypeT2> operator*( const Frame<Valtype1,ValtypeT1>& frame, const VectorBundle<Valtype2,ValtypeT2>& vb ) noexcept;
427
428 template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
429 VectorBundle2<Valtype2,ValtypeT2> operator*( const Frame<Valtype1,ValtypeT1>& frame, const VectorBundle2<Valtype2,ValtypeT2>& vb2 ) noexcept;
430
431 template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
433
434 template<typename Valtype1,typename ValtypeT1,typename Valtype2>
435 Sphere<Valtype2> operator*( const Frame<Valtype1,ValtypeT1>& frame, const Sphere<Valtype2>& sp ) noexcept;
436
437 template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
440
444 template<typename Valtype,typename ValtypeT>
445 Frame<Valtype,ValtypeT>& operator*=( Frame<Valtype,ValtypeT>& frame, ValtypeT param ) noexcept;
446
447
450 template<typename Valtype,typename ValtypeT>
451 auto Normalize( const Frame<Valtype,ValtypeT>& f ) noexcept -> std::pair<Vector<ValtypeT>,Frame<Valtype,decltype(ValtypeT{}/ValtypeT{})>>;
452
453
454template<typename Valtype,typename ValtypeT> constexpr
456 Valtype px, Valtype py, Valtype pz,
457 ValtypeT tx, ValtypeT ty, ValtypeT tz,
458 ValtypeT nx, ValtypeT ny, ValtypeT nz,
459 ValtypeT bx, ValtypeT by, ValtypeT bz ) noexcept
460 : P{px, py, pz},
461 T{tx, ty, tz},
462 N{nx, ny, nz},
463 B{bx, by, bz}
464{}
465
466template<typename Valtype,typename ValtypeT> constexpr
468 : P{vb2.P},
469 T{vb2.T},
470 N{vb2.N},
471 B{vb2.T % vb2.N}
472{}
473
474template<typename Valtype,typename ValtypeT>
476{
477 Init( vb, up );
478}
479
480
481template<typename Valtype,typename ValtypeT> constexpr
488
489template<typename Valtype,typename ValtypeT> constexpr
491 const Vector<ValtypeT>& tan,
492 const Vector<ValtypeT>& nor,
493 const Vector<ValtypeT>& bin ) noexcept
494 : P{pos},
495 T{tan},
496 N{nor},
497 B{bin}
498{}
499
500template<typename Valtype,typename ValtypeT>
502 const Position<Valtype>& pos,
503 const Rotation<ValtypeT>& rot ) noexcept
504 : P{pos}
505{
506 operator=( rot );
507}
508
509template<typename Valtype,typename ValtypeT>
511 P.Init();
512 operator=( rot );
513}
514
515template<typename Valtype,typename ValtypeT>
516template<typename Valtype2>
518 operator=( trans );
519}
520
521template<typename Valtype,typename ValtypeT>
522template<typename Valtype2>
523inline Frame<Valtype,ValtypeT>::Frame( const Valtype2* pVal ) noexcept
524 : P{pVal},
525 T{pVal+3},
526 N{pVal+6},
527 B{pVal+9}
528{
529}
530
531template<typename Valtype,typename ValtypeT>
532inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::operator=( const VectorBundle2<Valtype,ValtypeT>& vb2 ) noexcept{
533 P = vb2.P;
534 T = vb2.T;
535 N = vb2.N;
536 B = T % N;
537 return *this;
538}
539
540template<typename Valtype,typename ValtypeT>
541inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::operator=( const Rotation<ValtypeT>& rot ) noexcept{
542 T.dx = rot(0,0);
543 T.dy = rot(0,1);
544 T.dz = rot(0,2);
545
546 N.dx = rot(1,0);
547 N.dy = rot(1,1);
548 N.dz = rot(1,2);
549
550 B.dx = rot(2,0);
551 B.dy = rot(2,1);
552 B.dz = rot(2,2);
553 return *this;
554}
555
556template<typename Valtype,typename ValtypeT>
557template<typename Valtype2>
558inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::operator=( const Matrix<Valtype2,4,4>& trans ) noexcept{
559 T.dx = ValtypeT{trans(0,0)};
560 T.dy = ValtypeT{trans(0,1)};
561 T.dz = ValtypeT{trans(0,2)};
562
563 N.dx = ValtypeT{trans(1,0)};
564 N.dy = ValtypeT{trans(1,1)};
565 N.dz = ValtypeT{trans(1,2)};
566
567 B.dx = ValtypeT{trans(2,0)};
568 B.dy = ValtypeT{trans(2,1)};
569 B.dz = ValtypeT{trans(2,2)};
570
571 P.x = Valtype{trans(3,0)};
572 P.y = Valtype{trans(3,1)};
573 P.z = Valtype{trans(3,2)};
574
575 return *this;
576}
577
578template<typename Valtype,typename ValtypeT>
579template<typename Valtype2>
580inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::operator=( const Valtype2* pVal ) noexcept{
581 P = pVal;
582 T = pVal + 3;
583 N = pVal + 6;
584 B = pVal + 9;
585 return *this;
586}
587
588template<typename Valtype,typename ValtypeT>
589inline Frame<Valtype,ValtypeT>::operator VectorBundle2<Valtype,ValtypeT>() const noexcept{
590 return VectorBundle2<Valtype,ValtypeT>{ *this };
591}
592
593template<typename Valtype,typename ValtypeT>
594inline Frame<Valtype,ValtypeT>::operator VectorBundle<Valtype,ValtypeT>() const noexcept{
595 return VectorBundle<Valtype,ValtypeT>{ *this };
596}
597
598template<typename Valtype,typename ValtypeT>
599inline Valtype* Frame<Valtype,ValtypeT>::ptr() noexcept{
600 static_assert( sizeof(Valtype) == sizeof(ValtypeT), "Can not access a VectorBundle via pointer if the two types have different memory sizes.");
601 return P.ptr();
602}
603
604template<typename Valtype,typename ValtypeT>
605inline const Valtype* Frame<Valtype,ValtypeT>::ptr() const noexcept{
606 static_assert( sizeof(Valtype) == sizeof(ValtypeT), "Can not access a VectorBundle via pointer if the two types have different memory sizes.");
607 return P.ptr();
608}
609
610template<typename Valtype,typename ValtypeT>
612 P.Init();
616 return *this;
617}
618
619template<typename Valtype,typename ValtypeT>
621 P = pos;
625 return *this;
626}
627
628template<typename Valtype,typename ValtypeT>
630 P = vb.P;
631 T = vb.T;
632 N = up % T;
633 N.Normalize();
634 B = T % N;
635 return *this;
636}
637
638template<typename Valtype,typename ValtypeT>
640 P = vb.P;
641 T = vb.T;
642 N = vb.N;
643 B = T % N;
644 return *this;
645}
646
647template<typename Valtype,typename ValtypeT>
648Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::LookAt( const Vector<ValtypeT>& reference, const Vector<ValtypeT>& dir ) noexcept{
649//#ifdef _DEBUG
650// if( !IsOrthoNormal() ){
651// OrthogonalityDump( std::cout, *this );
652// assert( !"Frame misses to be orthogonal!" );
653// }
654//#endif
655
656 const ValtypeT pi__{3.141592654f};
657 Vector<ValtypeT> D = dir;
658 D.Normalize();
659 Vector<ValtypeT> R = reference;
660 ToParent( R );
661 R.Normalize();
662
663 Vector<ValtypeT> rotation = R % D;
664 if( ValtypeT sin = rotation.Normalize() ){
665 sin = std::clamp( sin, ValtypeT{-1}, ValtypeT{1} );
666 if( R*D < decltype(ValtypeT{}*ValtypeT{}){0} )
667 rotation *= pi__ - asin( sin );
668 else
669 rotation *= asin( sin );
670 }
671 else{
672 if( R == -D ){
673 // try to find a vector orthogonal on R
674 rotation = B.OrthogonalProjection( R );
675 if( !rotation.Normalize() ){
676 rotation = N.OrthogonalProjection( R );
677 if( !rotation.Normalize() ){
678 assert( !"impossible" );
679 return *this;
680 }
681 }
682
683 rotation *= pi__;
684 }
685 else
686 return *this; // R already points to D
687 }
688
689 Rotate( rotation );
690 assert( IsOrthoNormal() );
691 return *this;
692}
693
694template<typename Valtype,typename ValtypeT>
695Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::LookTAt( const Vector<ValtypeT>& dir ) noexcept{
696 return LookAt( Ex<ValtypeT>, dir );
697}
698
699template<typename Valtype,typename ValtypeT>
700Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::LookTAt( const Vector<ValtypeT>& dir, const Vector<ValtypeT>& up ) noexcept{
701 return LookAt( Ex<ValtypeT>, dir ).RotateTan( up );
702}
703
704template<typename Valtype,typename ValtypeT>
705Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::LookNAt( const Vector<ValtypeT>& dir ) noexcept{
706 return LookAt( Ey<ValtypeT>, dir );
707}
708
709template<typename Valtype,typename ValtypeT>
710Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::LookBAt( const Vector<ValtypeT>& dir ) noexcept{
711 return LookAt( Ez<ValtypeT>, dir );
712}
713
714template<typename Valtype,typename ValtypeT>
715inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::AircraftPrincipalAxes( ValtypeT yaw, ValtypeT pitch, ValtypeT roll )
716{
717 T = Ex<ValtypeT>;
718 N = Ey<ValtypeT>;
719 B = Ez<ValtypeT>;
720
721 return RotateBin( yaw ).RotateNor( pitch ).RotateTan( roll );
722}
723
724template<typename Valtype,typename ValtypeT>
725inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::AircraftPrincipalAxes( const Position<ValtypeT>& angles )
726{
727 return AircraftPrincipalAxes( angles.x, angles.y, angles.z );
728}
729
730template<typename Valtype,typename ValtypeT>
731inline Position<ValtypeT> Frame<Valtype,ValtypeT>::AircraftPrincipalAxes( ValtypeT _epsilon ) const
732{
733 const ValtypeT pi__{3.141592654f};
734
735 // todo: optimize!
736 if( Parallel( T, Ez<ValtypeT>, _epsilon ) ){
737 if( T * Ez<ValtypeT> > ValtypeT{0} )
738 return { ValtypeT{0}, -pi__/2, atan2( N * -Ex<ValtypeT>, N * Ey<ValtypeT> ) };
739 else
740 return { ValtypeT{0}, pi__/2, atan2( N * Ex<ValtypeT>, N * Ey<ValtypeT> ) };
741 }
742
743 Position<ValtypeT> retval{
744 atan2( T.dy, T.dx ),
745 atan2( -T.dz, sqrt( T.dx*T.dx + T.dy*T.dy ) ),
746 ValtypeT{0} };
747
749 ref.Init();
750 ref.RotateBin( retval.x ).RotateNor( retval.y );
751
752 retval.z = atan2( N * ref.B, N * ref.N );
753 return retval;
754}
755
756template<typename Valtype,typename ValtypeT>
758 T.Normalize();
759 N.Normalize();
760 B.Normalize();
761 return *this;
762}
763
764template<typename Valtype,typename ValtypeT>
767 {
768 T.dx = ValtypeT{1};
769 N = Ey<ValtypeT>;
770 B = Ez<ValtypeT>;
771 }
772 T.Normalize();
773 N -= (N * T) * T;
774
776 {
777 B -= (B * T) * T;
779 {
780 if ( !(T % Ey<ValtypeT>).Is(Vector<ValtypeT>::specials::null) )
781 N = Ey<ValtypeT> - (Ey<ValtypeT> * T) * T;
782 else
783 N = Ex<ValtypeT> - (Ex<ValtypeT> * T) * T;
784 }
785 else
786 {
787 B.Normalize();
788 N = B % T;
789 return *this;
790 }
791 }
792
793 N.Normalize();
794 B = T % N;
795 return *this;
796}
797
798template<typename Valtype,typename ValtypeT>
799inline bool Frame<Valtype,ValtypeT>::IsOrthoNormal( ValtypeT _epsilon_length, ValtypeT _epsilon_angle ) const noexcept{
800 return T.IsNormal( _epsilon_length ) &&
801 N.IsNormal( _epsilon_length ) &&
802 B.IsNormal( _epsilon_length ) &&
803 abs(T*N) <= ValtypeT{1} * _epsilon_angle &&
804 abs(T*B) <= ValtypeT{1} * _epsilon_angle &&
805 abs(N*B) <= ValtypeT{1} * _epsilon_angle;
806}
807
808template<typename Valtype,typename ValtypeT>
809template<typename Valtype2>
810inline Position<Valtype2>& Frame<Valtype,ValtypeT>::ToParent( Position<Valtype2>& p ) const noexcept{
811 p = spatial_cast<Valtype2>(P) + spatial_cast<Valtype2>(p.x * T + p.y * N + p.z * B);
812 return p;
813}
814
815template<typename Valtype,typename ValtypeT>
816template<typename Valtype2>
817inline Vector<Valtype2>& Frame<Valtype,ValtypeT>::ToParent( Vector<Valtype2>& v ) const noexcept{
818 v = spatial_cast<Valtype2>(v.dx * T + v.dy * N + v.dz * B);
819 return v;
820}
821
822template<typename Valtype,typename ValtypeT>
823template<typename Valtype2>
824inline Vector<Valtype2>& Frame<Valtype,ValtypeT>::NormalToParent( Vector<Valtype2>& n ) const noexcept
825{
826 n = spatial_cast<Valtype2>(n.dx * T / (T*T) + n.dy * N / (N*N) + n.dz * B / (B*B));
827 return n;
828}
829
830template<typename Valtype,typename ValtypeT>
831template<typename Valtype2,typename ValtypeT2>
832inline VectorBundle<Valtype2,ValtypeT2>& Frame<Valtype,ValtypeT>::ToParent( VectorBundle<Valtype2,ValtypeT2>& b ) const noexcept{
833 ToParent( b.P );
834 ToParent( b.T );
835 return b;
836}
837
838template<typename Valtype,typename ValtypeT>
839template<typename Valtype2,typename ValtypeT2>
840inline VectorBundle2<Valtype2,ValtypeT2>& Frame<Valtype,ValtypeT>::ToParent( VectorBundle2<Valtype2,ValtypeT2>& b ) const noexcept{
841 ToParent( b.P );
842 ToParent( b.T );
843 ToParent( b.N );
844 return b;
845}
846
847template<typename Valtype,typename ValtypeT>
848template<typename Valtype2,typename ValtypeT2>
850 ToParent( frame.P );
851 ToParent( frame.T );
852 ToParent( frame.N );
853 ToParent( frame.B );
854 return frame;
855}
856
857template<typename Valtype,typename ValtypeT>
858template<typename Valtype2>
859inline Box<Valtype2>& Frame<Valtype,ValtypeT>::ToParent( Box<Valtype2>& box ) const noexcept{
860
861 //todo
862 return box;
863}
864
865template<typename Valtype, typename ValtypeT>
866template<typename Valtype2>
867inline Sphere<Valtype2>& spat::Frame<Valtype,ValtypeT>::ToParent( Sphere<Valtype2>& sphere ) const noexcept
868{
869 ToParent( sphere.c );
870 return sphere;
871}
872
873template<typename Valtype,typename ValtypeT>
874template<typename Valtype2>
875inline Position<Valtype2>& Frame<Valtype,ValtypeT>::FromParent( Position<Valtype2>& p ) const noexcept{
876 Vector<Valtype2> v{ p - spatial_cast<Valtype2>(P) };
877 FromParent( v );
878 p.x = v.dx;
879 p.y = v.dy;
880 p.z = v.dz;
881 return p;
882}
883
884template<typename Valtype,typename ValtypeT>
885template<typename Valtype2>
886inline Vector<Valtype2>& Frame<Valtype,ValtypeT>::FromParent( Vector<Valtype2>& v ) const noexcept{
887 const Vector<Valtype2> vtemp{ v };
888 v.dx = vtemp*T;
889 v.dy = vtemp*N;
890 v.dz = vtemp*B;
891 return v;
892}
893
894template<typename Valtype,typename ValtypeT>
895template<typename Valtype2,typename ValtypeT2>
896inline VectorBundle<Valtype2,ValtypeT2>& Frame<Valtype,ValtypeT>::FromParent( VectorBundle<Valtype2,ValtypeT2>& b ) const noexcept{
897 FromParent( b.P );
898 FromParent( b.T );
899 return b;
900}
901
902template<typename Valtype,typename ValtypeT>
903template<typename Valtype2,typename ValtypeT2>
904inline VectorBundle2<Valtype2,ValtypeT2>& Frame<Valtype,ValtypeT>::FromParent( VectorBundle2<Valtype2,ValtypeT2>& b ) const noexcept{
905 FromParent( b.P );
906 FromParent( b.T );
907 FromParent( b.N );
908 return b;
909}
910
911template<typename Valtype,typename ValtypeT>
912template<typename Valtype2,typename ValtypeT2>
914 FromParent( frame.P );
915 FromParent( frame.T );
916 FromParent( frame.N );
917 FromParent( frame.B );
918 return frame;
919}
920
921template<typename Valtype,typename ValtypeT>
923 P += d * T;
924 return *this;
925}
926
927template<typename Valtype,typename ValtypeT>
929 P += p.x * T + p.y * N + p.z * B;
930 return *this;
931}
932
933template<typename Valtype,typename ValtypeT>
935 P.Transport( v );
936 return *this;
937}
938
939template<typename Valtype,typename ValtypeT>
941 P += dist * T;
942 return *this;
943}
944
945template<typename Valtype,typename ValtypeT>
947 P += dist * N;
948 return *this;
949}
950
951template<typename Valtype,typename ValtypeT>
953 P += dist * B;
954 return *this;
955}
956
957template<typename Valtype,typename ValtypeT>
959 N = -N;
960 B = -B;
961 return *this;
962}
963
964template<typename Valtype,typename ValtypeT>
966 T = -T;
967 B = -B;
968 return *this;
969}
970
971template<typename Valtype,typename ValtypeT>
973 T = -T;
974 N = -N;
975 return *this;
976}
977
978template<typename Valtype,typename ValtypeT>
980 T.Rotate( nr, angle );
981 N.Rotate( nr, angle );
982 B.Rotate( nr, angle );
983 return *this;
984}
985
986template<typename Valtype,typename ValtypeT>
988 Vector<ValtypeT> r(rot);
989 ValtypeT angle = r.Normalize();
990
991 T.Rotate( r, angle );
992 N.Rotate( r, angle );
993 B.Rotate( r, angle );
994 return *this;
995}
996
997template<typename Valtype,typename ValtypeT>
998template<typename Valtype2>
1000{
1002 Valtype2 angle = r.T.Normalize();
1003
1004 return Rotate( r, angle );
1005}
1006
1007template<typename Valtype,typename ValtypeT>
1008template<typename Valtype2>
1009inline Frame<Valtype,ValtypeT>& Frame<Valtype,ValtypeT>::Rotate( const VectorBundle<Valtype,Valtype2>& axis, Valtype2 angle ) noexcept
1010{
1011 P.Rotate( axis, angle );
1012 T.Rotate( axis.T, angle );
1013 N.Rotate( axis.T, angle );
1014 B.Rotate( axis.T, angle );
1015 return *this;
1016}
1017
1018template<typename Valtype,typename ValtypeT>
1020 N.Rotate( T, angle );
1021 B.Rotate( T, angle );
1022 return *this;
1023}
1024
1025template<typename Valtype,typename ValtypeT>
1027 return RotateTan( -std::atan2(up*N,up*B) );
1028}
1029
1030template<typename Valtype,typename ValtypeT>
1032 T.Rotate( N, angle );
1033 B.Rotate( N, angle );
1034 return *this;
1035}
1036
1037template<typename Valtype,typename ValtypeT>
1039 T.Rotate( B, angle );
1040 N.Rotate( B, angle );
1041 return *this;
1042}
1043
1044template<typename Valtype,typename ValtypeT> constexpr
1045inline bool Frame<Valtype,ValtypeT>::Equals( const Frame& frame, Valtype _epsilon_length, ValtypeT epsilon_lengthT ) const noexcept{
1046 return P.Equals( frame.P, _epsilon_length ) &&
1047 T.Equals( frame.T, epsilon_lengthT ) &&
1048 N.Equals( frame.N, epsilon_lengthT ) &&
1049 B.Equals( frame.B, epsilon_lengthT );
1050}
1051
1052template<typename Valtype,typename ValtypeT>
1054 P.Round(toDigit);
1055 T.Round(toDigit);
1056 N.Round(toDigit);
1057 B.Round(toDigit);
1058 return *this;
1059}
1060
1061template<typename Valtype,typename ValtypeT,typename Valtype2,typename ValtypeT2>
1063 static_assert( sizeof(Valtype) == sizeof(Valtype2), "Can not spatial_cast with different memory layout" );
1064 static_assert( sizeof(ValtypeT) == sizeof(ValtypeT2), "Can not spatial_cast with different memory layout" );
1065 return reinterpret_cast<Frame<Valtype,ValtypeT>&>(from);
1066}
1067
1068template<typename Valtype,typename ValtypeT,typename Valtype2,typename ValtypeT2>
1070 static_assert( sizeof(Valtype) == sizeof(Valtype2), "Can not spatial_cast with different memory layout" );
1071 static_assert( sizeof(ValtypeT) == sizeof(ValtypeT2), "Can not spatial_cast with different memory layout" );
1072 return reinterpret_cast<const Frame<Valtype,ValtypeT>&>(from);
1073}
1074
1075template<typename Valtype,typename ValtypeT> constexpr
1076inline bool operator==( const Frame<Valtype,ValtypeT>& frame1, const Frame<Valtype,ValtypeT>& frame2 ) noexcept{
1077 return !(frame1 != frame2);
1078}
1079
1080template<typename Valtype,typename ValtypeT> constexpr
1081inline bool operator!=( const Frame<Valtype,ValtypeT>& frame1, const Frame<Valtype,ValtypeT>& frame2 ) noexcept{
1082 return frame1.P != frame2.P ||
1083 frame1.T != frame2.T ||
1084 frame1.N != frame2.N ||
1085 frame1.B != frame2.B;
1086}
1087
1088template<typename Valtype1,typename ValtypeT1,typename Valtype2>
1090 Position<Valtype2> result{ v };
1091 frame.ToParent( result );
1092 return result;
1093}
1094
1095template<typename Valtype1,typename ValtypeT1,typename ValtypeT2>
1097 Vector<ValtypeT2> result{ v };
1098 frame.ToParent( result );
1099 return result;
1100}
1101
1102template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
1105 frame.ToParent( result );
1106 return result;
1107}
1108
1109template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
1112 frame.ToParent( result );
1113 return result;
1114}
1115
1116template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
1118 Frame<Valtype2,ValtypeT2> result{ f };
1119 frame.ToParent( result );
1120 return result;
1121}
1122
1123template<typename Valtype1,typename ValtypeT1,typename Valtype2>
1125 Sphere<Valtype2> result{ sp };
1126 frame.ToParent( result );
1127 return result;
1128}
1129
1130template<typename Valtype1,typename ValtypeT1,typename Valtype2,typename ValtypeT2>
1132 return frame = frame * f;
1133}
1134
1135template<typename Valtype,typename ValtypeT>
1136inline Frame<Valtype,ValtypeT>& operator*=( Frame<Valtype,ValtypeT>& frame, ValtypeT param ) noexcept{
1137 frame.T *= param;
1138 frame.N *= param;
1139 frame.B *= param;
1140 return frame;
1141}
1142
1143template<typename Valtype,typename ValtypeT>
1144auto Normalize( const Frame<Valtype,ValtypeT>& f ) noexcept -> std::pair<Vector<ValtypeT>,Frame<Valtype,decltype(ValtypeT{}/ValtypeT{})>>{
1145 auto normT = Normalize( f.T );
1146 auto normN = Normalize( f.N );
1147 auto normB = Normalize( f.B );
1148
1149 return std::make_pair(
1150 Vector<ValtypeT>{
1151 normT.first,
1152 normN.first,
1153 normB.first },
1154 Frame<Valtype,decltype(ValtypeT{}/ValtypeT{})>{
1155 f.P,
1156 normT.second,
1157 normN.second,
1158 normB.second } );
1159}
1160
1161} // namespace spat
Matrix template for arbitrary dimensions and value type.
Definition Matrix.h:63
Rotation matrix.
Definition Matrix.h:607
constexpr Value< Dimension< L/2, M/2, T/2 > > sqrt(Value< Dimension< L, M, T > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:670
constexpr Value< Dimension< 0, 0, 0 > > asin(Value< Dimension< 0, 0, 0 > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:706
constexpr Value< Dimension< 0, 0, 0 > > atan2(Value< Dimension< L, M, T > > y, Value< Dimension< L, M, T > > x) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:719
The namespace provides classes and methods for spatial computations.
Definition Box.h:32
Position< Valtype2 > operator*(const Frame< Valtype1, ValtypeT1 > &frame, const Position< Valtype2 > &p) noexcept
Frame operator.
Definition Frame.h:1089
Frame< Valtype2, ValtypeT2 > & operator*=(Frame< Valtype1, ValtypeT1 > &frame, const Frame< Valtype2, ValtypeT2 > &f) noexcept
right side multiplication of f to frame.
Definition Frame.h:1131
Frame< Valtype, ValtypeT > & spatial_cast(Frame< Valtype2, ValtypeT2 > &from) noexcept
Cast to Frame with different underlying value types.
Definition Frame.h:1062
Frame< Valtype, ValtypeT > VectorBundle3
Different name for Frame.
Definition Frame.h:380
constexpr Frame< Valtype, ValtypeT > Identity
Identity frame.
Definition Frame.h:385
constexpr Position< Valtype > Origin3D
Origin of coordinate system.
Definition Position.h:143
STL namespace.
Axis aligned box.
Definition Box.h:41
A Frame ("TNBFrame") describes a location in 3d space and an orientation using a right handed coordin...
Definition Frame.h:52
Frame & TransportTan(Valtype d) noexcept
constexpr Frame() noexcept=default
Does not initialize the members.
Frame & TransportNor(Valtype d) noexcept
bool IsOrthoNormal(ValtypeT epsilon_length=2 *std::numeric_limits< ValtypeT >::epsilon(), ValtypeT epsilon_angle=2 *std::numeric_limits< ValtypeT >::epsilon()) const noexcept
Frame & TransportBy(const Vector< Valtype > &v) noexcept
Vector< ValtypeT > B
Definition Frame.h:56
Frame & Rotate(const Vector< ValtypeT > &nr, ValtypeT angle) noexcept
Frame & TransportTo(Valtype d) noexcept
Frame & OrthoNormalize() noexcept
Position< Valtype > P
Definition Frame.h:53
Frame & Round(int toDigit) noexcept
Frame & RotateBin(ValtypeT angle) noexcept
Frame & RotateTan(ValtypeT angle) noexcept
constexpr bool Equals(const Frame &frame, Valtype epsilon_length=std::numeric_limits< Valtype >::epsilon(), ValtypeT epsilon_lengthT=std::numeric_limits< ValtypeT >::epsilon()) const noexcept
Vector< ValtypeT > N
Definition Frame.h:55
Frame & RotateNor(ValtypeT angle) noexcept
Vector< ValtypeT > T
Definition Frame.h:54
Frame & TransportBin(Valtype d) noexcept
Implements a 3D - position in cartesian coordinates.
Definition Position.h:46
Sphere with center and radius.
Definition Sphere.h:39
Implements a tangential space bundle.
Definition VectorBundle2.h:43
Implements a Vector bundle.
Definition VectorBundle.h:42
Implements a 3D - vector in cartesian coordinates.
Definition Vector.h:48
@ ez
Unit vector in z-direction.
Definition Vector.h:61
@ null
Vector with all parameters zeroed.
Definition Vector.h:58
@ ex
Unit vector in x-direction.
Definition Vector.h:59
@ ey
Unit vector in y-direction.
Definition Vector.h:60
auto Normalize() noexcept -> decltype(Valtype{}/Valtype{})
Normalizes the vector to length 1.
Definition Vector.h:487