versor  3.0
C++11 library for Geometric algebra
vsr_generic_op.h
Go to the documentation of this file.
1 
19 #ifndef VSR_GENERIC_OP_H_INCLUDED
20 #define VSR_GENERIC_OP_H_INCLUDED
21 
22 #include "vsr_multivector.h"
23 #include "../util/vsr_constants.h"
24 #include <vector>
25 
26 namespace vsr {
27 
28 
29 
30 /*-----------------------------------------------------------------------------
31  * Group Definitions for Doxygen...
32  *-----------------------------------------------------------------------------*/
33 
55 namespace nga{
56 
60 template<int DIM>
61 struct Proj{
62 
63  typedef NEVec<DIM> TVec;
64  typedef NEVec<DIM-1> OneDown;
65 
66  static auto Call( VSR_PRECISION dist, const TVec& v ) RETURNS (
67  ( Proj<DIM-1>::Call( dist, v.template cast<OneDown>() * ( dist / (dist - v[DIM-1] ) ) ) )
68  )
69 
70  template<int DIM2>
71  static auto Ortho( const TVec& v ) RETURNS (
72  ( v.template cast<NEVec<DIM2> >() )
73  )
74 
75  static auto Ortho3( const TVec& v ) RETURNS (
76  ( v.template cast<NEVec<3>>() )
77  )
78 
79 
80 
81  static VSR_PRECISION Val( VSR_PRECISION dist, const TVec & v ) {
82  return dist / (dist - v[DIM-1] ) * Proj<DIM-1>::Val(dist, OneDown(v) );
83  }
84  // static VSR_PRECISION Val( VSR_PRECISION dist, const Vec& v) {
85  // return Proj< DIM, 4, DIM==TARGET >::Call(dist, v);
86  // }
87 };
88 
89 template<>
90 struct Proj<3>{
91  typedef NEVec<3> TVec;
92  static TVec Call(VSR_PRECISION dist, const TVec& v) { return v; }
93  static VSR_PRECISION Val(VSR_PRECISION dist, const TVec & v ) { return 1.0; }
94  static TVec Ortho3( const TVec& v ) { return v; }
95 };
96 
97 //lift up to 3 from 2
98 template<>
99 struct Proj<2>{
100  typedef NEVec<3> TVec;
101  static TVec Call(VSR_PRECISION dist, const TVec& v) { return v; }
102  static VSR_PRECISION Val(VSR_PRECISION dist, const TVec & v ) { return 1.0; }
103  static TVec Ortho3( const TVec& v ) { return v; }
104 };
105 
106 
107  template< class X>
108  constexpr VSR_PRECISION dot(X x){
109  return x*x;
110 }
111 
112  template<class X, class ... XS>
113  constexpr VSR_PRECISION dot(X x, XS...xs){
114  return (x*x) + dot(xs...);
115  }
116 
117 
125 struct Op{
126 
127  template<class A>
128  static auto dual( const A& a ) RETURNS (
129  a.dual()
130  )
131 
132  template<class A>
133  static auto undual( const A& a ) RETURNS (
134  a.undual()
135  )
136 
137  template<class A>
138  static auto duale( const A& a ) RETURNS (
139  a.duale()
140  )
141 
142  template<class A>
143  static auto unduale( const A& a ) RETURNS (
144  a.unduale()
145  )
146 
147  template<class T> static auto dl( const T& t ) RETURNS ( dual(t) )
148  template<class T> static auto udl( const T& t) RETURNS ( udual(t) )
149  template<class T> static auto dle( const T& t) RETURNS (duale(t))
150  template<class T> static auto udle( const T& t) RETURNS (unduale(t))
151 
152 
153  template<class A>
154  static constexpr bool sign(const A& a, const A& b) {
155  return (a / b)[0] > 0 ? 1 : 0;
156  }
157 
159  template<class A> static constexpr bool sn(const A& a, const A& b){
160  return sign(a,b);
161  }
162 
164  template< class A, class B>
165  static constexpr auto project(const A& a, const B& b) RETURNS (
166  (a <= b ) / b
167  )
168 
169 
170  template< class A, class B>
171  static constexpr auto reject(const A& a, const B& b) RETURNS (
172  (a ^ b ) / b
173  )
174 
176  template< class A, class B>
177  static constexpr auto pj(const A& a, const B& b) RETURNS ( project(a,b) )
178  template< class A, class B>
179  static constexpr auto rj(const A& a, const B& b) RETURNS ( reject(a,b) )
180 
181 };
182 
183 
184 
189 struct Euc{
193  template<class algebra>
195  using up = typename algebra::up;
196  return GAVec<up>(v) + GAE<up>::e<up::Dim>(1.0);
197  }
198 
199 // template< bits::type N, class T >
200 // NEVec<N+1,T> hom(const NEVec<N,T>& v){
201 // return NEVec<N+1,T>(v) + NE<T>::e<N+1>(1.0);
202 // }
203 
204 
208 // template<class algebra>
209 // GAVec<typename algebra::> hom(const GAPnt< Algebra >& p){
210 // return NEVec<N-1,T>(p[0],p[1],p[2]) + NE<T>::e<N-1>(1.0);
211 // }
212 
213 // template<bits::type N, class T>
214 // NEVec<N-1, T> hom(const NPnt<N, T>& p){
215 // return NEVec<N-1,T>(p[0],p[1],p[2]) + NE<T>::e<N-1>(1.0);
216 // }
217 };
218 
219 
220 
240  struct Gen{
241 
242 
246  template<class A>
247  static auto rot ( const A& b ) -> decltype( b + 1 ) {
248  // printf("me");
249  VSR_PRECISION c = sqrt(- ( b.wt() ) );
250  VSR_PRECISION sc = -sin(c);
251  if (c != 0) sc /= c;
252  return b * sc + cos(c);
253  }
254 
258  template<class A>
259  static auto rotor( const A& b ) -> decltype( b + 1 ) {
260  return rot(b);
261  }
262 
263 
269  template<class algebra>
270  static auto log(const GARot<algebra>& r) -> GABiv<algebra> {
271 
272  using TBiv = GABiv< algebra >;
273 
274  VSR_PRECISION t = r.template get<0>(); //<--- Field Value from Rotor, or r[0]
275 
276  TBiv b = r.template cast<TBiv>();
277 
278  VSR_PRECISION n = b.rnorm();
279 
280  if (n <= 0) {
281  if (t < 0) {
282  return TBiv(PI);
283  } else {
284  return TBiv();
285  }
286  }
287 
288  VSR_PRECISION s = atan2( n, t );
289  return b * ( s / n);
290  }
291 
292 
298  template<class algebra>
299  static auto log(const GABst<algebra>& r) -> GAPar<algebra> {
300 
301  using TPar = GAPar<algebra>;
302 
303  VSR_PRECISION n;
304 
305  TPar p;
306  p = r; //extract 2-blade part
307  VSR_PRECISION td = p.wt(); //get scalar
308 
309  if (td > 0 ) { VSR_PRECISION s2 = sqrt(td); n = asinh( s2 ) / s2; }
310  else if ( td == 0 ) { n = 1; }
311  else if (td < 0 ) { VSR_PRECISION s2 = sqrt(-td); n = atan2(s2, r[0] ) / s2; }
312 
313  return p * n;
314 
315  }
316 
320  template< class A >
321  static auto pl( const GARot<A>& r) -> GABiv<A> {
322  using TBiv = GABiv<A>;
323  TBiv b = r.template cast<TBiv>();
324  VSR_PRECISION t = b.rnorm(); // use rnorm or norm here?
325  if (t == 0 ) return TBiv(1);
326  return b / t;
327  }
328 
332  template<class A> static auto plane( const A& r) -> GABiv<A>
333  { return pl(r); }
334 
338  template< class A >
339  static VSR_PRECISION iphi( const GARot<A>& r) {
340  using TBiv = GABiv<A>;
341  return TBiv ( log(r) * -2 ).norm();
342  }
343 
347  template< class A >
348  static auto aa (const GARot<A>& r) -> GARot<A> {
349  using TRot = GARot<A>;
350  using TVec = GAVec<A>;
351 
352  TVec v = Op::dle( pl( r ) ) ;
353  VSR_PRECISION deg = iphi(r) * ( -180 / PI );
354 
355  return TRot(deg, v[0], v[1], v[2]);
356  }
357 
361  template< class A >
362  static auto axisAngle( const A& r) RETURNS ( aa(r) )
363 
364 
368  template<class A, class B>
369  static auto trv ( const Multivector<A,B>& a ) RETURNS (
370  a.template copy< GATnv<A> >() + 1
371  )
372 
377  template< class A > static auto transversor( const A& a ) RETURNS ( trv(a) )
378 
379 
380  /*
381  Generate transversor as exponential of a direction vector
382  @param a tangent vector
383  */
384 
385  // template< typename ... T >
386  // auto trv ( T ... v ) -> NTrv<sizeof...(T)+2> {
387  // return ( NTnv<sizeof...(T)+2>(v...) ) + 1;
388  // }
389 
394  template< typename ... T> static auto transversor( T ... v ) RETURNS ( trv(v...) )
395 
400  template<class A, class B>
401  static GATrs<A> trs ( const Multivector<A,B>& a ) {
402  return (a.template copy< GADrv<A> > () * -.5 ) + 1;
403  }
408  template<class A> static auto translator (const A& a) RETURNS ( trs(a) )
409 
410 
414  template< typename ... Ts >
415  static auto trs ( Ts ... v ) -> NTrs<sizeof...(Ts)+2> {
416  return ( NDrv<sizeof...(Ts)+2>(v...) * -.5 ) + 1;
417  }
422  // template<typename ... T> auto translator(T ... v) RETURNS ( trs( v...) )
423 
429  template<bits::type N, class T>
430  static constexpr auto dil( T t) -> NDil<N> {
431  return NDil<N>( cosh( t *.5 ), sinh( t * .5 ) );
432  }
436  template<class T> static constexpr auto dilator( T t ) RETURNS ( dil(t) )
437 
438 
442  template<class A, class T>
443  static auto dil(const GAPnt<A>& p, T t) -> GATsd<A> {
444  return GATsd<A>( GADil<A>( cosh( t*.5 ), sinh( t*.5 ) ) ).trs( p );
445  }
450  template< class A, class T > static constexpr auto dilator ( const A& p, T t) RETURNS ( dil(p,t) )
451 
452 
458  template<class A>
459  static auto bst(const GAPar<A>& tp) -> decltype( tp + 1 ) {
460 
461  VSR_PRECISION norm; VSR_PRECISION sn; VSR_PRECISION cn;
462 
463  VSR_PRECISION td = tp.wt();
464 
465  if (td < 0) { norm = sqrt( - td ); sn = -sin(norm) / norm; cn = cos(norm); } //note, changed to cos from cosh
466  else if (td > 0) { norm = sqrt(td); sn = -sinh(norm) / norm; cn = cosh(norm); }
467  else if (td == 0) { norm = 0; sn = -1; cn = 1; }
468 
469  return (tp * sn) + cn;
470  }
476  template<class A> static auto boost( const A& a ) RETURNS ( bst(a) )
477 
478  // /*!
479  // Generate general rotation as exponential of anonymous
480  // Implemented from "Square Root and Logarithm of Rotors. . ." by Dorst and Valkenburg, 2011
481  // @param Point Pair generator
482  // */
483  // template<bits::type DIM, class A>
484  // auto gen(const CGAMultivector<DIM,A>& tp) -> decltype( tp + 1 ) {
485  //
486  // VSR_PRECISION norm; VSR_PRECISION sn; VSR_PRECISION cn;
487  //
488  // VSR_PRECISION td = tp.wt();
489  //
490  // if (td < 0) { norm = sqrt( - td ); sn = -sin(norm) / norm; cn = cosh(norm); }
491  // else if (td > 0) { norm = sqrt(td); sn = -sinh(norm) / norm; cn = cosh(norm); }
492  // else if (td == 0) { norm = 0; sn = -1; cn = 1; }
493  //
494  // return (tp * sn) + cn;
495  // }
496 
497 
498 
499  //feed in vectors!
503  template<class A>
504  static auto ratio(
505  const GAVec<A>& a,
506  const GAVec<A>& b ) -> decltype( (a*b) ) {
507 
508  using TVec = GAVec<A>;//typename NVec<DIM>::Space::Vec;
509  using TBiv = GABiv<A>;//typename NVec<DIM>::Space::Biv;
510  using TRot = GARot<A>;//decltype( (a^b) + 1);
511 
512  VSR_PRECISION s = ( a <= b )[0];
513  //180 degree check
514  if ( a == b.conjugation() ){//fabs ((a<=b)[0]) > .999999) {//a == b.conjugation() ) {
515  //printf("180!\n");
516  if ( a == TVec::y || a == -TVec::y ) {
517  return rot( TBiv::xy * PIOVERTWO );
518  }
519  return rot( a ^ TVec::y * PIOVERTWO); //mind the ordering of blades
520  }
521 
522  VSR_PRECISION ss = 2 * (s+1);
523  //VSR_PRECISION n = ( ss >= 0 ? sqrt ( ss ) : 0 );
524  VSR_PRECISION n = ( ss >= 0 ? sqrt ( ss ) : -sqrt(-ss) );
525 
526  TRot r = ( b * a ) ; //cout << r << endl;
527  r[0] += 1;
528  if (!FERROR(n)) r /= n;
529  if ( r == TRot() ) { return TRot(1); }//else cout << r << endl; //printf("0 in Gen::ratio\n");
530  return r;
531  }
532 
533  };
534 
535 
536 
537 
542  struct Round {
543 
546  template< class A, class B >
547  static constexpr GAPnt<A>
548  null( const Multivector<A,B>& v ) {
549  using TVec = GAVec<A>;
550  using TOri = GAOri<A>;
551  using TInf = GAInf<A>;
552  return v.template copy< TVec >() + TOri( 1 ) + TInf( v.template copy< TVec >().wt() / 2.0 );
553  }
554 
557  template< class ... T>
558  static constexpr NPnt< sizeof...(T) + 2>
559  null( T ... v) {
560  using TVEC = NVec<sizeof...(T)+2>;
561  using TORI = NOri<sizeof...(T)+2>;
562  using TINF = NInf<sizeof...(T)+2>;
563 
564  return TVEC(v...) + TORI(1) + TINF( TVEC(v...).wt() / 2.0 );
565  }
566 
569  template< class ... T>
570  static constexpr NPnt< sizeof...(T) + 2>
571  point( T ... v) {
572  using TVEC = NVec<sizeof...(T)+2>;
573  return null( TVEC(v...) );
574  }
575 
576 
584  template< class ... T >
585  static auto
586  dls(VSR_PRECISION r, T ... v ) -> NPnt< sizeof...(T) + 2 > {
587  using TPNT = NPnt< sizeof...(T) + 2 >;
588  TPNT s = point(v...);
589  ( r > 0) ? s.template get< bits::infinity< sizeof...(T) + 2>() >() -= .5 * (r * r)
590  : s.template get< bits::infinity< sizeof...(T) + 2 >() >() += .5 * (r*r);
591  return s;
592  }
593  template< class ... T > static auto dualSphere( VSR_PRECISION r, T ... v ) RETURNS ( dls(r, v...) )
594 
595 
599  template<class A, class B >
600  static auto
601  dls( const Multivector<A,B>& v, VSR_PRECISION r = 1.0 ) -> GAPnt<A>{
602 
603  auto s = null(v);
604  ( r > 0) ? s.template get< bits::infinity< A::dim >() >() -= .5 * (r * r)
605  : s.template get< bits::infinity< A::dim >() >() += .5 * (r*r);
606  return s;
607  }
608 
609  template< class T > static auto dualSphere( const T& t, VSR_PRECISION r = 1.0 ) RETURNS ( dls(t, r) )
610 
611 
616  template< class S >
617  static auto
618  sphere( const S& v, VSR_PRECISION r = 1.0 ) RETURNS(
619  dls( v, r )
620  )
621 
622 
623 
628  template< class A >
629  static GADls<A>
630  dls_pnt( const GAPnt<A>& p, VSR_PRECISION r = 1.0 ) {
631  GAPnt<A> s = p;
632  (r > 0) ? s.template get< bits::infinity<A::dim>() >() -= .5 * (r * r)
633  : s.template get< bits::infinity<A::dim>() >() += .5 * (r*r);
634  return s;
635  }
636 
640  template<class A, class B>
641  static constexpr GAPnt<A>
643  return ( s / ( GAInf<A>(-1) <= s ) ).template cast< GAPnt<A> >();
644  }
645 
651  template<class A, class B>
652  static constexpr GAPnt<A>
653  cen( const Multivector<A,B>& s) {
654  return center(s);
655  }
656 
657 
661  template<class A>
662  static constexpr typename A::space::point
663  location(const A& s) {
664  return null ( cen ( s ) );
665  }
666 
667  template<class A>
668  static constexpr typename A::space::point
669  loc(const A& s) { return location(s); }
670 
671 
676  template<class A>
677  static VSR_PRECISION
678  size( const A& r, bool dual){
679  auto s = typename A::space::infinity(1) <= r;
680  return ( ( r * r.inv() ) / ( s * s ) * ( (dual) ? -1.0 : 1.0 ) )[0];
681  }
684  template<class T>
685  static constexpr VSR_PRECISION
686  radius( const T& s ){
687  return sqrt ( fabs ( size(s, false) ) );
688  }
689  template<class T> static constexpr VSR_PRECISION rad( const T& t) { return radius(t); }
690 
694  template<class A>
695  static VSR_PRECISION
696  curvature(const A& s){
697  VSR_PRECISION r = rad( s );
698  return (r==0) ? 10000 : 1.0 / rad(s);
699  }
700 
705  template<class T>
706  static constexpr VSR_PRECISION
707  cur( const T& t) { return curvature(t); }
708 
709 
713  template<class A>
714  static constexpr VSR_PRECISION
715  dsize( const GAPnt<A>& dls ){
716  return (dls * dls)[0];
717  }
718 
721  template<class A>
722  static constexpr VSR_PRECISION
723  squaredDistance(const GAPnt<A>& a, const GAPnt<A> b){
724  return ( (a <= b)[0] ) * -2.0;
725  }
726  template< class A> static constexpr VSR_PRECISION sqd( const A& a, const A& b) { return squaredDistance(a,b); }
727 
728 
730  template<class A>
731  static constexpr VSR_PRECISION
732  distance(const GAPnt<A>& a, const GAPnt<A> b){
733  return sqrt( fabs(sqd(a,b) ) );
734  }
735  template< class A> static constexpr VSR_PRECISION dist( const A& a, const A& b) { return distance(a,b); }
736 
741  template<class A>
742  static std::vector< GAPnt<A> >
743  split(const GAPar<A>& pp){
744 
745  std::vector< GAPnt<A> > pair;
746 
747  VSR_PRECISION r = sqrt( fabs( ( pp <= pp )[0] ) );
748 
749  //dual line in 2d, dual plane in 3d
750  auto d = GAInf<A>(-1) <= pp;
751 
752  GABst<A> bstA; bstA = pp;
753  GABst<A> bstB; bstB = pp;
754 
755  bstA += GASca<A>(r);
756  bstB -= GASca<A>(r);
757 
758  GAPnt<A> pA;
759  pA = ( bstA ) / d;
760  GAPnt<A> pB;
761  pB = ( bstB ) / d;
762 
763  pair.push_back(pA);
764  pair.push_back(pB);
765 
766  return pair;
767  }
768 
773  template<class A>
774  static std::vector< GAPnt<A> >
775  splitLocation(const GAPar<A>& pp){
776  auto tp = split(pp);
777  for (auto& i : tp) i = location(i);
778  return tp;
779  }
780 
786  template<class A>
787  static GAPnt<A>
788  split(const GAPar<A>& pp, bool bFirst){
789 
790  VSR_PRECISION r = sqrt( fabs( ( pp <= pp )[0] ) );
791 
792  auto d = GAInf<A>(-1) <= pp;
793 
794  GABst<A> bst = pp + ( bFirst ? r : -r );
795 
796  return ( ( bst ) / d ).template cast< GAPnt<A> >();
797 
798  }
799 
803  template<class A>
804  static std::vector< GAPnt<A> >
805  split( const GACir<A>& nc ){
806  return split( nc.dual() );
807  }
808 
812  template<class A>
813  static constexpr auto
814  direction( const A& s ) RETURNS(
815  ( ( typename A::space::infinity(-1) <= s ) ^ typename A::space::infinity(1) )
816  )
817 
820  template<class A> static constexpr auto dir( const A&s ) RETURNS( direction(s) )
821 
822 
826  template<class A>
827  static constexpr auto
828  carrier(const A& s) RETURNS(
829  s ^ typename A::space::infinity(1)
830  )
833  template<class A>
834  static constexpr auto car( const A&s ) RETURNS( carrier(s) )
835 
837  template<class A>
838  static constexpr typename A::space::dual_sphere
839  surround( const A& s) {
840  return typename A::space::dual_sphere( s / ( s ^ typename A::space::infinity(1) ));
841  }
842 
844  template<class A>
845  static constexpr auto
846  sur( const A& s) RETURNS ( surround(s) )
847 
848 
852  template<class A, class S>
853  static constexpr auto
854  produce(const A& dls, const S& flat) RETURNS (
855  dls ^ ( ( dls <= ( flat.inv() * typename A::space::infinity(1) ) ) * -1.0 )
856  )
857 
861  template<class A>
862  static constexpr auto
863  real(const A& s) RETURNS (
864  produce(
865  Round::dls( Round::loc( s ), -Round::rad( Round::sur( s ) ) ),
866  typename A::space::origin(-1) <= Round::dir( s )
867  )
868  )
869 
870 
874  template<class A>
875  static constexpr auto
876  imag(const A& s) RETURNS (
877  produce(
878  Round::dls( Round::loc( s ), Round::rad( Round::sur( s ) ) ),
879  typename A::space::origin(-1) <= Round::dir( s )
880  )
881  )
887  template<class A>
888  static constexpr GADls<A>
889  at( const GADls<A> & c, const GADls<A>& p) {
890  return GADls<A>( p <= (c^GAInf<A>(1) ) );
891  }
892 
893 // /*!
894 // Direct Round From coordinates and Euclidean Bivector
895 // Note: round will be imaginary if dual sphere is real . . .
896 // */
897 // template<bits::type DIM, class B, class A>
898 // auto round(const CGAMultivector<DIM, B>& s, const A& flat, VSR_PRECISION radius=1.0) RETURNS (
899 // round( dls(s, radius*-1.0), flat );
900 // )
901 
902 
903 
904 
908  template<class A>
909  static constexpr GAPnt<A> pnt(const GADls<A> & dls, const GAVec<A>& flat){
910  return split( produce(dls, flat), true ); // cout << "y" << endl;
911  }
915  // template<class A
916 
917 
918 
919 
923  template<class A>
924  static GAVec<A>
925  vec(const GACir<A>& c, VSR_PRECISION theta = 0){
926  using TBIV = GABiv<A>;
927 
928  GADll<A> axis = (GAInf<A>(1) <= c).runit();
929  return GAVec<A>::x.sp( nga::Gen::ratio( TBIV::xz.duale(), TBIV(axis).duale() ) * nga::Gen::rot(TBIV::xz * theta) );
930  }
931 
932 
934  template<class A>
935  static GAPar<A>
936  par_cir(const GACir<A>& c, VSR_PRECISION t) {
937  using TBIV = GABiv<A>;
938  using TVEC = GAVec<A>;
939 
940  //NDll<DIM> axis = (NInf<DIM>(-1) <= c).runit();
941  //NRot<DIM> rot = Gen::ratio( TBIV::xz.duale(), TBIV(axis).duale() );
942  // NVec<DIM> vec = NVec<DIM>::x.sp( rot * Gen::rot(TBIV::xz * t/2.0)); //BIG CHANGE . . .
943  auto normal = TVEC( Round::carrier(c).dual() ).unit();
944  auto rot = nga::Gen::ratio( TVEC::z, normal );
945  auto vec = TVEC::x.spin( nga::Gen::rot( TBIV::xy.spin( rot ) * t/2.0 ) * rot );
946 
947  return produce( sur( c ), vec );
948  }
949 
951  template<class A>
952  static GAPnt<A>
953  pnt_cir(const GACir<A>& c, VSR_PRECISION t) {
954  return null( split( par_cir(c,t), true) );
955  }
956 
957 
959  /* template<bits::type DIM> */
960  /* NPnt<DIM> */
961  /* pointOnCircle(const NCir<DIM>& c, VSR_PRECISION t){ */
962  /* return null( split( par_cir(c,t), true) ); */
963  /* } */
964 
965 
966 
967  /* template<bits::type DIM> */
968  /* NPnt<DIM> pnt_dls( */
969 
970 
971  };
972 
973 
981  struct Flat {
982 
987  template<class A,class B>
988  static constexpr auto direction( const Multivector<A,B>& f) RETURNS(
989  GAInf<A>(-1) <= f
990  )
991 
995  template<class A,class B>
996  static constexpr auto dir( const Multivector<A,B>& f) RETURNS(
997  direction(f)
998  )
999 
1000 
1008  template<class A>
1009  static constexpr typename A::space::Pnt location(const A& f, const typename A::space::Pnt& p, bool dual){
1010  using TPnt = typename A::space::Pnt;
1011  return dual ? TPnt( ( p ^ f ) / f ) : TPnt ( ( p <= f ) / f );
1012  }
1013 
1014 
1024  template<class A, class P>
1025  static constexpr P loc(const A& f, const P& p, bool dual){
1026  return location(f,p,dual);
1027  }
1028 
1034  template<class A>
1035  static constexpr typename A::value_t wt(const A& f, bool bDual){
1036  using TOri = typename A::space::origin;
1037  return bDual ? ( TOri(1) <= dir( f.undual() ) ).wt() : ( TOri(1) <= dir(f) ).wt();
1038  }
1040  template<class A>
1041  static constexpr auto dlp( const GAPnt<A>& pnt, const GADrv<A>& drv) RETURNS (
1042  pnt <= drv
1043  )
1044 
1045 
1046  template<typename ...T>
1047  static constexpr NLin<sizeof...(T)+2> line( T ... v ){
1048  return nga::Round::null( NVec<sizeof...(T)+2>() ) ^ nga::Round::null(v...) ^ NInf<sizeof...(T)+2>(1);
1049  }
1050 
1052  template<typename ...T>
1053  static constexpr NCir<sizeof...(T)+2> dline( T ... v ){
1054  return nga::Round::null( NVec<sizeof...(T)+2>() ) ^ nga::Round::null(v...) ^ nga::Round::dls(NVec<sizeof...(T)+2>(), 1.0 );
1055  }
1056 
1057 
1058  };
1059 
1060 
1061 
1069  struct Tangent {
1070 
1071 // /*! Direction of Tangent Element (similar formulation to Rounds)
1072 // @ingroup direction
1073 //
1074 // @param a Direct Tangent Element
1075 // @return @ref direction type
1076 // */
1077 // template <class A>
1078 // static constexpr auto dir (const A& a) RETURNS (
1079 // ( typename A::space::infinity(-1) <= a ) ^ typename A::space::infinity(1)
1080 // )
1081 //
1087  template< class A >
1088  static constexpr typename A::space::point loc( const A& s){
1089  return ( s / typename A::space::infinity(-1) <= s );
1090  }
1091 
1097  template< class A >
1098  static constexpr auto at( const A& r, const typename A::space::point& p) RETURNS(
1099  p <= r.inv()
1100  )
1101 
1104  template<class A>
1105  static typename A::value_t wt(const A& s){
1106  using TOri = typename A::space::origin;
1107  return ( TOri(1) <= Round::dir(s) ).wt();
1108  }
1109 
1110  };
1111 
1112 }//nga::
1113 
1114  //------------------------------------------
1115 
1116  //METHODS (MOTORS IMPLEMENTED SEPARATELY, IN SPECIFIC INSTANTIATIONS)
1117  template<class Algebra, class B>
1119  return nga::Round::null(*this);
1120  }
1121 
1122  template<class Algebra, class B> template<class A>
1124  return this->sp( nga::Gen::rot(t) );
1125  }
1126  template<class Algebra, class B> template<class A>
1127  Multivector<Algebra,B> Multivector<Algebra,B>::rotate(const Multivector<Algebra,A>& t) const{
1128  return this->sp( nga::Gen::rot(t) );
1129  }
1130 
1131  template<class Algebra, class B> template<class A>
1132  Multivector<Algebra,B> Multivector<Algebra,B>::trs(const Multivector<Algebra,A>& t) const{
1133  return this->sp( nga::Gen::trs(t) );
1134  }
1135  template<class Algebra, class B> template<class A>
1136  Multivector<Algebra,B> Multivector<Algebra,B>::translate(const Multivector<Algebra,A>& t) const{
1137  return this->sp( nga::Gen::trs(t) );
1138  }
1139 
1140 
1141  template<class Algebra, class B> template<class ... Ts>
1142  Multivector<Algebra,B> Multivector<Algebra,B>::trs(Ts ... v) const{
1143  return this->sp( nga::Gen::trs( GADrv<Algebra>(v...) ) );
1144  }
1145  template<class Algebra, class B> template<class ... Ts>
1146  Multivector<Algebra,B> Multivector<Algebra,B>::translate(Ts ... v) const{
1147  return this->sp( nga::Gen::trs( GADrv<Algebra>(v...) ) );
1148  }
1149 
1150  template<class Algebra, class B> template<class A>
1151  Multivector<Algebra,B> Multivector<Algebra,B>::trv(const Multivector<Algebra,A>& t) const{
1152  return this->sp( nga::Gen::trv(t) );
1153  }
1154  template<class Algebra, class B> template<class A>
1155  Multivector<Algebra,B> Multivector<Algebra,B>::transverse(const Multivector<Algebra,A>& t) const{
1156  return this->sp( nga::Gen::trv(t) );
1157  }
1158 
1159  template<class Algebra, class B> template<class ... Ts>
1160  Multivector<Algebra,B> Multivector<Algebra,B>::trv(Ts ... v) const{
1161  return this->sp( nga::Gen::trv( GATrv<Algebra>(v...) ) );
1162  }
1163  template<class Algebra, class B> template<class ... Ts>
1164  Multivector<Algebra,B> Multivector<Algebra,B>::transverse(Ts ... v) const{
1165  return this->sp( nga::Gen::trv( GATrv<Algebra>(v...) ) );
1166  }
1167 
1168  template<class Algebra, class B> template<class A>
1169  Multivector<Algebra,B> Multivector<Algebra,B>::dil(const Multivector<Algebra,A>& s, VSR_PRECISION t) const{
1170  return this->sp( nga::Gen::dil(s,t) );
1171  }
1172  template<class Algebra, class B> template<class A>
1173  Multivector<Algebra,B> Multivector<Algebra,B>::dilate(const Multivector<Algebra,A>& s, VSR_PRECISION t) const{
1174  return this->sp( nga::Gen::dil(s,t) );
1175  }
1176 
1177  template<class Algebra, class B> template <class A>
1178 Multivector<Algebra,B> Multivector<Algebra,B>::bst( const Multivector<Algebra,A>& t) const{
1179  return this -> sp ( nga::Gen::bst(t) );
1180 }
1181 template<class Algebra, class B> template <class A>
1182 Multivector<Algebra,B> Multivector<Algebra,B>::boost( const Multivector<Algebra,A>& t) const{
1183  return this -> sp ( nga::Gen::bst(t) );
1184 }
1185 
1186 
1187 
1188 } //vsr::
1189 
1190 #endif
static constexpr GAPnt< A > null(const Multivector< A, B > &v)
Null Point from Arbitrary Multivector.
Definition: vsr_generic_op.h:548
static GAPar< A > par_cir(const GACir< A > &c, VSR_PRECISION t)
Point Pair on Direct Circle at angle t.
Definition: vsr_generic_op.h:936
static constexpr VSR_PRECISION radius(const T &s)
Radius of Round.
Definition: vsr_generic_op.h:686
static A::value_t wt(const A &s)
Weight of Tangent Element.
Definition: vsr_generic_op.h:1105
static auto dls(VSR_PRECISION r, T...v) -> NPnt< sizeof...(T)+2 >
Dual Sphere from Radius FIRST and Coordinate Center.
Definition: vsr_generic_op.h:586
static auto ratio(const GAVec< A > &a, const GAVec< A > &b) -> decltype((a *b))
Generate general rotation as exponential of anonymous Implemented from "Square Root and Logarithm of ...
Definition: vsr_generic_op.h:504
static constexpr VSR_PRECISION squaredDistance(const GAPnt< A > &a, const GAPnt< A > b)
Squared distance between two points.
Definition: vsr_generic_op.h:723
static GAPnt< A > split(const GAPar< A > &pp, bool bFirst)
Split a point pair.
Definition: vsr_generic_op.h:788
static constexpr A::space::point loc(const A &s)
Direction of Tangent Element (similar formulation to Rounds)
Definition: vsr_generic_op.h:1088
static constexpr auto dil(T t) -> NDil< N >
Generate translation as exponential of a direction vector.
Definition: vsr_generic_op.h:430
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
static auto plane(const A &r) -> GABiv< A >
Normalized plane of rotation from Rotor.
Definition: vsr_generic_op.h:332
static constexpr auto reject(const A &a, const B &b) -> auto
Rejection of A from B.
Multivector< algebra, typename algebra::vector_basis > null() const
Conformal Mapping \(\boldsymbol(x)\to n_o + \boldsymbol{x} + \boldsymbol{x}^2n_\infty \) ...
Definition: vsr_generic_op.h:1118
static GAVec< A > vec(const GACir< A > &c, VSR_PRECISION theta=0)
Direct Point From Dual Sphere and Euclidean Carrier Flat.
Definition: vsr_generic_op.h:925
static constexpr auto dir(const A &s) -> auto
Direction of Round Element (shorthand)
algebra< typename metric::up, value_t > up
Next Higher Algebra over the same field.
Definition: vsr_algebra.h:233
static GAPnt< A > pnt_cir(const GACir< A > &c, VSR_PRECISION t)
Point on Circle at angle t.
Definition: vsr_generic_op.h:953
Definition: vsr_multivector.h:469
static constexpr A::space::point location(const A &s)
Location of A Round Element (normalized) (Shorthand)
Definition: vsr_generic_op.h:663
static VSR_PRECISION size(const A &r, bool dual)
Squared Size of a General Round Element (could be negative)
Definition: vsr_generic_op.h:678
static constexpr auto carrier(const A &s) -> auto
Carrier Flat of Direct Round Element.
Operations on Round types (Points, Point Pairs, Circles, Spheres, N-Spheres)
Definition: vsr_generic_op.h:542
static constexpr VSR_PRECISION distance(const GAPnt< A > &a, const GAPnt< A > b)
Distance between points a and b.
Definition: vsr_generic_op.h:732
static std::vector< GAPnt< A > > split(const GACir< A > &nc)
Split A Circle into its dual point pair poles.
Definition: vsr_generic_op.h:805
NEVec< DIM > TVec
ND Vector Type.
Definition: vsr_generic_op.h:63
static constexpr P loc(const A &f, const P &p, bool dual)
Location of Flat A closest to Point p (shorthand)
Definition: vsr_generic_op.h:1025
static GATrs< A > trs(const Multivector< A, B > &a)
Generate translation from any type as exponential of a direction vector.
Definition: vsr_generic_op.h:401
static auto aa(const GARot< A > &r) -> GARot< A >
Axis Angle from Rotor (WARNING NOT GENERIC)
Definition: vsr_generic_op.h:348
static auto rot(const A &b) -> decltype(b+1)
ND Rotor from Bivector b.
Definition: vsr_generic_op.h:247
static auto bst(const GAPar< A > &tp) -> decltype(tp+1)
Generate Boost as exponential of a Point Pair Implemented from "Square Root and Logarithm of Rotors...
Definition: vsr_generic_op.h:459
static std::vector< GAPnt< A > > split(const GAPar< A > &pp)
Split Points from Point Pair.
Definition: vsr_generic_op.h:743
Generic ND Transformations and their Generators.
Definition: vsr_generic_op.h:240
static auto pl(const GARot< A > &r) -> GABiv< A >
Normalized plane of rotation from Rotor.
Definition: vsr_generic_op.h:321
static constexpr A::space::Pnt location(const A &f, const typename A::space::Pnt &p, bool dual)
Location of Flat A closest to Point p.
Definition: vsr_generic_op.h:1009
static constexpr auto pj(const A &a, const B &b) -> auto
Shorthand Proj and Rejection.
static auto log(const GARot< algebra > &r) -> GABiv< algebra >
Get Bivector Generator from a Rotor (Conformal or Euclidean )
Definition: vsr_generic_op.h:270
static VSR_PRECISION iphi(const GARot< A > &r)
Angle of Rotation from Rotor.
Definition: vsr_generic_op.h:339
static constexpr GAPnt< A > center(const Multivector< A, B > &s)
Simple Center of A Round Element (not normalized – use loc or location method)
Definition: vsr_generic_op.h:642
static constexpr auto project(const A &a, const B &b) -> auto
Projection of A onto B.
static constexpr A::value_t wt(const A &f, bool bDual)
Weight of Flat.
Definition: vsr_generic_op.h:1035
Generic ND Operations On Flat Typese.g.
Definition: vsr_generic_op.h:981
static constexpr VSR_PRECISION cur(const T &t)
Curvature of Round.
Definition: vsr_generic_op.h:707
static constexpr NCir< sizeof...(T)+2 > dline(T...v)
Direct hyperbolic d-Line at origin with coordinate v ...
Definition: vsr_generic_op.h:1053
static constexpr NPnt< sizeof...(T)+2 > null(T...v)
Or Null Point from Coordinates (x,y,z,...)
Definition: vsr_generic_op.h:559
static GAVec< typename algebra::up > hom(const GAVec< algebra > &v)
Homegenize an ND Euclidean Vector (add a dimension with weight of 1.0)
Definition: vsr_generic_op.h:194
NEVec< DIM-1 > OneDown
Next Projection Down.
Definition: vsr_generic_op.h:64
the versor library namespace
Definition: vsr_algebra.h:29
Multivector rot(const MultivectorB< B > &b) const
Generic ND Operations on a Tangent.
Definition: vsr_generic_op.h:1069
static std::vector< GAPnt< A > > splitLocation(const GAPar< A > &pp)
Split Points from Point Pair and normalize.
Definition: vsr_generic_op.h:775
static constexpr VSR_PRECISION dsize(const GAPnt< A > &dls)
Squared Size of Normalized Dual Sphere (faster than general case)
Definition: vsr_generic_op.h:715
Projection fron ND Euclidean down to 3D.
Definition: vsr_generic_op.h:61
NPnt< 5 > Pnt
Point
Definition: vsr_cga3D_types.h:72
Operations on All Types.
Definition: vsr_generic_op.h:125
static auto trv(const Multivector< A, B > &a) -> auto
Generate Local Boost at origin as exponential of a TangentVector vsr::GATnv
static auto log(const GABst< algebra > &r) -> GAPar< algebra >
Get Pair Generator from a Conformal Boost.
Definition: vsr_generic_op.h:299
static VSR_PRECISION curvature(const A &s)
Curvature of Round.
Definition: vsr_generic_op.h:696
static constexpr bool sign(const A &a, const A &b)
Sign of A with Respect to B.
Definition: vsr_generic_op.h:154
static constexpr GAPnt< A > pnt(const GADls< A > &dls, const GAVec< A > &flat)
Direct Round From coordinates and Euclidean Bivector Note: round will be imaginary if dual sphere is ...
Definition: vsr_generic_op.h:909
Operations on Euclidean Types.
Definition: vsr_generic_op.h:189
Multivector rotate(const MultivectorB< B > &b) const
static constexpr NPnt< sizeof...(T)+2 > point(T...v)
Null Point from Coordinates.
Definition: vsr_generic_op.h:571
static auto rotor(const A &b) -> decltype(b+1)
ND Rotor from Bivector b.
Definition: vsr_generic_op.h:259
static constexpr bool sn(const A &a, const A &b)
Sign of A with Respect to B (short hand)
Definition: vsr_generic_op.h:159
generic multivector class, templated on a geometric algebra and a field
static constexpr GAPnt< A > cen(const Multivector< A, B > &s)
Simple Center of A Round Element (shorthand)
Definition: vsr_generic_op.h:653