19 #ifndef VSR_GENERIC_OP_H_INCLUDED
20 #define VSR_GENERIC_OP_H_INCLUDED
23 #include "../util/vsr_constants.h"
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] ) ) ) )
71 static auto Ortho( const TVec& v ) RETURNS (
72 ( v.template cast<
NEVec<DIM2> >() )
75 static auto Ortho3( const TVec& v ) RETURNS (
76 ( v.template cast<
NEVec<3>>() )
81 static VSR_PRECISION Val( VSR_PRECISION dist, const TVec & v ) {
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; }
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; }
108 constexpr VSR_PRECISION dot(X x){
112 template<
class X,
class ... XS>
113 constexpr VSR_PRECISION dot(X x, XS...xs){
114 return (x*x) + dot(xs...);
128 static auto dual(
const A& a ) RETURNS (
133 static auto undual(
const A& a ) RETURNS (
138 static auto duale(
const A& a ) RETURNS (
143 static auto unduale(
const A& a ) RETURNS (
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))
154 static constexpr
bool sign(
const A& a,
const A& b) {
155 return (a / b)[0] > 0 ? 1 : 0;
159 template<
class A>
static constexpr
bool sn(
const A& a,
const A& b){
164 template<
class A,
class B>
165 static constexpr
auto project(
const A& a,
const B& b) RETURNS (
170 template< class A, class B>
171 static constexpr auto
reject(const A& a, const B& b) RETURNS (
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) )
193 template<
class algebra>
247 static auto rot (
const A& b ) -> decltype( b + 1 ) {
249 VSR_PRECISION c = sqrt(- ( b.wt() ) );
250 VSR_PRECISION sc = -sin(c);
252 return b * sc + cos(c);
259 static auto rotor(
const A& b ) -> decltype( b + 1 ) {
269 template<
class algebra>
274 VSR_PRECISION t = r.template get<0>();
276 TBiv b = r.template cast<TBiv>();
278 VSR_PRECISION n = b.rnorm();
288 VSR_PRECISION s = atan2( n, t );
298 template<
class algebra>
307 VSR_PRECISION td = p.wt();
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; }
323 TBiv b = r.template cast<TBiv>();
324 VSR_PRECISION t = b.rnorm();
325 if (t == 0 )
return TBiv(1);
341 return TBiv ( log(r) * -2 ).norm();
352 TVec v = Op::dle( pl( r ) ) ;
353 VSR_PRECISION deg = iphi(r) * ( -180 / PI );
355 return TRot(deg, v[0], v[1], v[2]);
362 static auto axisAngle(
const A& r) RETURNS ( aa(r) )
368 template<class A, class B>
369 static auto trv ( const
Multivector<A,B>& a ) RETURNS (
370 a.template copy<
GATnv<A> >() + 1
377 template< class A > static auto transversor( const A& a ) RETURNS ( trv(a) )
394 template< typename ... T> static auto transversor( T ... v ) RETURNS ( trv(v...) )
400 template<class A, class B>
402 return (a.template copy<
GADrv<A> > () * -.5 ) + 1;
408 template<
class A>
static auto translator (
const A& a) RETURNS ( trs(a) )
414 template< typename ... Ts >
415 static auto trs ( Ts ... v ) ->
NTrs<sizeof...(Ts)+2> {
416 return (
NDrv<
sizeof...(Ts)+2>(v...) * -.5 ) + 1;
429 template<bits::type N,
class T>
431 return NDil<N>( cosh( t *.5 ), sinh( t * .5 ) );
436 template<
class T>
static constexpr
auto dilator( T t ) RETURNS ( dil(t) )
442 template<class A, class T>
450 template<
class A,
class T >
static constexpr
auto dilator (
const A& p, T t) RETURNS ( dil(p,t) )
459 static auto bst(const
GAPar<A>& tp) -> decltype( tp + 1 ) {
461 VSR_PRECISION norm; VSR_PRECISION
sn; VSR_PRECISION cn;
463 VSR_PRECISION td = tp.wt();
465 if (td < 0) { norm = sqrt( - td ); sn = -sin(norm) / norm; cn = cos(norm); }
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; }
469 return (tp * sn) + cn;
476 template<
class A>
static auto boost(
const A& a ) RETURNS ( bst(a) )
506 const
GAVec<A>& b ) -> decltype( (a*b) ) {
512 VSR_PRECISION s = ( a <= b )[0];
514 if ( a == b.conjugation() ){
516 if ( a == TVec::y || a == -TVec::y ) {
517 return rot( TBiv::xy * PIOVERTWO );
519 return rot( a ^ TVec::y * PIOVERTWO);
522 VSR_PRECISION ss = 2 * (s+1);
524 VSR_PRECISION n = ( ss >= 0 ? sqrt ( ss ) : -sqrt(-ss) );
528 if (!FERROR(n)) r /= n;
529 if ( r == TRot() ) {
return TRot(1); }
546 template<
class A,
class B >
552 return v.template copy< TVec >() + TOri( 1 ) + TInf( v.template copy< TVec >().wt() / 2.0 );
557 template<
class ... T>
558 static constexpr
NPnt<
sizeof...(T) + 2>
560 using TVEC =
NVec<
sizeof...(T)+2>;
561 using TORI =
NOri<
sizeof...(T)+2>;
562 using TINF =
NInf<
sizeof...(T)+2>;
564 return TVEC(v...) + TORI(1) + TINF( TVEC(v...).wt() / 2.0 );
569 template<
class ... T>
570 static constexpr
NPnt<
sizeof...(T) + 2>
572 using TVEC =
NVec<
sizeof...(T)+2>;
573 return null( TVEC(v...) );
584 template<
class ... T >
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);
593 template<
class ... T >
static auto dualSphere( VSR_PRECISION r, T ... v ) RETURNS ( dls(r, v...) )
599 template<class A, class B >
604 ( r > 0) ? s.template
get< bits::infinity< A::dim >() >() -= .5 * (r * r)
605 : s.template get< bits::infinity< A::dim >() >() += .5 * (r*r);
609 template<
class T >
static auto dualSphere(
const T& t, VSR_PRECISION r = 1.0 ) RETURNS ( dls(t, r) )
618 sphere( const S& v, VSR_PRECISION r = 1.0 ) RETURNS(
630 dls_pnt( const
GAPnt<A>& p, VSR_PRECISION r = 1.0 ) {
632 (r > 0) ? s.template
get< bits::infinity<A::dim>() >() -= .5 * (r * r)
633 : s.template get< bits::infinity<A::dim>() >() += .5 * (r*r);
640 template<
class A,
class B>
643 return ( s / (
GAInf<A>(-1) <= s ) ).template cast< GAPnt<A> >();
651 template<
class A,
class B>
662 static constexpr
typename A::space::point
664 return null ( cen ( s ) );
668 static constexpr
typename A::space::point
669 loc(
const A& s) {
return location(s); }
679 auto s =
typename A::space::infinity(1) <= r;
680 return ( ( r * r.inv() ) / ( s * s ) * ( (dual) ? -1.0 : 1.0 ) )[0];
685 static constexpr VSR_PRECISION
687 return sqrt ( fabs ( size(s,
false) ) );
689 template<
class T>
static constexpr VSR_PRECISION rad(
const T& t) {
return radius(t); }
697 VSR_PRECISION r = rad( s );
698 return (r==0) ? 10000 : 1.0 / rad(s);
706 static constexpr VSR_PRECISION
707 cur(
const T& t) {
return curvature(t); }
714 static constexpr VSR_PRECISION
716 return (dls * dls)[0];
722 static constexpr VSR_PRECISION
724 return ( (a <= b)[0] ) * -2.0;
726 template<
class A>
static constexpr VSR_PRECISION sqd(
const A& a,
const A& b) {
return squaredDistance(a,b); }
731 static constexpr VSR_PRECISION
733 return sqrt( fabs(sqd(a,b) ) );
735 template<
class A>
static constexpr VSR_PRECISION dist(
const A& a,
const A& b) {
return distance(a,b); }
742 static std::vector< GAPnt<A> >
745 std::vector< GAPnt<A> > pair;
747 VSR_PRECISION r = sqrt( fabs( ( pp <= pp )[0] ) );
774 static std::vector< GAPnt<A> >
777 for (
auto& i : tp) i = location(i);
790 VSR_PRECISION r = sqrt( fabs( ( pp <= pp )[0] ) );
794 GABst<A> bst = pp + ( bFirst ? r : -r );
796 return ( ( bst ) / d ).
template cast<
GAPnt<A> >();
804 static std::vector< GAPnt<A> >
806 return split( nc.dual() );
813 static constexpr
auto
814 direction(
const A& s ) RETURNS(
815 ( (
typename A::space::infinity(-1) <= s ) ^
typename A::space::infinity(1) )
820 template<class A> static constexpr auto dir( const A&s ) RETURNS( direction(s) )
827 static constexpr auto
828 carrier(const A& s) RETURNS(
829 s ^ typename A::space::infinity(1)
834 static constexpr auto car( const A&s ) RETURNS( carrier(s) )
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) ));
845 static constexpr
auto
846 sur(
const A& s) RETURNS ( surround(s) )
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 )
862 static constexpr auto
863 real(const A& s) RETURNS (
866 typename A::space::origin(-1) <=
Round::dir( s )
875 static constexpr auto
876 imag(const A& s) RETURNS (
879 typename A::space::origin(-1) <=
Round::dir( s )
888 static constexpr
GADls<A>
890 return GADls<A>( p <= (c^GAInf<A>(1) ) );
910 return split( produce(dls, flat),
true );
945 auto vec = TVEC::x.spin(
nga::Gen::rot( TBIV::xy.spin( rot ) * t/2.0 ) * rot );
947 return produce( sur( c ), vec );
954 return null( split( par_cir(c,t),
true) );
987 template<
class A,
class B>
995 template<
class A,
class B>
1011 return dual ? TPnt( ( p ^ f ) / f ) : TPnt ( ( p <= f ) / f );
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);
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();
1041 static constexpr
auto dlp(
const GAPnt<A>& pnt,
const GADrv<A>& drv) RETURNS (
1046 template<typename ...T>
1047 static constexpr
NLin<sizeof...(T)+2> line( T ... v ){
1052 template<
typename ...T>
1088 static constexpr
typename A::space::point
loc(
const A& s){
1089 return ( s /
typename A::space::infinity(-1) <= s );
1098 static constexpr
auto at(
const A& r,
const typename A::space::point& p) RETURNS(
1105 static typename A::value_t
wt(
const A& s){
1106 using TOri =
typename A::space::origin;
1117 template<
class Algebra,
class B>
1122 template<
class Algebra,
class B>
template<
class A>
1126 template<
class Algebra,
class B>
template<
class A>
1131 template<
class Algebra,
class B>
template<
class A>
1132 Multivector<Algebra,B> Multivector<Algebra,B>::trs(
const Multivector<Algebra,A>& t)
const{
1135 template<
class Algebra,
class B>
template<
class A>
1136 Multivector<Algebra,B> Multivector<Algebra,B>::translate(
const Multivector<Algebra,A>& t)
const{
1141 template<
class Algebra,
class B>
template<
class ... Ts>
1142 Multivector<Algebra,B> Multivector<Algebra,B>::trs(Ts ... v)
const{
1145 template<
class Algebra,
class B>
template<
class ... Ts>
1146 Multivector<Algebra,B> Multivector<Algebra,B>::translate(Ts ... v)
const{
1150 template<
class Algebra,
class B>
template<
class A>
1151 Multivector<Algebra,B> Multivector<Algebra,B>::trv(
const Multivector<Algebra,A>& t)
const{
1154 template<
class Algebra,
class B>
template<
class A>
1155 Multivector<Algebra,B> Multivector<Algebra,B>::transverse(
const Multivector<Algebra,A>& t)
const{
1159 template<
class Algebra,
class B>
template<
class ... Ts>
1160 Multivector<Algebra,B> Multivector<Algebra,B>::trv(Ts ... v)
const{
1163 template<
class Algebra,
class B>
template<
class ... Ts>
1164 Multivector<Algebra,B> Multivector<Algebra,B>::transverse(Ts ... v)
const{
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{
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{
1177 template<
class Algebra,
class B>
template <
class A>
1178 Multivector<Algebra,B> Multivector<Algebra,B>::bst(
const Multivector<Algebra,A>& t)
const{
1181 template<
class Algebra,
class B>
template <
class A>
1182 Multivector<Algebra,B> Multivector<Algebra,B>::boost(
const Multivector<Algebra,A>& t)
const{
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