versor  3.0
C++11 library for Geometric algebra
vsr_rigid.h
1 /*
2  * =====================================================================================
3  *
4  * Filename: vsr_rigid.h
5  *
6  * Description: rigid body constraints using pointer networks
7  *
8  * Version: 1.0
9  * Created: 07/10/2014 15:53:03
10  * Revision: none
11  * Compiler: gcc
12  *
13  * Author: Pablo Colapinto (), gmail -> wolftype
14  * Organization: pretty awesome
15  *
16  * =====================================================================================
17  */
18 
19 
20  /*
21  @file Rigid Body Sphere-based Constraint Networks
22 
23  @sa vsr_fold.h
24 
25  @todo major clean up
26 
27  */
28 
29 #ifndef vsr_rigid_INC
30 #define vsr_rigid_INC
31 
32 namespace vsr { namespace cga {
33 
34 
36 struct Constrain {
37 
39  static DualSphere Distance( const Point& src, const Point& target){
40  return target <= (src ^ Inf(1));
41  }
42 
43  //unused?
44  static Point Crease (const Point& a, const Point& dls, const DualLine d, bool mtn){
45  Circle cir = a ^ d;
46  Pair par = ( dls ^ cir.dual()).dual();
47  return Round::loc( Round::split(par,mtn) );
48  }
49 
50 
52  static Point Double( const Dls& da, const Dls& db, double amt){
53  return Round::point( (da^db).dual(), amt );
54  }
55 
57  static Point Triple (const Dls& da, const Dls& db, const Dls& dc, bool mtn){
58  return Round::loc( Round::split( (da ^ db ^ dc).dual(), mtn ) ) ;
59  }
61  static Point Tetral (const Dls& da, const Dls& db, const Dls& dc, bool mtn){
62  return Round::loc( Round::split( (da ^ db ^ dc).dual(), mtn ) ) ;
63  }
65  static Point Planar( const Dls& da, const Dls& db, const Dls& dc, bool mtn){
66  Plane plane = da ^ db ^ dc ^ Inf(1);
67  return Round::loc( Round::split( (da ^ dc ^ plane.dual() ).dual(), mtn ) );
68  }
69 
71  static Point Tangency(const Pnt& p, const Dls& da, const Dls& db){
72 
73  auto meet = (da ^ db).dual();
74  auto tan = Round::loc( Tangent::at( meet, p ) );
75  auto sur = Round::sur( meet );
76  auto line = tan ^ sur ^ Inf(1);
77  auto np = Round::split ( ( line.dual() ^ sur).dual(), false );
78 
79  return np;
80 
81  }
82 
84  static Point Tangency(const Pnt& p, const Dls& da){
85  auto line = p ^ da ^ Inf(1);
86  auto np = Round::split( (line.dual() ^ da).dual(), false);
87  return np;
88  }
89 
92  static Point Tension(const Pnt& p, const Dls& da){
93  if ( (p<=da)[0] > 0 ) return p;
94  auto line = p ^ da ^ Inf(1);
95  auto np = Round::split( (line.dual() ^ da).dual(), false);
96  return np;
97  }
98 
100  static Point Tension(const Pnt& p, const Dls& da, const Dls& db){
101 
102  if ( ( (p<=da)[0] > 0 ) && ( (p<=db)[0] > 0 ) ) return p; // returns input point if it lies within both spheres
103 
104  //otherwise, constrain to lie on circle meet
105  auto meet = (da ^ db).dual();
106  auto tan = Round::loc( Tangent::at( meet, p ) );
107  auto sur = Round::sur( meet );
108  auto line = tan ^ sur ^ Inf(1);
109  auto np = Round::split ( ( line.dual() ^ sur).dual(), false );
110 
111  return np;
112  }
113 
114 
115 
116  // three distances, center of meet pre-SPLIT (experimental)
117  static Point Triple0 (const Dls& da, const Dls& db, const Dls& dc){
118  return Round::loc( (da ^ db ^ dc).dual() ) ;
119  }
120 
122  static Point PointToCircle( const Point& p, const Circle& c){
123 
124  auto cen = Flat::location( Round::carrier(c), p );
125  auto sur = Round::surround(c);
126  auto line = cen ^ sur ^ Infinity(1);
127  auto meet = (line.dual() ^ sur).dual();
128  return Round::split( meet ,false);
129  }
130  /* static Point Fabrik(const Dls& base, const Dls& goal){ */
131 
132  /* //repeat until distance is decreased to within error threshold, or give up after 20 iterations */
133  /* while (s[0] > err){ */
134 
135  /* Pnt tmpGoal = goal; */
136  /* Pnt tmpBase = base; */
137 
138  /* static Dls dls; //surround */
139  /* static Dll dll; //line */
140  /* static Par par; //intersection of line ^ surround */
141 
142  /* //backward reaching */
143  /* for (int i = end; i > begin; --i){ */
144  /* mFrame[i].pos( tmpGoal ); //set position of ith frame */
145  /* dls = prevDls(i); //set boundary sphere through i-1 th frame; */
146  /* dll = linb(i);//.sp( !mLink[i].mot() ); //get line from ith to i-1th frame */
147  /* par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere */
148  /* tmpGoal = Round::split(par,true); //extract point from point pair intersection */
149  /* } */
150 
151  /* //forward correction */
152  /* for (int i = begin; i < end; ++i){ */
153  /* dls = nextDls(i); //set boundary sphere through i+1 th frame */
154  /* dll = linf(i); //get line to i+1th frame; */
155  /* par = (dll ^ dls).dual(); //get point pair intersection of line and boundary sphere */
156  /* tmpBase = Round::split(par,true); */
157  /* mFrame[i+1].pos(tmpBase); //set position of i+1th frame */
158  /* } */
159 
160  /* s = mFrame[ end ].pos() <= p * -2.0; */
161 
162  /* n++; if (n > 20) { break; } */
163  /* } */
164 
165  /* } */
166 
167 
168 };
169 
170 
173 struct DistancePtr {
174 
175  Point * src = NULL;
176  double t;
177 
178  DistancePtr(){};
179 
180  DistancePtr( Pnt& a, const Pnt& target)
181  {
182  set(a,target);
183  }
184 
186  void set(Pnt& a, const Pnt& target){
187  src = &a; t = Round::rad( Round::at(*src,target) );
188  if (src==NULL) printf("null DistancePtr SET\n");
189  }
190 
193  if (src==NULL) { printf("null DistancePtr\n"); return Dls(); }
194  return Round::dls( *src, t );
195  }
196 
197 };
198 
200 struct RigidNode{
201 
203 
204  bool bCalc = true;
205 
206  virtual void onEval(double amt) = 0;
207 
208  vector <RigidNode*> mParent;
209 
210  Point eval(double amt=0){
211  if (bCalc) onEval(amt);
212  return result;
213  }
214 
215  void setResult(const Point& p){
216  result = p;
217  }
218 
219 };
220 
222 struct Rig2 : RigidNode {
223 
224  DistancePtr da,db;
225 
226  Rig2() : RigidNode() {}
227 
228  Rig2(const Point& target, RigidNode * ra, RigidNode * rb) : RigidNode() {
229  set(target,ra,rb);
230  }
231 
232  void set(const Point& target, RigidNode * ra, RigidNode * rb){
233  mParent.push_back(ra); mParent.push_back(rb);
234  da.set(ra->result,target);
235  db.set(rb->result,target);
236 
237  bCalc=true;
238  result = target;
239  }
240 
241  virtual void onEval(double amt){
242  result = Round::point( (da() ^ db()).dual(), amt);
243  }
244 
245 
246 };
247 
248 struct Rig3 : RigidNode {
249 
250 
251  DistancePtr da,db,dc;
252 
253  bool bMtn;
254  bool bCoplanar = false;
255 
256  Rig3() : RigidNode() {}
257 
258  Rig3( const Pnt& target, RigidNode * ra, RigidNode * rb, RigidNode * rc, bool m, bool p) : RigidNode() {
259  set(target,ra,rb,rc,m,p);
260  }
261 
263  void set( const Point& target, RigidNode * ra, RigidNode *rb, RigidNode *rc, bool m, bool p){
264  mParent.push_back(ra); mParent.push_back(rb); mParent.push_back(rc);
265  bMtn = m;
266  bCoplanar=p;
267 
268  if (ra==NULL || rb==NULL || rc==NULL) printf("null rig3 set\n");
269 
270  da.set(ra->result,target);
271  db.set(rb->result,target);
272  dc.set(rc->result,target);
273 
274  bCalc=true;
275  result = target;
276 
277  }
278 
279  virtual void onEval(double amt){
280  result = bCoplanar ? Constrain::Planar(da(),db(),dc(),bMtn) : Constrain::Triple(da(),db(),dc(),bMtn);
281  }
282 
283 
284 };
285 
286 
288 struct Rigid{
289 
291  bool bCalc;
292 
294  bool bTriple;
295 
298 
300  bool mtn;
301 
304 
306  Rigid *ra, *rb, *rc;
307 
309  vector<Rigid*> child;
310 
311  Rigid() : bCalc(false), bTriple(true), ra(NULL), rb(NULL), rc(NULL) {}
312 
313  Rigid(const Pnt& res ) : bTriple(true), ra(NULL), rb(NULL), rc(NULL) {
314  set(res);
315  }
316 
318  void set(const Pnt& res){
319  bCalc = false;
320  result = res;
321  }
322 
324  void setResult(const Pnt& res){
325  bCalc = false;
326  result = res;
327  }
328 
329  Rigid( const Pnt& target, Rigid * pa, Rigid * pb, Rigid * pc, bool m) : bTriple(true)
330  {
331  set(target,pa,pb,pc,m);
332  }
333 
335  void set( const Pnt& target, Rigid * pa, Rigid * pb, Rigid * pc, bool m){
336  mtn = m; bCalc=true;
337  ra = pa; rb = pb; rc = pc;
338  result = target;
339  da.set(ra->result,target);
340  db.set(rb->result,target);
341  dc.set(rc->result,target);
342  }
343 
345  void set( Rigid * pa, Rigid * pb, Rigid * pc, bool m){
346  mtn = m; bCalc=true;
347  ra = pa; rb = pb; rc = pc;
348  da.set(ra->result,result);
349  db.set(rb->result,result);
350  dc.set(rc->result,result);
351 
352  //add this to children of three others
353  ra->child.push_back(this); rb->child.push_back(this); rc->child.push_back(this);
354  }
355 
356 
357  //hmmm?
358  void set( Rigid * pa, Rigid * pb, bool m){
359  mtn =m; bCalc=true; bTriple=false;
360  ra=pa; rb=pb;rc=this;
361  da.set(ra->result,result);
362  db.set(rb->result,result);
363  dc.set(rc->result,result);
364 
365  //add this to children of three others
366  ra->child.push_back(this); rb->child.push_back(this); rc->child.push_back(this);
367  }
368 
369  void reset(){
370  if (ra!=NULL && rb!=NULL && rc!=NULL) bCalc = true;
371  }
372 
373  Circle circleA(){
374  return (da()^db()).dual();
375  }
376  Circle circleB(){
377  return (db()^dc()).dual();
378  }
379  void orbitA(float amt){
380  result = Round::point( circleA(), amt * ( mtn?1:-1) );
381  }
382  void orbitB(float amt){
383  result = Round::point( circleB(), amt * ( mtn?1:-1) );
384  }
385 
386 
387  Pnt up(){
388  if (bCalc) {
389  bCalc=false; // lock in case network graph is looped
390  for (auto& i : child) i -> down(); // cascade children
391  (*ra).up(); (*rb).up(); (*rc).up();
392  // satisfy();
393  result = bTriple ? Constrain::Triple(da(),db(),dc(),mtn) : Constrain::Planar(da(),db(),dc(),mtn);
394  }
395  return result;
396  }
397 
398  //calculate current position based on parents
399  void update(){
400  if (bCalc){
401  result = bTriple ? Constrain::Triple(da(),db(),dc(),mtn) : Constrain::Planar(da(),db(),dc(),mtn);
402  }
403  }
404 
405  //broadcast position to child
406  void down(){
407  if (bCalc){
408  bCalc=false;
409  for (auto& i : child) {
410  i -> update();
411  // i -> satisfy();
412  i -> down();
413  }
414  // up();
415  }
416  }
417 
418  Pair meet(){
419  return ( da() ^ db() ^ dc() ).dual();
420  }
421 
422  //bring three spheres closer together towards mutual center until meet is legit.
423  void satisfy(int max=20){
424  auto& pa = *da.src; auto& pb = *db.src; auto& pc = *dc.src;
425  auto rs = Round::size(meet(),false);
426  int iter=0;
427  while ( rs < -.0001 && iter < max ){
428  auto center = Round::loc(pa^pb^pc);
429  pa = Round::null( pa+(Vec(center-pa)*fabs(rs)) );
430  pb = Round::null( pb+(Vec(center-pb)*fabs(rs)) );
431  pc = Round::null( pc+(Vec(center-pc)*fabs(rs)) );
432  rs = Round::size( meet(), false );
433  iter++;
434  }
435  }
436 };
437 
438 
439 
440 
441 
442 struct Rigid2{
443 
446 
448  int iter=0;
449 
450  /*-----------------------------------------------------------------------------
451  * Parents Generate Circles to Control This Result
452  *-----------------------------------------------------------------------------*/
453  struct Parents{
454  DistancePtr da,db;
455  Rigid2 *ra, *rb; //parents
456 
457  Circle meet(){
458  return (da()^db()).dual();
459  }
460 
461  bool inside(const Point& p){
462  return ( (p<=da())[0] > 0 ) && ( (p<=db())[0] > 0 );
463  }
464 
465  void operator()(){
466  (*ra)(); (*rb)();
467  }
468  };
469 
470  bool bMtn,bCalc,bReCalc;
471 
473  vector<Parents> parents;
474  vector<Rigid2*> child; //children
475 
476 
477  Rigid2() : bCalc(false), bReCalc(false) {}
478  Rigid2(const Pnt& res) { set(res); }
479 
480  void set(const Pnt& res){
481  bCalc=false; bReCalc=false;
482  result=res;
483  }
484 
485  //add parents
486  void add(Rigid2 *pa, Rigid2 *pb, bool m){
487 
488  bCalc=true; bReCalc=true;
489 
490  //make new parents
491  Parents p;
492  p.ra=pa; p.rb=pb;
493 
494  //set distance contraints based on pa and pb
495  p.da.set(pa->result,result);
496  p.db.set(pb->result,result);
497 
498  //add this to list of children of just pa
499  pa->child.push_back(this);
500  // pb->child.push_back(this);
501  parents.push_back(p);
502  }
503 
504 
505  /* Rigid2(const Pnt& target, Rigid2* pa, Rigid2*pb, bool m) */
506  /* : result(target), ra(pa), rb(pb), bCalc(true), bMtn(m) */
507  /* { */
508  /* da.set(ra->result,target); */
509  /* db.set(rb->result,target); */
510 
511  /* ra->child.push_back(this); rb->child.push_back(this); */
512  /* } */
513 
514  void reset(){ bCalc=true; bReCalc=true; iter=0; }
515 
516  void operator()(){
517  if (bCalc){
518  // Pnt np = result;
519  bCalc=false;
520  for(auto& i : parents){
521  i();
522  //np = Constrain::Tangency(np, i.da(), i.db());
523  }
524  update();
525  //result = np;
526  }
527  //return result;
528  }
529 
530  void update(){
531  if(bReCalc){
532  for(auto& i : parents){
533  result = Constrain::Tangency(result, i.da(), i.db());
534  }
535  }
536  }
537 
538  //update only relative to parents with r
539  void satisfy_old(Rigid2 * r){
540  if(bReCalc){
541  bReCalc=false;
542  bool bRepeat = true;
543  int iter=0;
544  while(bRepeat && (iter<10) ){
545  bRepeat=false;
546  iter++;
547  for(auto& i : parents){
548  if ( (r==i.ra) || (r==i.rb) ){
549  bool bCocircular = ( fabs( (result <= i.meet()).wt() ) < .001);
550  // bool bInside = i.inside(result);
551  if (!bCocircular) {
552  result = Constrain::Tangency(result, i.da(), i.db());
553  bRepeat = true;
554  }
555  }
556  }
557  }
558  }
559  }
560 
561  bool hasA(Rigid2 * r){
562  for (auto& i : parents){
563  if (r==i.ra) return true;
564  }
565  return false;
566  }
567 
568  bool hasB(Rigid2 * r){
569  for (auto& i : parents){
570  if (r==i.rb) return true;
571  }
572  return false;
573  }
574 
575 
576 
577  void satisfy_forward(Rigid2 * r){
578  if (bReCalc){
579  for(auto& i : parents){
580  if (r==i.ra){
581  result = Constrain::Tangency(result, i.da(), i.db());
582  }
583  }
584  }
585  }
586  void satisfy_backward(Rigid2 * r){
587  if (bReCalc){
588  for(auto& i : parents){
589  if (r==i.rb){
590  result = Constrain::Tangency(result, i.da(), i.db());
591  }
592  }
593  }
594  }
595 
596  float error(Rigid2 * r){
597  float tf=0; bool bFound=false;
598  for (auto& i : parents){
599  if (r==i.ra){
600  bFound=true;
601  tf = fabs((result <= i.meet()).wt());
602  }
603  }
604  if (!bFound){
605  for (auto& i : parents){
606  if (r==i.rb){
607  tf = fabs((result <= i.meet()).wt());
608  }
609  }
610  }
611  return tf;
612 
613  }
614 
615 
616  /* void fabrik(Rigid2 * r){ */
617  /* if (bReCalc){ */
618  /* bool bRepeat = true; */
619  /* int iter =0; */
620  /* while (bRepeat && (iter<100)){ */
621  /* bRepeat=false; */
622  /* iter++; */
623  /* for (auto& i : parents){ */
624  /* if (r==i.ra) */
625  /* } */
626  /* } */
627  /* } */
628  /* } */
629 
630  //set bReCalc to true
631  bool checkRecalc(){
632  for (auto& i : parents){
633  if (i.ra->error(this)>.001){
634  bCalc=true;
635  bReCalc=true;
636  i.ra->bReCalc=true;
637  i.ra->bCalc=true;
638  }
639  }
640  return bReCalc;
641  }
642 
643  vector<Rigid2*> satisfy(int begin, int end){
644 
645  if (!parents.empty()){
646  int tIter=0;
647  float tf;
648  //find first not already locked
649  Rigid2 * tr;
650  for (auto& i : parents){
651  if (i.ra->bReCalc){
652  tr = i.ra;
653  break;
654  }
655  }
656  //cout << parents[0].ra->hasA(this) << endl;
657  bool bLoop = parents[0].ra->hasA(this);
658  if (bLoop){
659  do{
660  tIter++;
661  for (int i=begin; i<=end;++i){
662  parents[i].ra->satisfy_forward(this);
663  }
664  for(int i =end; i >= begin; i-- ) {
665  parents[i].ra->satisfy_backward(this);
666  }
667  tf = tr->error(this);//parents[begin].ra->error(this);
668  }while( (tf>.001) && (tIter < 10));
669  } else {
670  do{
671  tIter++;
672  for (int i=begin; i<=end;++i){
673  parents[i].ra->satisfy_forward(this);
674  parents[i].rb->satisfy_forward(this); //only last one
675  }
676  for(int i =end; i >= begin; i-- ) {
677  parents[i].rb->satisfy_backward(this);
678  parents[i].ra->satisfy_backward(this); //only first one
679  }
680  //this should test for first non-already bound ...
681  tf = tr->error(this);//parents[begin].ra->error(this);
682  }while( (tf>.001) && (tIter < 10));
683  //cout << "iter " << tIter << endl;
684  }
685  }
686 
687  vector<Rigid2*> temp;
688 
689  //mark parents as satisfied
690  for (auto& i : parents){
691  if(i.ra->bReCalc==true) temp.push_back(i.ra);
692  i.ra->bReCalc=false;
693  // i.rb->bReCalc=false;
694  }
695  bool bLoop = parents[0].ra->hasA(this);
696  if (!bLoop){
697  if(parents.back().rb->bReCalc==true) temp.push_back(parents.back().rb);
698  parents.back().rb->bReCalc=false;
699  }
700 
701  return temp;
702  }
703 
704 
705  // go through all parents satisfy relationship to this
706  void cascade(int begin, int end){
707 
708  //do this forward and backward reach how many times?
709  //until first node is within error of first forward meet
710  auto rp = satisfy(begin,end);
711  cout << "parents to solve: " << rp.size() << endl;
712  while (!rp.empty()){
713  //cascade connections
714  vector<Rigid2*> temp;
715  for (auto& i : rp){
716  auto r = i->satisfy(0, i->parents.size()-1);
717  for (auto& j : r){
718  temp.push_back(j);
719  }
720  //i.ra->cascade(0,i.ra->parents.size()-1);
721  }
722  //cout << temp.size() << endl;
723  rp = temp;
724  }
725 
726  }
727 
728  Cir circle(int idx =0) { return ( parents[idx].da() ^ parents[idx].db() ).dual(); }
729 
731  Pnt orbit(VSR_PRECISION t, int idx=0) { return Round::point( circle(idx), t * ( bMtn?1:-1) ); }
732 };
733 
734 
735 
739 struct Rig {
740 
742  bool bCalc,bReCalc;
743  int iter=0;
744 
745  void set(const Pnt& res){
746  bCalc=false; bReCalc=false;
747  result=res;
748  }
749 
750  void reset(){
751  bCalc=true; bReCalc=true; iter=0;
752  }
753 
754  struct Parent{
755  DistancePtr da;
756  Rig * rig;
757  bool bStrut =true;
758 
759  //set distance constraint to rig r
760  void set(const Point& p){
761  da.set(rig->result, p);
762  }
763 
764  //constrain a point p to spherical distance via strut or cable
765  Point constrain(const Point& p){//, bool strut){
766  return bStrut ? Constrain::Tangency(p,da()) : Constrain::Tension(p, da());
767  }
768 
769  float distance(const Point& p){
770  return (p<=da())[0];
771  }
772  };
773 
774  vector<Parent> parent;
775  vector<Rig*> child;
776 
777  //add a constraint
778  void add(Rig * r, bool bStrut=true){
779  Parent p;
780  p.bStrut = bStrut;
781  p.rig = r;
782  p.set(result);
783  parent.push_back(p);
784  p.rig->child.push_back(this);
785  }
786 
787  void modify(Rig * r, bool bStrut){
788  for (auto& i : parent){
789  if (r==i.rig) i.bStrut=bStrut;
790  }
791  }
792 
793  //satisfy constraint to rig r
794  void satisfy(Rig * r){
795  if (bReCalc){
796  for (auto& i : parent){
797  bool tCalc=false;
798  //if parent is r
799  if (r==i.rig) tCalc=true;
800  //...or is connected to r
801  for (auto& j : i.rig->parent){
802  if (r==j.rig) tCalc=true;
803  }
804  //..calc
805  if (tCalc){
806  result = i.constrain(result);
807  }
808  }
809  }
810  }
811 
812  void cascade(){
813  if (bCalc){
814  iter++;
815  if (iter>1000) {
816  bCalc=false;
817  }
818  for (auto& i : child){
819  i->satisfy(this);
820  }
821  for (auto& i : child){
822  // i->cascade();
823  }
824  }
825  }
826 
827 };
828 
829 /* ----------------------------------------------------------------------------- */
830 /* * SIMPLICIAL CONSTRAINT . . . (n+1)-simplices to constrain (n)-chains connected by (n-1)-simplex edges */
831 /* *-----------------------------------------------------------------------------*/
832 /* struct Rigid_{ */
833 /* bool bCalc, bTriple; */
834 /* Pnt result; */
835 
836 /* DistancePtr da,db,dc; */
837 /* Rigid_ *ra, *rb, *rc; */
838 /* bool mtn; */
839 
840 /* Rigid_() : bCalc(false), bTriple(true), ra(NULL), rb(NULL), rc(NULL) {} */
841 
842 /* Rigid_(const Pnt& res ) : bTriple(true), ra(NULL), rb(NULL), rc(NULL) { */
843 /* set(res); */
844 /* } */
845 /* void set(const Pnt& res){ */
846 /* bCalc = false; */
847 /* result = res; */
848 /* } */
849 
850 /* Rigid_( const Pnt& target, Rigid * pa, Rigid * pb, Rigid * pc, bool m) : bTriple(true) */
851 /* { */
852 /* set(target,pa,pb,pc,m); */
853 /* } */
854 
855 /* //Counter Clockwise */
856 /* void set( const Pnt& target, Rigid * pa, Rigid * pb, Rigid * pc, bool m){ */
857 /* mtn = m; bCalc=true; */
858 /* ra = pa; rb = pb; rc = pc; */
859 /* result = target; */
860 /* da.set(ra->result,target); */
861 /* db.set(rb->result,target); */
862 /* dc.set(rc->result,target); */
863 /* } */
864 
865 /* //Counter Clockwise */
866 /* void set( Rigid * ra, Rigid * rb, Rigid * rc, bool m){ */
867 
868 /* mtn = m; bCalc=true; */
869 /* da.set(ra->result,result); */
870 /* db.set(rb->result,result); */
871 /* dc.set(rc->result,result); */
872 
873 /* //fasten cycle */
874 /* ra->set(rb, rc, this, m); */
875 /* rb->set(rc, this, ra, m); */
876 /* rc->set(this, ra, rb, m); */
877 
878 /* } */
879 
880 /* /1* void set( Rigid * pa, Rigid * pb, bool m){ *1/ */
881 /* /1* mtn =m; bCalc=true; bTriple=false; *1/ */
882 /* /1* ra=pa; rb=pb;rc=this; *1/ */
883 /* /1* da.set(ra->result,result); *1/ */
884 /* /1* db.set(rb->result,result); *1/ */
885 /* /1* dc.set(rc->result,result); *1/ */
886 /* /1* } *1/ */
887 
888 /* void reset(){ */
889 /* if (ra!=NULL && rb!=NULL && rc!=NULL) bCalc = true; */
890 /* } */
891 
892 /* Pnt operator()(){ */
893 /* if (bCalc) { */
894 /* bCalc=false; //lock because network graph is looped */
895 /* (*ra)(); (*rb)(); (*rc)(); */
896 /* result = satisfy(); //satisfying requires unlocking */
897 /* } */
898 /* return result; */
899 /* } */
900 
901 /* Pair meet(){ */
902 /* return Constrain::Triple( da(), db(), dc() ); */
903 /* } */
904 
905 /* //bring three spheres closer together towards center of meet until meet is legit. */
906 /* Pnt satisfy(){ */
907 /* auto meet = Constrain::Triple( da(), db(), dc() ); */
908 /* if ( Round::size(meet,false) < -.0001 ){ */
909 
910 /* } */
911 /* return bTriple ? Constrain::Triple(da(),db(),dc(),mtn) : Constrain::Planar(da(),db(),dc(),mtn); */
912 
913 /* } */
914 /* }; */
915 
916 
917 } } //vsr::cga:;
918 #endif /* ----- #ifndef vsr_rigid_INC ----- */
static std::vector< Point > split(const Pair &pp)
Split Points from Point Pair.
bool bCalc
default calc is false until ra parents are set
Definition: vsr_rigid.h:291
A Rigid Contraint Node set by Two Distance Pointers.
Definition: vsr_rigid.h:222
static DualSphere dls(VSR_PRECISION r, VSR_PRECISION x, VSR_PRECISION y, VSR_PRECISION z)
Dual Sphere from Coordinate Center (shorthand)
Definition: vsr_cga3D_round.h:79
bool bTriple
coplanar or not
Definition: vsr_rigid.h:294
bool mtn
mountain or valley
Definition: vsr_rigid.h:300
Methods for Evaluating Constrained Points using Intersections of Sphere-based Distances.
Definition: vsr_rigid.h:36
Dls operator()()
Evaluate Distance Constraint as a Dual Sphere.
Definition: vsr_rigid.h:192
NCir< 5 > Cir
Circle
Definition: vsr_cga3D_types.h:74
bool bCalc
whether to Evaluate
Definition: vsr_rigid.h:204
NVec< 5 > Vec
Vector
Definition: vsr_cga3D_types.h:62
static DualSphere at(const Point &c, const Point &p)
Dual Round from Center and Point on Surface.
virtual void onEval(double amt)=0
evaluation implementation to be implemented by subclass
static Point Double(const Dls &da, const Dls &db, double amt)
two distances and a theta around their meet
Definition: vsr_rigid.h:52
Par Pair
Point Pair 2-blade \(\tau=p_a \wedge p_b=\{e_{12},e_{13},e_{23},e_{1}n_o,e_{2}n_o,e_{3}n_o,e_{1}n_\infty,e_{2}n_\infty,e_{3}n_\infty,n_{o}n_\infty\}\)
Definition: vsr_cga3D_types.h:129
static Line carrier(const Pair &p)
Carrier Flat of Pair.
NDls< 5 > Dls
DualSphere
Definition: vsr_cga3D_types.h:76
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
void set(Rigid *pa, Rigid *pb, Rigid *pc, bool m)
set from constraints Counter Clockwise
Definition: vsr_rigid.h:345
Inf Infinity
Null Infinity Blade: \(n_\infty\)
Definition: vsr_cga3D_types.h:125
static Point Planar(const Dls &da, const Dls &db, const Dls &dc, bool mtn)
planar constraint: two distances and a plane
Definition: vsr_rigid.h:65
bool bMtn
fold is a mountain fold
Definition: vsr_rigid.h:253
vector< Parents > parents
possibly many couples (one per valence)
Definition: vsr_rigid.h:473
static DualSphere sur(const A &s)
Dual Surround of a Direct or Dual Round Element (Shorthand)
Definition: vsr_cga3D_round.h:347
static Point loc(const A &s)
Location (normalizd) of a Round Element (shorthand)
Definition: vsr_cga3D_round.h:146
static Point Tangency(const Pnt &p, const Dls &da)
spherical tangency constrain, one distance and an original point (returns point on sphere closest to ...
Definition: vsr_rigid.h:84
double t
Distance t from Source.
Definition: vsr_rigid.h:176
DistancePtr da
three dual sphere distances
Definition: vsr_rigid.h:303
static DualSphere surround(const Pair &s)
Dual Surround of a Direct or Dual Pair.
Definition: vsr_rigid.h:442
Cir Circle
Direct Circle 3-blade \(\kappa=p_a \wedge p_b \wedge p_c\)
Definition: vsr_cga3D_types.h:130
vector< RigidNode * > mParent
parents which might need to be evaluated before this one
Definition: vsr_rigid.h:208
static Pair at(const Circle &r, const Point &p)
Tangent Element of A Circle at Point p.
static Point Tetral(const Dls &da, const Dls &db, const Dls &dc, bool mtn)
tetral constraint
Definition: vsr_rigid.h:61
NInf< 5 > Inf
Infinity
Definition: vsr_cga3D_types.h:68
void setResult(const Pnt &res)
set result
Definition: vsr_rigid.h:324
bool bCoplanar
result is coplanar with three constraints
Definition: vsr_rigid.h:254
Pnt Point
Null Vector \(p=\{e_1,e_2,e_3,n_o,n_\infty\}\)
Definition: vsr_cga3D_types.h:128
Rigid * ra
linked to three parents
Definition: vsr_rigid.h:306
static VSR_PRECISION rad(const T &t)
Squared Size of a DualSphere (result could be negative)
Definition: vsr_cga3D_round.h:203
Multivector & set(value_t v)
Set value of blade type IDX
static Point PointToCircle(const Point &p, const Circle &c)
constrain a point p to a circle c
Definition: vsr_rigid.h:122
vector< Rigid * > child
Has n children which depend on it.
Definition: vsr_rigid.h:309
Point result
Meet of parents.
Definition: vsr_rigid.h:445
the versor library namespace
Definition: vsr_algebra.h:29
Pnt orbit(VSR_PRECISION t, int idx=0)
get point at theta t around constraint orbit
Definition: vsr_rigid.h:731
static Point Tangency(const Pnt &p, const Dls &da, const Dls &db)
circle tangency constraint, two distances and an original point (closest to original) ...
Definition: vsr_rigid.h:71
Definition: vsr_rigid.h:453
static Point Tension(const Pnt &p, const Dls &da)
Tension tangency constrain, one distance and an original point (returns point on sphere closest to p ...
Definition: vsr_rigid.h:92
Point * src
Pointer to Point Source.
Definition: vsr_rigid.h:175
virtual void onEval(double amt)
evaluation implementation to be implemented by subclass
Definition: vsr_rigid.h:241
Holds a pointer to a source, and has a radius t, the operator() generates a dual sphere at source wit...
Definition: vsr_rigid.h:173
static Point Triple(const Dls &da, const Dls &db, const Dls &dc, bool mtn)
three distances, counter clockwise (deprecated, use Tetral)
Definition: vsr_rigid.h:57
A Rigid Constraint Node set by Three Distance Pointers.
Definition: vsr_rigid.h:288
void set(const Point &target, RigidNode *ra, RigidNode *rb, RigidNode *rc, bool m, bool p)
set from target and constraints Counter Clockwise
Definition: vsr_rigid.h:263
static VSR_PRECISION size(const DualSphere &s, bool bDual=true)
Squared Size of a DualSphere (result could be negative)
NPnt< 5 > Pnt
Point
Definition: vsr_cga3D_types.h:72
static Point point(VSR_PRECISION x, VSR_PRECISION y, VSR_PRECISION z)
Null Point from Coordinates.
Point result
result of constraint computation
Definition: vsr_rigid.h:741
void set(const Pnt &res)
set result
Definition: vsr_rigid.h:318
Pnt result
stored evaluated result of (*this)()
Definition: vsr_rigid.h:297
void set(const Pnt &target, Rigid *pa, Rigid *pb, Rigid *pc, bool m)
set from target and constraints Counter Clockwise
Definition: vsr_rigid.h:335
void set(Pnt &a, const Pnt &target)
Set constraint from source and target.
Definition: vsr_rigid.h:186
static Point location(const DualLine &f, const Point &p, bool dual=true)
Location of DualLine closest to Point p.
Definition: vsr_rigid.h:754
static DualSphere Distance(const Point &src, const Point &target)
Construct a Distance Constraint from a source and target.
Definition: vsr_rigid.h:39
static Point null(const Vec &v)
Null Point from a vec.
static Point Tension(const Pnt &p, const Dls &da, const Dls &db)
tension constraint from two distances
Definition: vsr_rigid.h:100
Definition: vsr_rigid.h:248
Point result
stored evaluated result
Definition: vsr_rigid.h:202
Rig has n spherical constraints to satisfy (try using fabrik solver here)
Definition: vsr_rigid.h:739
virtual void onEval(double amt)
evaluation implementation to be implemented by subclass
Definition: vsr_rigid.h:279
Generic Rigid Constraint Node.
Definition: vsr_rigid.h:200