chart.c
Go to the documentation of this file.
1 #include "chart.h"
2 
3 #include "defines.h"
4 #include "error.h"
5 #include "random.h"
6 #include "algebra.h"
7 #include "samples.h"
8 
9 #include <string.h>
10 #include <math.h>
11 
70 unsigned int InitChartInt(boolean trusted,boolean singular,boolean forceRS,Tparameters *pr,boolean simple,
71  Tbox *domain,unsigned int *tp,unsigned int m,unsigned int k,double *p,double e,
72  double eCurv,double r,double *T,TJacobian *sJ,TAtlasBase *w,Tchart *c);
73 
96 unsigned int ComputeJacobianKernelBasis(double epsilon,TJacobian *sJ,Tchart *c);
97 
106 void LinkChart(unsigned int id,Tchart *c);
107 
126 boolean IntersectChartsInt(Tparameters *pr,boolean cut,
127  unsigned int *tp,Tbox *ambient,
128  unsigned int id1,Tchart *c1,
129  unsigned int id2,Tchart *c2);
130 
131 
164 void PlotChartAsPolygon(Tparameters *pr,FILE *fcost,TJacobian *sJ,
165  unsigned int xID,unsigned int yID,unsigned int zID,
166  Tplot3d *p3d,Tchart *c);
167 
168 
185 void PlotChartAsBox(Tparameters *pr,
186  unsigned int xID,unsigned int yID,unsigned int zID,
187  Tplot3d *p3d,Tchart *c);
188 
189 /****************************************************************************/
190 /****************************************************************************/
191 /****************************************************************************/
192 
193 unsigned int ComputeJacobianKernelBasis(double epsilon,TJacobian *sJ,Tchart *c)
194 {
195  unsigned int out;
196  double *JT;
197 
198  NEW(JT,c->m*c->nrJ,double);
200 
201  #if (_DEBUG>1)
202  PrintVector(stdout,"c",c->m,c->center);
203  PrintTMatrix(stdout,"J",c->m,c->nrJ,JT);
204  #endif
205 
206  out=FindKernelAndIndependentRows(c->nrJ,c->m,JT,c->k,epsilon,&(c->singular),&(c->BJ),&(c->T));
207 
208  #if (_DEBUG>1)
209  PrintTMatrix(stdout,"T",c->m,c->k,c->T);
210  #endif
211 
212  free(JT);
213 
214  return(out);
215 }
216 
217 void LinkChart(unsigned int id,Tchart *c)
218 {
219  if (!c->singular)
220  Error("Only singular maps can be linked to other singular maps");
221 
222  if (c->nl==c->ml)
223  MEM_DUP(c->l,c->ml,unsigned int);
224 
225  c->l[c->nl]=id;
226  c->nl++;
227 }
228 
229 void AddBorderConstraint(Tparameters *pr,double *t,unsigned int *tp,Tbox *ambient,Tchart *c)
230 {
231  double *td,nm;
232 
233  NEW(td,c->k,double);
234 
235  /* The face to add is orthogonal to the line connecting the interior and the
236  exterior of the domain. In this way we ensure that the exterior point is
237  cropped. */
238  memcpy(td,t,c->k*sizeof(double));
239 
240  nm=Norm(c->k,td);
241  /* To avoid numerical instabilities, do not use too small vectors. */
242  //if (nm>MIN_SAMPLING_RADIUS)
243  {
244  double n;
245 
246  /* Normalize the director vector for the plane */
247  ScaleVector(1/nm,c->k,td);
248 
249  /* Compute the offset: the inequality must pass over the projection
250  of 'pt' on the chart */
251  n=-GeneralDotProduct(c->k,td,t);
252 
253  if (c->simple)
255  else
256  /* The vertexes generated with a "border" face will not be expandible
257  (they will be out of the domain but too close to the border -> do
258  not expand them). */
259  CutPolytopeWithFace(pr,td,n,NO_UINT,(void *)c->w,(void *)c,c->m,tp,ambient,c->p);
260  }
261 
262  free(td);
263 }
264 
265 void ForceChartCut(Tparameters *pr,unsigned int *tp,Tbox *ambient,
266  unsigned int id1,Tchart *c1,
267  unsigned int id2,Tchart *c2)
268 {
269  double *t;
270 
271  NEW(t,c1->k,double);
272 
273  Manifold2Chart(c1->center,tp,t,c2);
274  if (c1->simple)
275  CutSPolytope(t,c2->r,id2,c1->sp);
276  else
277  CutPolytope(pr,t,c2->r,id2,(void *)c1->w,(void *)c1,c1->m,tp,ambient,c1->p);
278 
279  Manifold2Chart(c2->center,tp,t,c1);
280  if (c2->simple)
281  CutSPolytope(t,c1->r,id1,c2->sp);
282  else
283  CutPolytope(pr,t,c1->r,id1,(void *)c2->w,(void *)c2,c2->m,tp,ambient,c2->p);
284 
285 }
286 
287 boolean IntersectChartsInt(Tparameters *pr,boolean cut,
288  unsigned int *tp,Tbox *ambient,
289  unsigned int id1,Tchart *c1,
290  unsigned int id2,Tchart *c2)
291 {
292  boolean neighbours;
293 
294  neighbours=FALSE;
295 
296  if ((c1->w==c2->w)&&(c1->m==c2->m)&&(c1->k==c2->k))
297  {
298  double d,sr;
299  double *t1,*t2;
300  double n1,n2;
301  double e;
302 
303  d=DistanceTopology(c1->m,tp,c1->center,c2->center);
304 
305  /* At a given point we used a reduced radius for
306  the ball projected in the "other" tangent space.
307  We even mention this in our papers but we have
308  to fix it.
309  Using a reduced radius is appealing since the
310  projection of a ball has less area/volume than
311  the original ball. However, intersecting balls
312  with different radius does not warrantee the
313  balls to intersect at all and, if they do, the
314  plane defined by the intersection does not
315  necessarity cuts out the polytope vertex used
316  to generate the new chart. This is specially true
317  when the new chart is generated very close
318  to the previous one (this occurs in high curvature
319  ares). If the vertex used to generate the new
320  chart is not removed from the polytope the algorithm
321  iterates forever selecting the same vertice and
322  generating the same new chart forever.
323  To avoid this problem we use keep the original
324  radius for the projected ball. Two balls with the
325  same radius always intersect and the resulting plane
326  always crosses the line in between the two ball
327  centers cropping one vertex from the polyedron.
328  */
329  sr=c1->r+c2->r;
330 
331  if (d<sr)
332  {
333  /*center of chart1 in chart2*/
334  NEW(t1,c2->k,double);
335  n1=Manifold2Chart(c1->center,tp,t1,c2);
336 
337  /* n1 = norm(t1) */
338  /* Points are typically selected on the ball of radius 'r'
339  and we allow for some error in the back-projection */
340  //if ((n1<1.1*c2->r)&&(n1/d>(1.0-c2->eCurv)))
341  {
342  /* compute 'e': distance from the center of c1 to c2 */
343  e=d*d-n1*n1;
344 
345  if (e<-ZERO)
346  Error("Non-orthonormal tangent space in IntersectChartsInt (1)?");
347  if (e<ZERO) e=0.0; /* tiny neg. values are set to zero */
348  e=sqrt(e);
349 
350  if (e<c2->error)
351  {
352  /*center of chart2 in chart1*/
353  NEW(t2,c1->k,double);
354  n2=Manifold2Chart(c2->center,tp,t2,c1);
355 
356  /* n2 = norm(t2) */
357  //if ((n2<1.1*c1->r)&&(n2/d>(1.0-c1->eCurv)))
358  {
359  /* compute 'e': distance from the center of c2 to c1 */
360  e=d*d-n2*n2;
361  if (e<-ZERO)
362  Error("Non-orthonormal tangent space in IntersectChartsInt (2)?");
363  if (e<ZERO) e=0.0; /* tiny neg. values are set to zero */
364  e=sqrt(e);
365 
366  if (e<c1->error)
367  {
368  boolean compare;
369 
370  compare=((c1->n==0)||(CompareTangentSpaces(c1,c2)));
371  if (compare)
372  {
373  neighbours=TRUE;
374  if (cut)
375  {
376  if (c1->simple)
377  CutSPolytope(t2,c2->r,id2,c1->sp);
378  else
379  CutPolytope(pr,t2,c2->r,id2,(void *)c1->w,(void *)c1,c1->m,tp,ambient,c1->p);
380 
381  if (c2->simple)
382  CutSPolytope(t1,c1->r,id1,c2->sp);
383  else
384  CutPolytope(pr,t1,c1->r,id1,(void *)c2->w,(void *)c2,c2->m,tp,ambient,c2->p);
385  }
386  }
387  }
388  }
389  free(t2);
390  }
391  }
392  free(t1);
393  }
394  }
395  else
396  Error("Intersecting non-compatible local charts");
397 
398  return(neighbours);
399 }
400 
401 
402 void PlotChartAsPolygon(Tparameters *pr,FILE *fcost,TJacobian *sJ,
403  unsigned int xID,unsigned int yID,unsigned int zID,
404  Tplot3d *p3d,Tchart *c)
405 {
406  double cost;
407  Tcolor color;
408 
409  if (c->k!=2)
410  Error("PlotChartAsFace only works for 2d manifolds");
411 
412  /* Read the cost associated with the chart, if any. */
413  if (fcost!=NULL)
414  {
415  if (fscanf(fcost,"%lf",&cost)!=1)
416  Error("No enough data in the cost file");
417  if (cost>0)
418  CostColor(cost,1e-4,&color);
419  }
420 
421  /* When plotting with a cost function the frontier charts are not plotted (?) */
422  if ((fcost==NULL)||(!c->frontier))
423  {
424  unsigned int nv;
425  double **v;
426  Tcpolytope *pol;
427 
428  if (c->simple)
429  {
430  NEW(pol,1,Tcpolytope);
431  SPolytope2Polytope(pr,c->sp,pol);
432  }
433  else
434  pol=c->p;
435 
436  GetPolytopeVertices(&nv,&v,pol);
437 
438  if (nv>0)
439  {
440  unsigned int ne;
441  unsigned int *v1;
442  unsigned int *v2;
443  unsigned int i,k;
444  double **p,*g,*o;
445  unsigned int current,n1,n2,nc;
446  boolean found;
447  boolean *visited;
448  unsigned int *fv;
449  boolean e;
450 
451  NEW(p,nv,double *);
452  NEW(g,c->m,double);
453  NEW(visited,nv,boolean);
454  NEW(fv,nv,unsigned int); /*face vertices in order*/
455 
456  for(i=0;i<nv;i++)
457  {
458  NEW(p[i],3,double);
459  if ((!PLOT_ON_MANIFOLD)||
460  (Chart2Manifold(pr,sJ,v[i],NULL,NULL,g,c)==INF))
461  Local2Global(v[i],NULL,g,c);
463 
464  p[i][0]=o[xID];
465  p[i][1]=o[yID];
466  p[i][2]=o[zID];
467 
468  free(o);
469 
470  visited[i]=FALSE;
471  }
472 
473  //if (!ON_CUIKSYSTEM(c->w))
474  {
475  unsigned int rep;
476 
477  rep=(unsigned int)(GetParameter(CT_REPRESENTATION,pr));
478  if (rep==REP_JOINTS)
479  {
480  double ox,oy,oz;
481  double cx,cy,cz;
482 
483  cx=GetParameter(CT_CUT_X,pr);
484  cy=GetParameter(CT_CUT_Y,pr);
485  cz=GetParameter(CT_CUT_Z,pr);
486 
487  /* If any of the points in the polygon is above the cut
488  displace the whole polygon -2pi */
489  ox=0;
490  oy=0;
491  oz=0;
492  for(i=0;i<nv;i++)
493  {
494  if ((cx<0)&&(p[i][0]<cx))
495  ox=+M_2PI;
496  if ((cx>0)&&(p[i][0]>cx))
497  ox=-M_2PI;
498  if ((cy<0)&&(p[i][1]<cy))
499  oy=+M_2PI;
500  if ((cy>0)&&(p[i][1]>cy))
501  oy=-M_2PI;
502  if ((cz<0)&&(p[i][2]<cz))
503  oz=+M_2PI;
504  if ((cz>0)&&(p[i][2]>cz))
505  oz=-M_2PI;
506  }
507 
508  for(i=0;i<nv;i++)
509  {
510  p[i][0]+=ox;
511  p[i][1]+=oy;
512  p[i][2]+=oz;
513  }
514  }
515  }
516 
517  GetPolytopeEdges(&ne,&v1,&v2,pol);
518 
519  /* Start the face at the first vertex*/
520  fv[0]=0;
521  current=0;
522  visited[0]=TRUE;
523  nc=1; /*number of vertices already in the face*/
524  e=FALSE; /* error in the polygon */
525 
526  while(nc<nv)
527  {
528  /*look for a not visited neighbour*/
529  found=FALSE;
530  i=0;
531  while((!found)&&(i<ne))
532  {
533  /*Extremes of the edges*/
534  n1=v1[i];
535  n2=v2[i];
536 
537  if ((n1==current)&&(!visited[n2]))
538  {
539  found=TRUE;
540  k=n2;
541  }
542  else
543  {
544  if ((n2==current)&&(!visited[n1]))
545  {
546  found=TRUE;
547  k=n1;
548  }
549  else
550  i++;
551  }
552  }
553  if (!found)
554  {
555  Warning("A vertex without neighbours!!");
556  e=TRUE;
557  }
558  visited[k]=TRUE;
559  fv[nc]=k;
560  current=k;
561  nc++;
562  }
563 
564  if (!e)
565  {
566  if (fcost!=NULL)
567  {
568  if (cost>0)
569  Plot3dObjectWithColor(nv,1,0,p,&nv,&fv,&color,p3d);
570  }
571  else
572  Plot3dObject(nv,1,0,p,&nv,&fv,p3d);
573  }
574 
575  for(i=0;i<nv;i++)
576  {
577  free(v[i]);
578  free(p[i]);
579  }
580 
581  free(p);
582  free(v);
583  free(v1);
584  free(v2);
585  free(g);
586  free(visited);
587  free(fv);
588  }
589 
590  if (c->simple)
591  {
592  DeletePolytope(pol);
593  free(pol);
594  }
595  }
596 }
597 
598 
600  unsigned int xID,unsigned int yID,unsigned int zID,
601  Tplot3d *p3d,Tchart *c)
602 {
603  double *o;
604 
605  if (c->k!=3)
606  Error("PlotChartAsBox only works for 3d manifolds");
607 
609 
610  PlotBox3d(o[xID]-c->r,o[xID]+c->r,
611  o[yID]-c->r,o[yID]+c->r,
612  o[zID]-c->r,o[zID]+c->r,
613  p3d);
614 
615  free(o);
616 }
617 
618 void InitCSWDFromFile(Tparameters *pr,char *name,TAtlasBase *wcs)
619 {
620  FILE *f;
621  Tfilename fn;
622 
623  CreateFileName(NULL,name,NULL,CUIK_EXT,&fn);
624  f=fopen(GetFileFullName(&fn),"r");
625  if (f)
626  {
627  /* The cuik file exists -> read from it */
628  fclose(f);
629  fprintf(stderr,"Reading cuik from : %s\n",GetFileFullName(&fn));
630 
631  wcs->isCS=TRUE;
632  wcs->w=NULL;
633  NEW(wcs->cs,1,TCuikSystem);
635  }
636  else
637  {
638  /* The cuik file does not exits -> try to read the world one */
639  wcs->isCS=FALSE;
640  wcs->cs=NULL;
641  NEW(wcs->w,1,Tworld);
642  InitWorldFromFile(pr,TRUE,name,wcs->w);
643  }
644  DeleteFileName(&fn);
645 }
646 
647 unsigned int InitChartInt(boolean trusted,boolean singular,boolean forceRS,Tparameters *pr,boolean simple,
648  Tbox *domain,unsigned int *tp,unsigned int m,unsigned int k,double *p,double e,
649  double eCurv,double r,double *T,TJacobian *sJ,TAtlasBase *w,Tchart *c)
650 {
651  double epsilon;
652  double error;
653  double sr;
654  unsigned int out;
655  double delta;
656  unsigned int nrJ,ncJ;
657 
658  out=0; /* no problem generating the chart. */
659 
660  epsilon=GetParameter(CT_EPSILON,pr);
661  delta=GetParameter(CT_DELTA,pr);
662 
663  sr=GetParameter(CT_SR,pr);
664  if (sr==0)
665  sr=(double)k;
666  if (sr<r+2*delta)
667  sr=r+2*delta;
668 
669  c->w=w;
670 
671  c->m=m; /*number of variables */
672  c->k=k; /*dimensionality of the manifold*/
673  c->n=c->m-c->k; /*number of non-redundant equations (equalities)*/
674 
675  if ((c->k==0)||(c->m==0)||(c->k>c->m))
676  Error("Dimension missmatch in InitChart (2)");
677 
678  GetJacobianSize(&nrJ,&ncJ,sJ);
679  if ((c->m!=ncJ)||(c->n>nrJ))
680  Error("Jacobian-system missmatch in InitChart (1)");
681 
682  /* Default initialization */
683  c->center=NULL;
684  c->T=NULL;
685  c->BJ=NULL;
686  c->singular=FALSE;
687  c->ml=0;
688  c->nl=0;
689  c->l=NULL;
690  c->degree=NO_UINT; /* We defer the computation of the degree until needed */
691  c->simple=simple;
692  c->p=NULL;
693  c->sp=NULL;
694 
695  /* Copy the center */
696  NEW(c->center,c->m,double);
697  memcpy(c->center,p,c->m*sizeof(double));
698 
699  /* Note that PointInBoxTopology can modify the center !! */
700  if (trusted)
701  {
702  c->frontier=FALSE;
703  if (tp!=NULL)
704  ArrayPi2Pi(c->m,tp,c->center);
705  }
706  else
707  c->frontier=((!PointInBoxTopology(NULL,TRUE,c->m,c->center,epsilon,tp,domain))||
708  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,c->center,c->w)));
709 
710  /* Check if the (modified) center is actually on the manifold */
711  if ((trusted)||(c->n==0))
712  error=0.0;
713  else
714  error=CS_WD_ERROR_IN_SIMP_EQUATIONS(pr,c->center,c->w);
715 
716  if (error>epsilon)
717  out=4; /* The map can not be defined since the given point is not in the manifold */
718  else
719  {
720  c->error=e;
721  c->eCurv=eCurv;
722  c->r=r;
723 
724  if (trusted)
725  c->collision=FALSE;
726  else
727  { CS_WD_IN_COLLISION(c->collision,pr,c->center,NULL,c->w); }
728 
729  c->frontier=((c->frontier)||(c->collision));
730 
731  c->nrJ=nrJ;
732 
733 
734  if (c->n>0) /* no empty problem */
735  {
736  if (T!=NULL)
737  {
738  NEW(c->T,c->m*c->k,double);
739  memcpy(c->T,T,sizeof(double)*(c->m*c->k));
740  /* BJ is already NULL. Actually never used for singular charts */
741  }
742  else
743  {
744  /* Initialize c->T, c->BJ and c->singular */
745  out=ComputeJacobianKernelBasis(epsilon,sJ,c);
746 
747  if ((!singular)&&(forceRS)&&(c->singular))
748  Error("The point is not regular (and is supposed to be)");
749  }
750  }
751 
752 
753  if (out<(singular?2:1)) /* If the chart could be actually created */
754  {
755  if ((singular)||(T!=NULL))
756  {
757  /* Even if ComputeJacobianKernelBasis determines that the point
758  is not singular, we force it to be singular (we are for sure
759  close to a singularity). */
760  if ((forceRS)||(T!=NULL))
761  c->singular=TRUE;
762 
763  c->ml=1;
764  NEW(c->l,c->ml,unsigned int);
765  }
766 
767  if (c->simple)
768  {
769  NEW(c->sp,1,Tscpolytope);
770  InitEmptySPolytope(delta,k,r,sr,c->sp);
771  }
772  else
773  {
774  NEW(c->p,1,Tcpolytope);
775  InitEmptyPolytope(k,r,c->p);
776  }
777  }
778 
779  }
780 
781  /* If there was any error in the map definition release (possibly) used memory*/
782  if (out>(singular?1:0))
783  DeleteChart(c);
784 
785  /*
786  0 if we could actually define the chart, 1 if there the kernel is
787  too large (i.e., the given point is singular), 2 if the chart could not be defined
788  since the kernel is too small at the given point, 3 if there is an error while
789  performing QR decomposition, and 4 if the error w.r.t. the manifold is
790  too large. Most of these outputs come directly from \ref AnalyzeKernel.
791  */
792  return(out);
793 }
794 
795 unsigned int InitChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
796  unsigned int m,unsigned int k,double *p,double e,double eCurv,double r,
797  TJacobian *sJ,TAtlasBase *w,Tchart *c)
798 {
799  /* trusted=FALSE singular=FALSE forceRS=TRUE (error if not regular) */
800  return(InitChartInt(FALSE,FALSE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
801 }
802 
803 unsigned int InitPossiblySingularChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
804  unsigned int m,unsigned int k,double *p,double e, double eCurv, double r,
805  TJacobian *sJ,TAtlasBase *w,Tchart *c)
806 {
807  /* trusted=FALSE singular=TRUE forceRS=FALSE (no error if singular and do not force to mark it as singular) */
808  return(InitChartInt(FALSE,TRUE,FALSE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
809 }
810 
811 unsigned int InitSingularChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
812  unsigned int m,unsigned int k,double *p,double e, double eCurv,double r,
813  TJacobian *sJ,TAtlasBase *w,Tchart *c)
814 {
815  /* trusted=FALSE singular=TRUE forceRS=TRUE (mark as singular even if not detected as such) */
816  return(InitChartInt(FALSE,TRUE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
817 }
818 
819 unsigned int InitTrustedChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
820  unsigned int m,unsigned int k,double *p,double e, double eCurv,double r,
821  TJacobian *sJ,TAtlasBase *w,Tchart *c)
822 {
823  /* trusted=TRUE singular=FALSE forceRS=TRUE (error if not regular) */
824  return(InitChartInt(TRUE,FALSE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
825 }
826 
827 unsigned int InitChartWithTangent(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
828  unsigned int m,unsigned int k,double *p,double *T,
829  double e, double eCurv, double r,
830  TJacobian *sJ,TAtlasBase *w,Tchart *c)
831 {
832  /* singular=FALSE forceRS=TRUE (but forceRS plays no role since we give T) */
833  return(InitChartInt(FALSE,TRUE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,T,sJ,w,c));
834 }
835 
836 void CopyChart(Tchart *c_dst,Tchart *c_src)
837 {
838  /* Copy chart */
839  c_dst->w=c_src->w;
840 
841  c_dst->m=c_src->m;
842  c_dst->k=c_src->k;
843  c_dst->n=c_src->n;
844  c_dst->nrJ=c_src->nrJ;
845 
846  c_dst->error=c_src->error;
847  c_dst->eCurv= c_src->eCurv;
848  c_dst->r=c_src->r;
849  c_dst->degree=c_src->degree;
850  c_dst->frontier=c_src->frontier;
851  c_dst->singular=c_src->singular;
852 
853  NEW(c_dst->center,c_dst->m,double);
854  memcpy(c_dst->center,c_src->center,c_dst->m*sizeof(double));
855 
856  if ((c_src->n==0)||(c_src->T==NULL))
857  c_dst->T=NULL;
858  else
859  {
860  NEW(c_dst->T,c_dst->m*c_dst->k,double);
861  memcpy(c_dst->T,c_src->T,sizeof(double)*(c_dst->m*c_dst->k));
862  }
863 
864  /* maps defined with given tangent space don't have Jacobian basis */
865  if ((c_src->nrJ==0)||(c_src->BJ==NULL)) /* c_src->singular==TRUE */
866  c_dst->BJ=NULL;
867  else
868  {
869  NEW(c_dst->BJ,c_dst->nrJ,boolean);
870  memcpy(c_dst->BJ,c_src->BJ,c_dst->nrJ*sizeof(boolean));
871  }
872 
873  c_dst->ml=c_src->ml;
874  if (c_dst->ml>0)
875  {
876  c_dst->nl=c_src->nl;
877  NEW(c_dst->l,c_dst->ml,unsigned int);
878  memcpy(c_dst->l,c_src->l,c_dst->nl*sizeof(unsigned int));
879  }
880  else
881  {
882  c_dst->nl=0;
883  c_dst->l=NULL;
884  }
885 
886  /* Copy Polytope */
887  c_dst->simple=c_src->simple;
888 
889  if (c_src->sp!=NULL)
890  {
891  NEW(c_dst->sp,1,Tscpolytope);
892  CopySPolytope(c_dst->sp,c_src->sp);
893  c_dst->p=NULL;
894  }
895 
896  if (c_src->p!=NULL)
897  {
898  NEW(c_dst->p,1,Tcpolytope);
899  CopyPolytope(c_dst->p,c_src->p);
900  c_dst->sp=NULL;
901  }
902 }
903 
905 {
906  double d;
907  double *aData;
908 
909  if (c1->w!=c2->w)
910  Error("Comparing maps defined on diferent manifolds");
911 
912  NEW(aData,c1->k*c1->k,double);
913 
914  TMatrixMatrixProduct(c1->m,c1->k,c1->T,c2->k,c2->T,aData);
915 
916  d=fabs(MatrixDeterminant(c1->k,aData));
917 
918  free(aData);
919 
920  return(fabs(d-1)<=c1->eCurv);
921 }
922 
924 {
925  if (c1->w!=c2->w)
926  Error("Comparing maps defined on diferent manifolds");
927 
928  return(MinCosinusBetweenSubSpaces(c1->m,c1->k,c1->T,c2->T));
929 }
930 
932 {
933  return(c->w);
934 }
935 
937 {
938  return(c->center);
939 }
940 
942 {
943  return(c->r);
944 }
945 
947 {
948  if (!c->simple)
949  Error("GetChartSamplingRadius is only defined for simple charts");
950  return(SPolytopeGetSamplingRadius(c->sp));
951 }
952 
954 {
955  return(c->error);
956 }
957 
959 {
960  return(c->eCurv);
961 }
962 
963 unsigned int GetChartAmbientDim(Tchart *c)
964 {
965  return(c->m);
966 }
967 
968 unsigned int GetChartManifoldDim(Tchart *c)
969 {
970  return(c->k);
971 }
972 
974 {
975  return(c->T);
976 }
977 
979 {
980  return(c->BJ);
981 }
982 
984 {
985  return(c->singular);
986 }
987 
988 unsigned int GetChartDegree(Tparameters *pr,double *T,TJacobian *sJ,
989  boolean *singular,Tchart *c)
990 {
991  double *A;
992  int sg;
993  unsigned int d;
994 
995  d=0; /* default output*/
996 
997  if (c->singular)
998  *singular=TRUE;
999  else
1000  {
1001  if (c->BJ==NULL)
1002  Error("A non-singular chart without Jacobian basis?");
1003 
1004  *singular=FALSE;
1005 
1006  if ((T==c->T)&&(c->degree!=NO_UINT))
1007  d=c->degree;
1008  else
1009  {
1010  /* Evaluate the Jacobian */
1011  NEW(A,c->m*c->m,double);
1012 
1013  /* We only take the c->n independent rows of the Jacobian */
1014  EvaluateJacobianSubSetInVector(c->center,c->BJ,c->m,c->m,A,sJ);
1015 
1016  /* The lower part of A is T' */
1017  SubMatrixFromTMatrix(c->m,c->k,T,c->n,0,c->m,c->m,A);
1018 
1019  #if (_DEBUG>4)
1020  PrintVector(stdout,NULL,c->m,c->center);
1021  PrintMatrix(stdout,NULL,c->m,c->m,A);
1022  #endif
1023 
1025 
1026  if (sg>0) d=1;
1027  else
1028  {
1029  if (sg<0) d=0;
1030  else *singular=TRUE;
1031  }
1032 
1033  free(A);
1034  }
1035  }
1036  return(d);
1037 }
1038 
1039 double Manifold2Chart(double *p,unsigned int *tp,double *t,Tchart *c)
1040 {
1041  if (c->n==0) /* k==m */
1042  {
1043  if (tp!=NULL)
1044  DifferenceVectorTopology(c->m,tp,p,c->center,t);
1045  else
1046  DifferenceVector(c->m,p,c->center,t);
1047  return(Norm(c->m,t));
1048  }
1049  else
1050  {
1051  double *p1;
1052 
1053  /* Project a point to the tangent space */
1054  /* t=T'*(p-center)*/
1055  NEW(p1,c->m,double);
1056 
1057  DifferenceVector(c->m,p,c->center,p1);
1058  if (tp!=NULL)
1059  ArrayPi2Pi(c->m,tp,p1);
1060  TMatrixVectorProduct(c->m,c->k,c->T,p1,t);
1061 
1062  free(p1);
1063  return(Norm(c->k,t));
1064  }
1065 }
1066 
1067 
1068 
1070  double *t,unsigned int *tp,double *pInit,
1071  double *p,Tchart *c)
1072 {
1073  if (c->n==0) /* k==m */
1074  {
1075  SumVector(c->m,c->center,t,p);
1076  if (tp!=NULL)
1077  ArrayPi2Pi(c->m,tp,p);
1078  return(0.0);
1079  }
1080  else
1081  {
1082  double d;
1083  double epsilon;
1084  unsigned int i,it,maxIterations,nr,nrJ;
1085  boolean converged;
1086 
1087  TLinearSystem ls;
1088  double *aData;
1089  double *bData;
1090  double *xData;
1091 
1092  double error;
1093  double *p0;
1094  int err;
1095  double *dif;
1096 
1097  epsilon=GetParameter(CT_EPSILON,pr);
1098  maxIterations=(unsigned int)GetParameter(CT_MAX_NEWTON_ITERATIONS,pr);
1099 
1100  if (maxIterations==0)
1101  Error("MAX_NEWTON_ITERATIONS must be larger than 0 to use Map2Manifold");
1102 
1103  /* If we already identified a basis of the Jacobian (most of the cases), we
1104  can use these rows only. This produces a smaller system without changing
1105  the solution. If actually produces a squared sytem which are solved faster
1106  (non-squared systems are solved via less-squares which is slower). */
1107  if (c->BJ==NULL)
1108  nrJ=c->nrJ;
1109  else
1110  nrJ=c->n; /* squared system */
1111  nr=nrJ+c->k;
1112 
1113  /* Initializes the structure to solve linear systems */
1114  InitLS(nr,c->m,&ls);
1115 
1116  /* direct acces to the LS structures */
1117  aData=GetLSMatrixBuffer(&ls);
1118  bData=GetLSRHBuffer(&ls);
1119  xData=GetLSSolutionBuffer(&ls);
1120 
1121  /* Point on the tangent space corresponding to the given paremeters 't' */
1122  NEW(p0,c->m,double);
1123  Local2Global(t,tp,p0,c);
1124 
1125  /* If the user provides an initial estimation for the output use it
1126  (otherwise we will depart from the tangent space estimation. */
1127  if (pInit!=NULL)
1128  {
1129  /* pInit can be pi2pi-ed and this can cause a large error in
1130  the intial estimation when there is not such error.
1131  This is why we have to use DifferenceVectorTopology inside
1132  the loop. */
1133  if (p!=pInit)
1134  memcpy(p,pInit,sizeof(double)*c->m);
1135  }
1136  else
1137  memcpy(p,p0,sizeof(double)*c->m);
1138 
1139  /* Space for the difference between current point (p) and p0
1140  taking into account topology */
1141  NEW(dif,c->m,double);
1142 
1143  /* Iterate from this point to a point on the manifold */
1144  it=0;
1145  converged=FALSE;
1146  err=0;
1147  while((!converged)&&(it<maxIterations))
1148  {
1149  /* Define the residual (right-had side of the system) */
1150  if (c->BJ==NULL)
1151  { CS_WD_EVALUATE_SIMP_EQUATIONS(pr,p,bData,c->w); }
1152  else
1153  { CS_WD_EVALUATE_SUBSET_SIMP_EQUATIONS(pr,c->BJ,p,bData,c->w); }
1154 
1155  /* Complete the the right-hand side of the system of equations */
1156  DifferenceVectorTopology(c->m,tp,p,p0,dif);
1157  TMatrixVectorProduct(c->m,c->k,c->T,dif,&(bData[nrJ]));
1158 
1159  error=Norm(nr,bData);
1160 
1161  if (error<epsilon)
1162  //if ((it>0)&&(error<epsilon))
1163  converged=TRUE;
1164  else
1165  {
1166  /* To avoid overflows we assume that convergence
1167  is impossible with too large errors */
1168  if (error>1e10)
1169  it=maxIterations;
1170  else
1171  {
1172  /* Fill in the part of the 'A' corresponding to the Jacobian */
1173  if (c->BJ==NULL)
1174  EvaluateJacobianInVector(p,nr,c->m,aData,sJ);
1175  else
1176  EvaluateJacobianSubSetInVector(p,c->BJ,nr,c->m,aData,sJ);
1177 
1178  /* Now the part of the 'A' matrix corresponding to the tangent
1179  space (transposed) */
1180  SubMatrixFromTMatrix(c->m,c->k,c->T,nrJ,0,nr,c->m,aData);
1181 
1182  /* Once A and b are defined, solve the system */
1183  err=LSSolve(&ls);
1184 
1185  /* Update the estimate */
1186  if (err)
1187  it=maxIterations;
1188  else
1189  {
1190  for(i=0;i<c->m;i++)
1191  {
1192  p[i]-=xData[i];
1193  if ((tp!=NULL)&&(tp[i]==TOPOLOGY_S))
1194  PI2PI(p[i]);
1195  }
1196  it++;
1197  }
1198  }
1199  }
1200  }
1201 
1202  free(dif);
1203  DeleteLS(&ls);
1204 
1205  if (it<maxIterations)
1206  d=DistanceTopology(c->m,tp,p,p0);
1207  else
1208  d=INF;
1209  free(p0);
1210 
1211  return(d);
1212  }
1213 }
1214 
1215 void Local2Global(double *t,unsigned int *tp,double *p,Tchart *c)
1216 {
1217  if (c->n==0) /* k==m */
1218  {
1219  /*p=center+t*/
1220  SumVector(c->m,c->center,t,p);
1221  }
1222  else
1223  {
1224  /*p=center+T*t*/
1225  MatrixVectorProduct(c->m,c->k,c->T,t,p);
1226  AccumulateVector(c->m,c->center,p);
1227  }
1228  if (tp!=NULL)
1229  ArrayPi2Pi(c->m,tp,p);
1230 }
1231 
1232 double ChartErrorFromParameters(double *t,double *p,unsigned int *tp,
1233  Tchart *c)
1234 {
1235  if (c->n==0)
1236  return(0.0);
1237  else
1238  {
1239  double *p2,e;
1240 
1241  NEW(p2,c->m,double);
1242  Local2Global(t,tp,p2,c);
1243  e=DistanceTopology(c->m,tp,p,p2);
1244  free(p2);
1245 
1246  return(e);
1247  }
1248 }
1249 
1250 double Error2Chart(double *p,unsigned int *tp,Tchart *c)
1251 {
1252  if (c->n==0)
1253  return(0.0);
1254  else
1255  {
1256  double *t,e;
1257 
1258  NEW(t,c->k,double);
1259  Manifold2Chart(p,tp,t,c);
1260  e=ChartErrorFromParameters(t,p,tp,c);
1261  free(t);
1262 
1263  return(e);
1264  }
1265 }
1266 
1267 inline boolean CloseCharts(Tparameters *pr,unsigned int *tp,
1268  Tchart *c1,Tchart *c2)
1269 {
1270  return(IntersectChartsInt(pr,FALSE,tp,NULL,NO_UINT,c1,NO_UINT,c2));
1271 }
1272 
1273 boolean IntersectCharts(Tparameters *pr,unsigned int *tp,Tbox *ambient,
1274  unsigned int id1,Tchart *c1,
1275  unsigned int id2,Tchart *c2)
1276 {
1277  return(IntersectChartsInt(pr,TRUE,tp,ambient,id1,c1,id2,c2));
1278 }
1279 
1280 inline boolean CollisionChart(Tchart *c)
1281 {
1282  return(c->collision);
1283 }
1284 
1285 inline boolean FrontierChart(Tchart *c)
1286 {
1287  return(c->frontier);
1288 }
1289 
1290 inline void ChartIsFrontier(Tchart *c)
1291 {
1292  c->frontier=TRUE;
1293 }
1294 
1295 inline boolean ExpandibleChart(Tchart *c)
1296 {
1297  if (c->simple)
1298  Error("ExpandibleChart is undefined for simple charts");
1299 
1300  return((!c->frontier)&&(ExpandiblePolytope(c->p)));
1301 }
1302 
1303 inline boolean OpenChart(Tchart *c)
1304 {
1305  return((c->simple)||(ExpandiblePolytope(c->p)));
1306 }
1307 
1308 void WrongCorner(unsigned int nv,Tchart *c)
1309 {
1310  if (c->simple)
1311  Error("WrongCorner is undefined for simple charts");
1312 
1313  WrongPolytopeCorner(nv,c->p);
1314 }
1315 
1316 boolean InsideChartPolytope(double *t,Tchart *c)
1317 {
1318  if (c->simple)
1319  return(InsideSPolytope(t,c->sp));
1320  else
1321  return(InsidePolytope(t,c->p));
1322 }
1323 
1324 unsigned int DetermineChartNeighbour(double epsilon,double *t,Tchart *c)
1325 {
1326  if (c->simple)
1327  return(DetermineSPolytopeNeighbour(epsilon,t,c->sp));
1328  else
1329  {
1330  Error("DetermineChartNeighbour is only defined for simple charts");
1331  return(NO_UINT);
1332  }
1333 }
1334 
1335 void EnlargeChart(double *t,Tchart *c)
1336 {
1337  if (c->simple)
1338  EnlargeSPolytope(t,c->sp);
1339  else
1340  Error("EnlargeChart is only defined for simple charts");
1341 }
1342 
1343 boolean BoundaryPointFromExternalCorner(boolean rand,unsigned int *nv,double *t,Tchart *c)
1344 {
1345  if (c->simple)
1346  Error("BoundaryPointFromExternalCorner is undefined for simple charts");
1347 
1348  return(PolytopeBoundaryPointFromExternalCorner(c->r,rand,nv,t,c->p));
1349 }
1350 
1351 void BoundaryPointsFromExternalCorners(unsigned int *n,unsigned int **nv,double ***t,Tchart *c)
1352 {
1353  if (c->simple)
1354  Error("BoundaryPointsFromExternalCorners is undefined for simple charts");
1355 
1357 }
1358 
1359 boolean RandomPointOnBoundary(double *t,Tchart *c)
1360 {
1361  if (c->simple)
1362  return(SPolytopeRandomPointOnBoundary(c->r,t,c->sp));
1363  else
1364  return(PolytopeRandomPointOnBoundary(c->r,t,c->p));
1365 }
1366 
1367 boolean RandomPointInChart(Tparameters *pr,double scale,unsigned int *tp,double *t,double *p,Tchart *c)
1368 {
1369  boolean canSample;
1370 
1371  if (c->simple)
1372  canSample=RandomPointInSPolytope(scale,t,c->sp);
1373  else
1374  canSample=RandomPointInPolytope(t,c->p);
1375 
1376  if (canSample)
1377  Local2Global(t,tp,p,c);
1378 
1379  return(canSample);
1380 }
1381 
1383 {
1384  if (c->simple)
1386 }
1387 
1389 {
1390  if (c->simple)
1392 }
1393 
1395 {
1396  double v;
1397 
1398  /* use the cached volume stored in the charts. This
1399  significantly speeds up the query if we ask for the
1400  volume of a chart many times */
1401  if (c->simple)
1402  v=SPolytopeVolume(c->sp);
1403  else
1404  v=PolytopeVolume(c->p);
1405 
1406  return(v);
1407 }
1408 
1409 double ChartVolume(Tparameters *pr,boolean collisionFree,
1410  unsigned int *tp,TJacobian *sJ,Tchart *c)
1411 {
1412  double v;
1413 
1414  if (!collisionFree)
1415  v=ChartMaxVolume(c);
1416  else
1417  {
1418  double *t,*s;
1419  unsigned int i,n,in;
1420  boolean valid,inCollision;
1421 
1422  /* If collisions must be taken into account, we have to replicate
1423  the rejection sampling implemented in Polytope and SPolytope
1424  but including rejection due to obstacles */
1425 
1426  NEW(t,c->k,double);
1427  NEW(s,c->m,double);
1428 
1429  n=(unsigned int)floor(pow(10,c->k));
1430  if (n>10000) n=10000;
1431  in=0;
1432  for(i=0;i<n;i++)
1433  {
1434  if (c->simple)
1435  valid=RandomPointInSPolytope(1.0,t,c->sp);
1436  else
1437  valid=RandomPointInPolytope(t,c->p);
1438  if (valid)
1439  {
1440  if (Chart2Manifold(pr,sJ,t,tp,NULL,s,c)<INF)
1441  {
1442  CS_WD_IN_COLLISION(inCollision,pr,s,NULL,c->w);
1443  if (!inCollision)
1444  in++;
1445  }
1446  }
1447  }
1448  free(t);
1449  free(s);
1450 
1451  if (c->simple)
1452  v=SPolytopeMaxVolume(c->sp);
1453  else
1454  v=PolytopeMaxVolume(c->p);
1455 
1456  v*=((double)in/(double)n);
1457  }
1458  return(v);
1459 }
1460 
1461 boolean FocusedPointOnBoundary(double *p,unsigned int *tp,
1462  double *t,Tchart *c)
1463 {
1464  if (c->simple)
1465  Error("FocusedPointOnBoundary is undefined for simple charts");
1466 
1467  if (ExpandibleChart(c))
1468  {
1469  double nt;
1470 
1471  nt=Manifold2Chart(p,tp,t,c);
1472  ScaleVector(c->r/nt,c->k,t);
1473 
1474  return(InsidePolytope(t,c->p));
1475  }
1476  else
1477  return(FALSE);
1478 }
1479 
1480 boolean PathInChart(Tparameters *pr,double *t,unsigned int *tp,TJacobian *sJ,
1481  unsigned int nvs,boolean *systemVars,
1482  unsigned int *ms,
1483  double *pl,unsigned int *ns,double ***path,
1484  Tchart *c)
1485 {
1486  double *nt,*p,*pPrev;
1487  double delta,n;
1488  boolean projectionOk,collision,reached,close;
1489  unsigned int step,nv;
1490  double *o,*oPrev;
1491 
1492  delta=GetParameter(CT_DELTA,pr);
1493 
1494  NEW(p,c->m,double);
1495  NEW(pPrev,c->m,double);
1496  NEW(nt,c->k,double);
1497 
1498  /* We move from the center of the chart toward 't' */
1499  step=0; /* start at 0 to add the center */
1500  projectionOk=TRUE;
1501  collision=FALSE;
1502  n=Norm(c->k,t);
1503  reached=(n<delta);
1504  close=FALSE;
1505 
1506  /* depart from the center */
1507  memcpy(pPrev,c->center,c->m*sizeof(double));
1508  nv=CS_WD_REGENERATE_ORIGINAL_POINT(pr,pPrev,&oPrev,c->w);
1509 
1510  while((projectionOk)&&(!reached))
1511  {
1512  memcpy(nt,t,c->k*sizeof(double));
1513 
1514  /* If in the last step we where close to 't' just use
1515  it as a new set of parameters. Otherwise approach it */
1516  if (close)
1517  reached=TRUE;
1518  else
1519  ScaleVector(((double)step)*delta/n,c->k,nt);
1520 
1521  projectionOk=(Chart2Manifold(pr,sJ,nt,tp,pPrev,p,c)<=c->error);
1522 
1523  if (projectionOk)
1524  {
1525  (*pl)+=DistanceTopology(c->m,tp,pPrev,p);
1526 
1527  nv=CS_WD_REGENERATE_ORIGINAL_POINT(pr,p,&o,c->w);
1528  AddSample2Samples(nv,o,nvs,systemVars,ms,ns,path);
1529 
1530  collision=((collision)||(CS_WD_ORIGINAL_IN_COLLISION(pr,o,oPrev,c->w)));
1531 
1532  memcpy(oPrev,o,nv*sizeof(double));
1533  free(o);
1534 
1535  memcpy(pPrev,p,c->m*sizeof(double));
1536  close=(Distance(c->k,nt,t)<delta);
1537  }
1538 
1539  step++;
1540  }
1541  free(p);
1542  free(pPrev);
1543  free(nt);
1544  free(oPrev);
1545 
1546  return(!collision);
1547 }
1548 
1549 double DistanceOnChart(Tparameters *pr,double *t,unsigned int *tp,TJacobian *sJ,
1550  Tchart *c)
1551 {
1552  double *nt,*p,*pPrev;
1553  double delta,n,d;
1554  boolean projectionOk,inCollision,reached;
1555  unsigned int step;
1556 
1557  delta=GetParameter(CT_DELTA,pr);
1558 
1559  NEW(p,c->m,double);
1560  NEW(pPrev,c->m,double);
1561  NEW(nt,c->k,double);
1562 
1563  /* We move from the center of the chart toward 't' */
1564  step=1;
1565  projectionOk=TRUE;
1566  inCollision=FALSE;
1567  n=Norm(c->k,t);
1568  reached=(n<delta);
1569  d=0.0;
1570  memcpy(pPrev,c->center,c->m*sizeof(double));
1571 
1572  while((projectionOk)&&(!inCollision)&&(!reached)&&(d<INF))
1573  {
1574  memcpy(nt,t,c->k*sizeof(double));
1575  ScaleVector(((double)step)*delta/n,c->k,nt);
1576 
1577  projectionOk=(Chart2Manifold(pr,sJ,nt,tp,pPrev,p,c)<=c->error);
1578 
1579  if (projectionOk)
1580  {
1581  CS_WD_IN_COLLISION(inCollision,pr,p,pPrev,c->w);
1582 
1583  if (!inCollision)
1584  {
1585  d+=DistanceTopology(c->m,tp,pPrev,p);
1586  memcpy(pPrev,p,c->m*sizeof(double));
1587  reached=(Distance(c->k,nt,t)<delta);
1588  }
1589  else
1590  d=INF;
1591  }
1592  else
1593  d=INF;
1594 
1595  step++;
1596  }
1597 
1598  free(p);
1599  free(pPrev);
1600  free(nt);
1601 
1602  return(d);
1603 }
1604 
1606  double *p,unsigned int *tp,
1607  double *t,Tchart *c)
1608 {
1609  boolean inside;
1610 
1611  inside=FALSE;
1612 
1613  if ((Manifold2Chart(p,tp,t,c)<c->r)&&
1614  (InsideChartPolytope(t,c)))
1615  {
1616  double eps;
1617  double *p1;
1618 
1619  eps=GetParameter(CT_EPSILON,pr);
1620 
1621  NEW(p1,c->m,double);
1622 
1623  inside=((Chart2Manifold(pr,sJ,t,tp,NULL,p1,c)<c->error)&&
1624  (DistanceTopology(c->m,tp,p1,p)<eps));
1625 
1626  free(p1);
1627  }
1628 
1629  return(inside);
1630 }
1631 
1632 unsigned int ClassifyPointInChart(Tparameters *pr,boolean error,TJacobian *sJ,
1633  double *p,unsigned int *tp,
1634  double *t,Tchart *c)
1635 {
1636  double eps;
1637  double *p1;
1638  unsigned int cs;
1639 
1640  eps=GetParameter(CT_EPSILON,pr);
1641  NEW(p1,c->m,double);
1642 
1643  if (Manifold2Chart(p,tp,t,c)>c->r)
1644  {
1645  /* out of the ball */
1646  if (InsideChartPolytope(t,c)) /* but still inside the polytope */
1647  cs=1; /* In the chart scope but out of the ball */
1648  else
1649  cs=4; /* Completely out of the scope of the chart */
1650  }
1651  else
1652  {
1653  /* In the ball */
1654  if (InsideChartPolytope(t,c))
1655  {
1656  if ((error)&&((Chart2Manifold(pr,sJ,t,tp,NULL,p1,c)>c->error)||
1657  (DistanceTopology(c->m,tp,p1,p)>eps)))
1658  cs=3; /* Out of the scope due to lack of convergence or large error */
1659  else
1660  cs=0; /* In inside the scope of this chart */
1661  }
1662  else
1663  cs=2; /* Was inside the scope of this chart but is in a neighbouring chart now */
1664  }
1665 
1666  free(p1);
1667 
1668  return(cs);
1669 }
1670 
1671 
1672 void LinkCharts(unsigned int id1,Tchart *c1,unsigned int id2,Tchart *c2)
1673 {
1674  LinkChart(id1,c2);
1675  LinkChart(id2,c1);
1676 }
1677 
1678 unsigned int ChartNumNeighbours(Tchart *c)
1679 {
1680  unsigned int n;
1681 
1682  if (c->simple)
1683  n=SPolytopeNumNeighbours(c->sp);
1684  else
1685  n=PolytopeNumNeighbours(c->p);
1686 
1687  return(c->nl+n);
1688 }
1689 
1690 unsigned int ChartNeighbourID(unsigned int n,Tchart *c)
1691 {
1692  unsigned int id;
1693 
1694  if (n<c->nl)
1695  id=c->l[n];
1696  else
1697  {
1698  if (c->simple)
1699  id=SPolytopeNeighbourID(n-c->nl,c->sp);
1700  else
1701  id=PolytopeNeighbourID(n-c->nl,c->p);
1702  }
1703 
1704  return(id);
1705 }
1706 
1708  unsigned int *nn,unsigned int **cID1,unsigned int **cID2,Tchart *c)
1709 {
1710  Tcpolytope *p;
1711 
1712  if (c->simple)
1713  {
1714  NEW(p,1,Tcpolytope);
1715  SPolytope2Polytope(pr,c->sp,p);
1716  }
1717  else
1718  p=c->p;
1719 
1720  GetPolytopeNeighboursFromVertices(nn,cID1,cID2,p);
1721 
1722  if (c->simple)
1723  {
1724  DeletePolytope(p);
1725  free(p);
1726  }
1727 }
1728 
1729 void PlotChart(Tparameters *pr,FILE *fcost,TJacobian *sJ,
1730  unsigned int xID,unsigned int yID,unsigned int zID,
1731  Tplot3d *p3d,Tchart *c)
1732 {
1733  if (c->k>3)
1734  Error("PlotChart only works for 2/3d manifolds");
1735 
1736  if ((PLOT_AS_POLYGONS)&&((c->k==2)||(c->k==3)))
1737  {
1738  if (c->k==2)
1739  PlotChartAsPolygon(pr,fcost,sJ,xID,yID,zID,p3d,c);
1740  else
1741  PlotChartAsBox(pr,xID,yID,zID,p3d,c);
1742  }
1743  else
1744  {
1745  unsigned int nv;
1746  double **v;
1747  Tcpolytope *p;
1748 
1749  if (c->simple)
1750  {
1751  NEW(p,1,Tcpolytope);
1752  SPolytope2Polytope(pr,c->sp,p);
1753  }
1754  else
1755  p=c->p;
1756 
1757  GetPolytopeVertices(&nv,&v,p);
1758 
1759  if (nv>0)
1760  {
1761  unsigned int i,k,n1,n2;
1762  unsigned int ne;
1763  unsigned int *v1;
1764  unsigned int *v2;
1765  double *x,*y,*z;
1766  double *g,*o;
1767  double ox,oy,oz;
1768  double cx,cy,cz;
1769 
1770  /* Collect the edges of the polytope bounding the chart (local coordinates) */
1771  GetPolytopeEdges(&ne,&v1,&v2,p);
1772 
1773  /* Transform the polytope edges from local to gobal */
1774 
1775  NEW(g,c->m,double); /* space for the points in global */
1776 
1777  NEW(x,2*ne,double); /* space for the vertices in global */
1778  NEW(y,2*ne,double);
1779  NEW(z,2*ne,double);
1780 
1781  for(i=0,k=0;i<ne;i++,k+=2)
1782  {
1783  /*Extremes of the edges*/
1784  n1=v1[i];
1785  n2=v2[i];
1786 
1787  if ((!PLOT_ON_MANIFOLD)||
1788  (Chart2Manifold(pr,sJ,v[n1],NULL,NULL,g,c)==INF))
1789  Local2Global(v[n1],NULL,g,c);
1790  CS_WD_REGENERATE_ORIGINAL_POINT(pr,g,&o,c->w);
1791  x[k]=o[xID];
1792  y[k]=o[yID];
1793  z[k]=o[zID];
1794  free(o);
1795 
1796  if ((!PLOT_ON_MANIFOLD)||
1797  (Chart2Manifold(pr,sJ,v[n2],NULL,NULL,g,c)==INF))
1798  Local2Global(v[n2],NULL,g,c);
1799  CS_WD_REGENERATE_ORIGINAL_POINT(pr,g,&o,c->w);
1800  x[k+1]=o[xID];
1801  y[k+1]=o[yID];
1802  z[k+1]=o[zID];
1803  free(o);
1804  }
1805 
1806  /* If any of the vertices is out of the box in global coordiantes
1807  offset the whole polygon */
1808  cx=GetParameter(CT_CUT_X,pr);
1809  cy=GetParameter(CT_CUT_Y,pr);
1810  cz=GetParameter(CT_CUT_Z,pr);
1811 
1812  ox=0;
1813  oy=0;
1814  oz=0;
1815 
1816  for(k=0;k<2*ne;k++)
1817  {
1818  if ((cx<0)&&(x[k]<cx))
1819  ox=+M_2PI;
1820  if ((cx>0)&&(x[k]>cx))
1821  ox=-M_2PI;
1822  if ((cy<0)&&(y[k]<cy))
1823  oy=+M_2PI;
1824  if ((cy>0)&&(y[k]>cy))
1825  oy=-M_2PI;
1826  if ((cz<0)&&(z[k]<cz))
1827  oz=+M_2PI;
1828  if ((cz>0)&&(z[k]>cz))
1829  oz=-M_2PI;
1830  }
1831 
1832  /* Apply the offset if any */
1833  for(k=0;k<2*ne;k++)
1834  {
1835  x[k]+=ox;
1836  y[k]+=oy;
1837  z[k]+=oz;
1838  }
1839 
1840  /* Plot the edges defining the polygon (possibly with offset) */
1841  for(k=0;k<2*ne;k+=2)
1842  PlotVect3d(2,&(x[k]),&(y[k]),&(z[k]),p3d);
1843 
1844  /* Release allocated space */
1845  free(g);
1846 
1847  free(x);
1848  free(y);
1849  free(z);
1850 
1851  for(i=0;i<nv;i++)
1852  free(v[i]);
1853  free(v);
1854  free(v1);
1855  free(v2);
1856  }
1857  if (c->simple)
1858  {
1859  DeletePolytope(p);
1860  free(p);
1861  }
1862  }
1863 }
1864 
1865 unsigned int ChartMemSize(Tchart *c)
1866 {
1867  unsigned int b;
1868 
1869  b=sizeof(double)*c->m; /* center */
1870  b+=sizeof(double)*(c->m*c->k); /* T */
1871 
1872  if (c->simple)
1873  b+=SPolytopeMemSize(c->sp);
1874  else
1875  b+=PolytopeMemSize(c->p);
1876 
1877  return(b);
1878 }
1879 
1880 void SaveChart(FILE *f,Tchart *c)
1881 {
1882  unsigned int i;
1883 
1884  /* Save map */
1885  fprintf(f,"%u\n",c->m);
1886  fprintf(f,"%u\n",c->k);
1887  fprintf(f,"%u\n",c->n);
1888  fprintf(f,"%u\n",c->nrJ);
1889 
1890  fprintf(f,"%f\n",c->error);
1891  fprintf(f,"%f\n",c->eCurv);
1892  fprintf(f,"%f\n0\n",c->r); /* the 0 is for rSample (back-compatibility) */
1893  fprintf(f,"%u\n",c->degree);
1894  fprintf(f,"%u\n",c->frontier);
1895  fprintf(f,"%u\n",c->singular);
1896 
1897  for(i=0;i<c->m;i++)
1898  fprintf(f,"%.16f ",c->center[i]);
1899  fprintf(f,"\n");
1900 
1901  if (c->n>0)
1902  {
1903  for(i=0;i<c->m*c->k;i++)
1904  fprintf(f,"%.16f ",c->T[i]);
1905  fprintf(f,"\n");
1906 
1907  if (c->BJ==NULL)
1908  fprintf(f,"0\n");
1909  else
1910  {
1911  fprintf(f,"1\n");
1912  for(i=0;i<c->nrJ;i++)
1913  fprintf(f,"%u ",c->BJ[i]);
1914  fprintf(f,"\n");
1915  }
1916  }
1917 
1918  fprintf(f,"%u\n",c->ml);
1919  if (c->ml>0)
1920  {
1921  fprintf(f,"%u\n",c->nl);
1922  for(i=0;i<c->nl;i++)
1923  fprintf(f,"%u ",c->l[i]);
1924  fprintf(f,"\n");
1925  }
1926 
1927  /* Save polytope */
1928  fprintf(f,"%u\n",c->simple);
1929  if (c->simple)
1930  SaveSPolytope(f,c->sp);
1931  else
1932  SavePolytope(f,c->p);
1933 }
1934 
1935 void LoadChart(FILE *f,TAtlasBase *w,Tchart *c)
1936 {
1937  unsigned int i,flag;
1938  double rSample;
1939 
1940  /* Load map */
1941  c->w=w;
1942 
1943  fscanf(f,"%u",&(c->m));
1944  fscanf(f,"%u",&(c->k));
1945  fscanf(f,"%u",&(c->n));
1946  fscanf(f,"%u",&(c->nrJ));
1947 
1948  fscanf(f,"%lf",&(c->error));
1949  fscanf(f,"%lf",&(c->eCurv));
1950  fscanf(f,"%lf",&(c->r));
1951  fscanf(f,"%lf",&rSample); /*for back-compatibility*/
1952  fscanf(f,"%u",&(c->degree));
1953  fscanf(f,"%u",&(c->frontier));
1954  fscanf(f,"%u",&(c->singular));
1955 
1956  NEW(c->center,c->m,double);
1957  for(i=0;i<c->m;i++)
1958  fscanf(f,"%lf",&(c->center[i]));
1959 
1960  if (c->n==0)
1961  {
1962  c->T=NULL;
1963  c->BJ=NULL;
1964  }
1965  else
1966  {
1967  NEW(c->T,c->m*c->k,double);
1968  for(i=0;i<c->m*c->k;i++)
1969  fscanf(f,"%lf",&(c->T[i]));
1970 
1971  /* Do not load the Jacobian Basis. We keep the
1972  read code for back-compatibility. */
1973  fscanf(f,"%u",&flag);
1974  if (flag)
1975  {
1976  NEW(c->BJ,c->nrJ,boolean);
1977  for(i=0;i<c->nrJ;i++)
1978  fscanf(f,"%u",&(c->BJ[i]));
1979  }
1980  else
1981  c->BJ=NULL;
1982  }
1983 
1984  fscanf(f,"%u",&(c->ml));
1985  if (c->ml>0)
1986  {
1987  NEW(c->l,c->ml,unsigned int);
1988  fscanf(f,"%u",&(c->nl));
1989  for(i=0;i<c->nl;i++)
1990  fscanf(f,"%u",&(c->l[i]));
1991  }
1992  else
1993  {
1994  c->nl=0;
1995  c->l=NULL;
1996  }
1997 
1998  /* Load Polytope */
1999  fscanf(f,"%u\n",&(c->simple));
2000  if (c->simple)
2001  {
2002  NEW(c->sp,1,Tscpolytope);
2003  LoadSPolytope(f,c->sp);
2004  c->p=NULL;
2005  }
2006  else
2007  {
2008  NEW(c->p,1,Tcpolytope);
2009  LoadPolytope(f,c->p);
2010  c->sp=NULL;
2011  }
2012 }
2013 
2015 {
2016  /* Delete map center */
2017  if (c->center!=NULL)
2018  free(c->center);
2019 
2020  /* Delete tangent space */
2021  if (c->T!=NULL)
2022  free(c->T);
2023 
2024  /* Delete Jacobian basis */
2025  if (c->BJ!=NULL)
2026  free(c->BJ);
2027 
2028  /* Delete the list of linked charts */
2029  if (c->l!=NULL)
2030  free(c->l);
2031 
2032  /* Delete Polytope */
2033  if (c->p!=NULL)
2034  {
2035  DeletePolytope(c->p);
2036  free(c->p);
2037  }
2038  if (c->sp!=NULL)
2039  {
2040  DeleteSPolytope(c->sp);
2041  free(c->sp);
2042  }
2043 }
int MatrixDeterminantSgn(double epsilon, unsigned int n, double *A)
Sign of the determinant of a matrix.
unsigned int k
Definition: chart.h:74
Tcpolytope * p
Definition: chart.h:107
void CopyChart(Tchart *c_dst, Tchart *c_src)
Copy constructor.
Definition: chart.c:836
double GetChartMaxCurvError(Tchart *c)
Returns the maximum oriented curvature error between the chart and the manifold.
Definition: chart.c:958
void PlotVect3d(unsigned int n, double *x, double *y, double *z, Tplot3d *p)
Adds a polyline to the current object.
Definition: plot3d.c:447
CBLAS_INLINE void ScaleVector(double f, unsigned int s, double *v)
Scales a vector.
Definition: basic_algebra.c:30
boolean PointOnChart(Tparameters *pr, TJacobian *sJ, double *p, unsigned int *tp, double *t, Tchart *c)
Identify points on a chart.
Definition: chart.c:1605
void SaveChart(FILE *f, Tchart *c)
Stores the chart information on a file.
Definition: chart.c:1880
double * GetLSSolutionBuffer(TLinearSystem *ls)
Buffer to store the linear system solution.
Definition: algebra.c:1177
double PolytopeVolume(Tcpolytope *mp)
Polytope volume.
Definition: cpolytope.c:951
unsigned int ChartMemSize(Tchart *c)
Memory used by a given chart.
Definition: chart.c:1865
boolean PolytopeRandomPointOnBoundary(double rSample, double *t, Tcpolytope *mp)
Random point on the boundary of the chart.
Definition: cpolytope.c:908
void EnlargeSPolytope(double *t, Tscpolytope *mp)
Ensures that a polytompe includes a given point.
Definition: scpolytope.c:170
#define REP_JOINTS
One of the possible values of the REPRESENTATION parameter.
Definition: parameters.h:60
double error
Definition: chart.h:79
void CopySPolytope(Tscpolytope *mp_dst, Tscpolytope *mp_src)
Copies the simplified polytope from one chart to another.
Definition: scpolytope.c:54
#define CS_WD_ERROR_IN_SIMP_EQUATIONS(pr, p, wcs)
Computes the error in the simplified system for a given point.
Definition: wcs.h:509
#define CT_SR
Sampling ball in atlas.
Definition: parameters.h:266
void PlotBox3d(double min_x, double max_x, double min_y, double max_y, double min_z, double max_z, Tplot3d *p)
Adds an axis aligned box to the current object.
Definition: plot3d.c:224
void GetPolytopeVertices(unsigned int *nv, double ***v, Tcpolytope *mp)
Gets the set of vertices of the polytope.
Definition: cpolytope.c:1027
#define CT_EPSILON
Numerical tolerance.
Definition: parameters.h:194
#define FALSE
FALSE.
Definition: boolean.h:30
unsigned int * l
Definition: chart.h:103
boolean CompareTangentSpaces(Tchart *c1, Tchart *c2)
Checks if the tangent spaces are similar.
Definition: chart.c:904
boolean RandomPointInSPolytope(double scale, double *t, Tscpolytope *mp)
Random point on the polytope with uniform distribution.
Definition: scpolytope.c:262
boolean SPolytopeRandomPointOnBoundary(double rSample, double *t, Tscpolytope *mp)
Random point on the boundary of the chart.
Definition: scpolytope.c:255
#define PLOT_ON_MANIFOLD
Set to 1 to project charts to the manifold before plotting.
Definition: chart.h:40
double DistanceTopology(unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points.
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
void EvaluateTransposedJacobianInVector(double *v, unsigned int nr, unsigned int nc, double *m, TJacobian *j)
Evaluates the transposed Jacobian.
Definition: jacobian.c:143
Data structure to hold the information about the name of a file.
Definition: filename.h:271
void WrongPolytopeCorner(unsigned int nv, Tcpolytope *mp)
Mark a vertex as wrong.
Definition: cpolytope.c:684
void ArrayPi2Pi(unsigned int n, unsigned int *t, double *a)
Applies PI2PI to an array.
boolean collision
Definition: chart.h:84
boolean simple
Definition: chart.h:106
double MatrixDeterminant(unsigned int n, double *A)
Determinant of a matrix.
boolean BoundaryPointFromExternalCorner(boolean rand, unsigned int *nv, double *t, Tchart *c)
Random point on the chart boundary from the polytope vetices.
Definition: chart.c:1343
void PlotChartAsPolygon(Tparameters *pr, FILE *fcost, TJacobian *sJ, unsigned int xID, unsigned int yID, unsigned int zID, Tplot3d *p3d, Tchart *c)
Plots a 3d projection of a local chart as a filled polygon.
Definition: chart.c:402
boolean * GetChartJacobianBasis(Tchart *c)
Gets the index of the basis of the Jacobian vectors forming a basis.
Definition: chart.c:978
void CutSPolytopeWithFace(double *t, double offset, unsigned int id, Tscpolytope *mp)
Cuts a simple polytope with a given plane.
Definition: scpolytope.c:199
CBLAS_INLINE void TMatrixMatrixProduct(unsigned int ra, unsigned int ca, double *A, unsigned int cb, double *B, double *C)
C = A^t * B.
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
void LinkCharts(unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Connect charts at singularities.
Definition: chart.c:1672
CBLAS_INLINE void SumVector(unsigned int s, double *v1, double *v2, double *v)
Adds two vectors.
Definition: basic_algebra.c:67
#define PI2PI(a)
Forces an angle go be in [-pi,pi].
Definition: defines.h:205
void DifferenceVectorTopology(unsigned int s, unsigned int *tp, double *v1, double *v2, double *v)
Substracts two vectors.
void DeletePolytope(Tcpolytope *mp)
Deletes the structure allocated by DefinePolytope.
Definition: cpolytope.c:1380
CBLAS_INLINE void AccumulateVector(unsigned int s, double *v1, double *v2)
Adds a vector to another vectors.
Definition: basic_algebra.c:55
void SPolytope2Polytope(Tparameters *pr, Tscpolytope *sp, Tcpolytope *p)
Defines a chart polytope from a simple chart polytope.
Definition: cpolytope.c:188
boolean isCS
Definition: wcs.h:31
boolean FocusedPointOnBoundary(double *p, unsigned int *tp, double *t, Tchart *c)
Generates point on the boundary towards a given goal.
Definition: chart.c:1461
double GetChartMaxError(Tchart *c)
Returns the maximum error between the chart and the manifold.
Definition: chart.c:953
boolean CutPolytope(Tparameters *pr, double *t, double r, unsigned int id, void *wcs, void *c, unsigned int m, unsigned int *tp, Tbox *ambient, Tcpolytope *mp)
Crops the polytope bounding chart with a plane.
Definition: cpolytope.c:396
#define TRUE
TRUE.
Definition: boolean.h:21
unsigned int SPolytopeNumNeighbours(Tscpolytope *mp)
Number of neighbours of the simple polytope.
Definition: scpolytope.c:328
double SPolytopeMaxVolume(Tscpolytope *mp)
Maximum volume of the simple polytope.
Definition: scpolytope.c:300
void IncreaseChartSamplingRadius(Tchart *c)
Increase the sampling radious of the chart.
Definition: chart.c:1382
double MinCosinusBetweenCharts(Tchart *c1, Tchart *c2)
Computes the angle between the tangent spaces in the charts.
Definition: chart.c:923
void CutSPolytope(double *t, double r, unsigned int id, Tscpolytope *mp)
Crops the polytope bounding chart with a plane.
Definition: scpolytope.c:186
boolean * BJ
Definition: chart.h:95
double Chart2Manifold(Tparameters *pr, TJacobian *sJ, double *t, unsigned int *tp, double *pInit, double *p, Tchart *c)
Returns the point in the manifold for a given set of parameteres.
Definition: chart.c:1069
void Error(const char *s)
General error function.
Definition: error.c:80
All the necessary information to generate equations for mechanisms.
Definition: world.h:229
#define CUIK_EXT
File extension for equation files.
Definition: filename.h:71
A color.
Definition: color.h:86
void GetJacobianSize(unsigned int *nr, unsigned int *nc, TJacobian *j)
Returns the size of the Jacobian.
Definition: jacobian.c:49
double ChartMaxVolume(Tchart *c)
Estimate the volume of a chart.
Definition: chart.c:1394
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
A chart on a manifold.
Definition: chart.h:70
void SaveSPolytope(FILE *f, Tscpolytope *mp)
Saves the chart polytope to a file.
Definition: scpolytope.c:351
Error and warning functions.
void InitCSWDFromFile(Tparameters *pr, char *name, TAtlasBase *wcs)
Initializes a world or a CuikSystem structre.
Definition: chart.c:618
#define CS_WD_EVALUATE_SUBSET_SIMP_EQUATIONS(pr, st, p, r, wcs)
Evaluates a subset of the simplified set of equations.
Definition: wcs.h:192
void DeleteFileName(Tfilename *fn)
Destructor.
Definition: filename.c:205
#define PLOT_AS_POLYGONS
Set to 1 to get a nicer plot for 2D manifolds.
Definition: chart.h:50
A 3D plot.
Definition: plot3d.h:54
double GetChartRadius(Tchart *c)
Returns de range of the chart.
Definition: chart.c:941
boolean IntersectChartsInt(Tparameters *pr, boolean cut, unsigned int *tp, Tbox *ambient, unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Intersects two local charts.
Definition: chart.c:287
#define CT_CUT_X
Limit of domain of the X dimension of 3d plots.
Definition: parameters.h:420
void BoundaryPointsFromExternalCorners(unsigned int *n, unsigned int **nv, double ***t, Tchart *c)
All the possible points on the chart's boundary from polytope vertices.
Definition: chart.c:1351
double Distance(unsigned int s, double *v1, double *v2)
Computes the distance of two points.
void AddSample2Samples(unsigned int nv, double *sample, unsigned int nvs, boolean *systemVars, unsigned int *ms, unsigned int *ns, double ***path)
Adds a sample to a set of samples.
Definition: samples.c:672
A simpleifed polytope associated with chart on a manifold.
Definition: scpolytope.h:45
void PrintVector(FILE *f, char *label, unsigned int n, double *v)
Prints a vector.
void LinkChart(unsigned int id, Tchart *c)
Add a map indentifier to the list of linked charts.
Definition: chart.c:217
unsigned int InitChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:795
void EvaluateJacobianInVector(double *v, unsigned int nr, unsigned int nc, double *m, TJacobian *j)
Evaluates the Jacobian.
Definition: jacobian.c:103
void AddBorderConstraint(Tparameters *pr, double *t, unsigned int *tp, Tbox *ambient, Tchart *c)
Crops the domain for a given chart.
Definition: chart.c:229
TCuikSystem * cs
Definition: wcs.h:32
CBLAS_INLINE double GeneralDotProduct(unsigned int s, double *v1, double *v2)
Computes the dot product of two general vectors.
Definition: basic_algebra.c:15
CBLAS_INLINE void MatrixVectorProduct(unsigned int r, unsigned int c, double *A, double *b, double *o)
Product of a matrix and a vector.
double * T
Definition: chart.h:93
unsigned int PolytopeNumNeighbours(Tcpolytope *mp)
Number of neighbours of the polytope.
Definition: cpolytope.c:974
#define CT_CUT_Z
Limit of domain of the Z dimension of 3d plots.
Definition: parameters.h:444
#define CS_WD_SIMP_INEQUALITIES_HOLD(pr, p, wcs)
Cheks if all inequalities hold.
Definition: wcs.h:207
boolean RandomPointInChart(Tparameters *pr, double scale, unsigned int *tp, double *t, double *p, Tchart *c)
Samples a random point in the area covered by the chart.
Definition: chart.c:1367
double SPolytopeGetSamplingRadius(Tscpolytope *mp)
Returns the current sampling radius.
Definition: scpolytope.c:281
Definitions of constants and macros used in several parts of the cuik library.
double r
Definition: chart.h:81
boolean CollisionChart(Tchart *c)
Identifies collision charts.
Definition: chart.c:1280
unsigned int degree
Definition: chart.h:83
boolean ExpandiblePolytope(Tcpolytope *mp)
Identifies polytopes not fully bounded.
Definition: cpolytope.c:679
double GetChartSamplingRadius(Tchart *c)
Returns de sampling range of the chart.
Definition: chart.c:946
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
void Plot3dObjectWithColor(unsigned int nv, unsigned int nf, unsigned int ne, double **v, unsigned int *nvf, unsigned int **fv, Tcolor *c, Tplot3d *p)
Adds a colored polytope to the current object.
Definition: plot3d.c:304
void PolytopeBoundaryPointsFromExternalCorners(double rSample, unsigned int *n, unsigned int **nv, double ***t, Tcpolytope *mp)
Points on boundary from all the polytope vertexes.
Definition: cpolytope.c:876
unsigned int PolytopeNeighbourID(unsigned int n, Tcpolytope *mp)
Returns the identifier of one of the neighbours of a polytope.
Definition: cpolytope.c:992
unsigned int ml
Definition: chart.h:99
boolean CutPolytopeWithFace(Tparameters *pr, double *t, double offset, unsigned int id, void *wcs, void *c, unsigned int m, unsigned int *tp, Tbox *ambient, Tcpolytope *mp)
Cuts a polytope with a given plane.
Definition: cpolytope.c:412
double * GetChartTangentSpace(Tchart *c)
Gets the chart tangent space.
Definition: chart.c:973
Tworld * w
Definition: wcs.h:34
void InitCuikSystemFromFile(Tparameters *p, char *filename, TCuikSystem *cs)
Constructor from a file.
void DeleteSPolytope(Tscpolytope *mp)
Deletes the structure allocated by DefineSPolytope.
Definition: scpolytope.c:411
void InitEmptySPolytope(double delta, unsigned int k, double r, double sr, Tscpolytope *mp)
Defines an empty chart simplieifed polytope.
Definition: scpolytope.c:21
double DistanceOnChart(Tparameters *pr, double *t, unsigned int *tp, TJacobian *sJ, Tchart *c)
Distance between the center of a chart and a point on this chart.
Definition: chart.c:1549
double ChartVolume(Tparameters *pr, boolean collisionFree, unsigned int *tp, TJacobian *sJ, Tchart *c)
Estimate the volume of a chart.
Definition: chart.c:1409
boolean PolytopeBoundaryPointFromExternalCorner(double rSample, boolean rand, unsigned int *nv, double *t, Tcpolytope *mp)
Random point on the boundary from the polytope vetices.
Definition: cpolytope.c:847
unsigned int m
Definition: chart.h:73
void Warning(const char *s)
General warning function.
Definition: error.c:116
unsigned int ComputeJacobianKernelBasis(double epsilon, TJacobian *sJ, Tchart *c)
Computes the kernel of the Jacobian and, optionally its basis.
Definition: chart.c:193
A table of parameters.
void CreateFileName(char *path, char *name, char *suffix, char *ext, Tfilename *fn)
Constructor.
Definition: filename.c:22
void GetChartNeighboursFromVertices(Tparameters *pr, unsigned int *nn, unsigned int **cID1, unsigned int **cID2, Tchart *c)
Returns the identifier of neighbouring charts coincident at a vertex.
Definition: chart.c:1707
unsigned int GetChartAmbientDim(Tchart *c)
Dimensionality of the ambient space.
Definition: chart.c:963
unsigned int nrJ
Definition: chart.h:76
double * center
Definition: chart.h:92
boolean singular
Definition: chart.h:88
boolean FrontierChart(Tchart *c)
Identifies frontier charts.
Definition: chart.c:1285
void DeleteChart(Tchart *c)
Destructor.
Definition: chart.c:2014
void SavePolytope(FILE *f, Tcpolytope *mp)
Saves the chart polytope to a file.
Definition: cpolytope.c:1187
Type defining the equations on which the atlas is defined.
Definition: wcs.h:30
void GetPolytopeNeighboursFromVertices(unsigned int *nv, unsigned int **cID1, unsigned int **cID2, Tcpolytope *mp)
Identifiy the three charts coincident at a vertex.
Definition: cpolytope.c:1061
Definition of a local chart on a manifold.
TAtlasBase * w
Definition: chart.h:72
double MinCosinusBetweenSubSpaces(unsigned int m, unsigned int k, double *T1, double *T2)
Computes the cosinus of the maximum angle between two lineal sub-spaces.
boolean InsidePolytope(double *t, Tcpolytope *mp)
Identifies points inside a chart polytope.
Definition: cpolytope.c:329
char * GetFileFullName(Tfilename *fn)
Gets the file full name (paht+name+extension).
Definition: filename.c:151
void InitLS(unsigned int nr, unsigned int nc, TLinearSystem *ls)
Defines a linear system structure.
boolean IntersectCharts(Tparameters *pr, unsigned int *tp, Tbox *ambient, unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Intersects two local charts.
Definition: chart.c:1273
#define M_2PI
2*Pi.
Definition: defines.h:100
#define CT_REPRESENTATION
Representation.
Definition: parameters.h:215
unsigned int DetermineSPolytopeNeighbour(double epsilon, double *t, Tscpolytope *mp)
Identifes the neighbour containing a given point.
Definition: scpolytope.c:105
CBLAS_INLINE void TMatrixVectorProduct(unsigned int r, unsigned int c, double *A, double *b, double *o)
Product of a transposed matrix and a vector.
unsigned int InitTrustedChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:819
#define CS_WD_REGENERATE_ORIGINAL_POINT(pr, p, o, wcs)
Completes an original point from a simplified one.
Definition: wcs.h:293
unsigned int nl
Definition: chart.h:102
boolean ExpandibleChart(Tchart *c)
Identifies boundary charts.
Definition: chart.c:1295
boolean InitWorldFromFile(Tparameters *p, boolean error, char *fn, Tworld *w)
Constructor.
A box.
Definition: box.h:83
unsigned int SPolytopeMemSize(Tscpolytope *mp)
Computes the memory used by the polytope.
Definition: scpolytope.c:341
unsigned int PolytopeMemSize(Tcpolytope *mp)
Computes the memory used by the polytope.
Definition: cpolytope.c:1169
void ChartIsFrontier(Tchart *c)
Marks a chart as a frontier chart.
Definition: chart.c:1290
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
A cuiksystem, i.e., a set of variables and equations defining a position analysis problem...
Definition: cuiksystem.h:181
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
void LoadSPolytope(FILE *f, Tscpolytope *mp)
Reads the chart polytope from a file.
Definition: scpolytope.c:377
boolean InsideSPolytope(double *t, Tscpolytope *mp)
Identifies points inside a chart simple polytope.
Definition: scpolytope.c:88
double * GetChartCenter(Tchart *c)
Returns the center of the chart.
Definition: chart.c:936
void EvaluateJacobianSubSetInVector(double *v, boolean *sr, unsigned int nr, unsigned int nc, double *m, TJacobian *j)
Evaluates some of the Jacobian equations.
Definition: jacobian.c:120
A polytope associated with chart on a manifold.
Definition: cpolytope.h:52
boolean RandomPointOnBoundary(double *t, Tchart *c)
Random point on the boundary of the chart.
Definition: chart.c:1359
unsigned int n
Definition: chart.h:75
#define CS_WD_EVALUATE_SIMP_EQUATIONS(pr, p, r, wcs)
Evaluates the simplified set of equations.
Definition: wcs.h:176
boolean InsideChartPolytope(double *t, Tchart *c)
Checks if a parameter point is inside the chart polytope.
Definition: chart.c:1316
double eCurv
Definition: chart.h:80
void SPolytopeIncreaseSamplingRadius(Tscpolytope *mp)
Increases the sampling radius.
Definition: scpolytope.c:286
void CopyPolytope(Tcpolytope *mp_dst, Tcpolytope *mp_src)
Copies the polytope from one chart to another.
Definition: cpolytope.c:229
unsigned int FindKernelAndIndependentRows(unsigned int nr, unsigned int nc, double *mT, unsigned int dof, double epsilon, boolean *singular, boolean **IR, double **T)
Computes the kernel of a matrix and determines the independent rows of this matrix.
Definition: algebra.c:1133
The Jacobian of a set of equations.
Definition: jacobian.h:23
void Local2Global(double *t, unsigned int *tp, double *p, Tchart *c)
Transforms a parameter in tangent space to a point in ambient space.
Definition: chart.c:1215
boolean OpenChart(Tchart *c)
Identifies charts not fully sorrounded by other charts.
Definition: chart.c:1303
double Error2Chart(double *p, unsigned int *tp, Tchart *c)
Distance from the manifold to the tangent space.
Definition: chart.c:1250
#define CT_MAX_NEWTON_ITERATIONS
Maximum number of iterations in the Newton-Raphson function.
Definition: parameters.h:311
double Manifold2Chart(double *p, unsigned int *tp, double *t, Tchart *c)
Returns the parametrization of a point.
Definition: chart.c:1039
boolean CloseCharts(Tparameters *pr, unsigned int *tp, Tchart *c1, Tchart *c2)
Identifies close local charts.
Definition: chart.c:1267
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
void DeleteLS(TLinearSystem *ls)
Releases a linear system structure.
void WrongCorner(unsigned int nv, Tchart *c)
Mark a vertex as wrong.
Definition: chart.c:1308
double * GetLSRHBuffer(TLinearSystem *ls)
Buffer to store the linear system right hand (RH).
Definition: algebra.c:1172
int LSSolve(TLinearSystem *ls)
Solves the linear sytem.
#define CT_CUT_Y
Limit of domain of the Y dimension of 3d plots.
Definition: parameters.h:432
unsigned int ChartNumNeighbours(Tchart *c)
Number of neighbours of the chart.
Definition: chart.c:1678
unsigned int InitPossiblySingularChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:803
double * GetLSMatrixBuffer(TLinearSystem *ls)
Buffer to store the A matrix.
Definition: algebra.c:1167
void ForceChartCut(Tparameters *pr, unsigned int *tp, Tbox *ambient, unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Intersect two charts that might be non-neighbours.
Definition: chart.c:265
unsigned int InitChartInt(boolean trusted, boolean singular, boolean forceRS, Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, double *T, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:647
#define CS_WD_IN_COLLISION(f, pr, s, sPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:355
unsigned int InitChartWithTangent(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double *T, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:827
#define INF
Infinite.
Definition: defines.h:70
void EnlargeChart(double *t, Tchart *c)
Ensures that a chart includes a given point.
Definition: chart.c:1335
void PrintMatrix(FILE *f, char *label, unsigned int r, unsigned int c, double *m)
Prints a matrix.
CBLAS_INLINE void SubMatrixFromTMatrix(unsigned int nr1, unsigned int nc1, double *m1, unsigned int nri, unsigned int nci, unsigned int nr, unsigned int nc, double *m)
Defines a submatrix in a matrix.
void SPolytopeDecreaseSamplingRadius(Tscpolytope *mp)
Decreases the sampling radious.
Definition: scpolytope.c:293
#define CT_DELTA
Size of the steps in the path connecting two configurations.
Definition: parameters.h:282
double PolytopeMaxVolume(Tcpolytope *mp)
Maximum volume of the polytope.
Definition: cpolytope.c:943
Auxiliary functions to deal with sets of samples.
unsigned int ChartNeighbourID(unsigned int n, Tchart *c)
Returns the identifier of one of the neighbours of a chart.
Definition: chart.c:1690
unsigned int GetChartManifoldDim(Tchart *c)
Dimensionality of the manifold space.
Definition: chart.c:968
Definition of basic randomization functions.
void PlotChart(Tparameters *pr, FILE *fcost, TJacobian *sJ, unsigned int xID, unsigned int yID, unsigned int zID, Tplot3d *p3d, Tchart *c)
Plots a 3d projection of a local chart.
Definition: chart.c:1729
void Plot3dObject(unsigned int nv, unsigned int nf, unsigned int ne, double **v, unsigned int *nvf, unsigned int **fv, Tplot3d *p)
Adds a polytope to the current object.
Definition: plot3d.c:276
double SPolytopeVolume(Tscpolytope *mp)
Volume of the simple polytope.
Definition: scpolytope.c:305
void LoadChart(FILE *f, TAtlasBase *w, Tchart *c)
Defines a chart from the information on a file.
Definition: chart.c:1935
unsigned int GetChartDegree(Tparameters *pr, double *T, TJacobian *sJ, boolean *singular, Tchart *c)
Returns the chart degree.
Definition: chart.c:988
unsigned int SPolytopeNeighbourID(unsigned int n, Tscpolytope *mp)
Returns the identifier of one of the neighbours of a polytope.
Definition: scpolytope.c:333
void InitEmptyPolytope(unsigned int k, double r, Tcpolytope *mp)
Defines an empty chart polytope.
Definition: cpolytope.c:65
void PrintTMatrix(FILE *f, char *label, unsigned int r, unsigned int c, double *m)
Prints a transposed matrix.
boolean frontier
Definition: chart.h:85
void LoadPolytope(FILE *f, Tcpolytope *mp)
Reads the chart polytope from a file.
Definition: cpolytope.c:1252
boolean PathInChart(Tparameters *pr, double *t, unsigned int *tp, TJacobian *sJ, unsigned int nvs, boolean *systemVars, unsigned int *ms, double *pl, unsigned int *ns, double ***path, Tchart *c)
Defines the path to a point in the chart.
Definition: chart.c:1480
void DecreaseChartSamplingRadius(Tchart *c)
Decrease the sampling radious of the chart.
Definition: chart.c:1388
void CostColor(double cost, double minCost, Tcolor *c)
Definees a color in function of a cost.
Definition: color.c:90
boolean SingularChart(Tchart *c)
Identify charts defined on singularities.
Definition: chart.c:983
double ChartErrorFromParameters(double *t, double *p, unsigned int *tp, Tchart *c)
Identifies points inside the defined error.
Definition: chart.c:1232
unsigned int ClassifyPointInChart(Tparameters *pr, boolean error, TJacobian *sJ, double *p, unsigned int *tp, double *t, Tchart *c)
Identifies the position of a point w.r.t. a given chart.
Definition: chart.c:1632
boolean RandomPointInPolytope(double *t, Tcpolytope *mp)
Random point on the polytope with uniform distribution.
Definition: cpolytope.c:914
TAtlasBase * GetChartWorld(Tchart *c)
Returns the world defining the manifold.
Definition: chart.c:931
void GetPolytopeEdges(unsigned int *ne, unsigned int **vID1, unsigned int **vID2, Tcpolytope *mp)
Gets the set of edges of the polytope.
Definition: cpolytope.c:1126
unsigned int InitSingularChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:811
#define TOPOLOGY_S
One of the possible topologies.
Definition: defines.h:139
boolean PointInBoxTopology(boolean *used, boolean update, unsigned int n, double *v, double tol, unsigned int *tp, Tbox *b)
Checks if a point is included in a(sub-) box.
Definition: box.c:374
Tscpolytope * sp
Definition: chart.h:108
unsigned int DetermineChartNeighbour(double epsilon, double *t, Tchart *c)
Determines the neighbouring chart containing a given point.
Definition: chart.c:1324
#define CS_WD_ORIGINAL_IN_COLLISION(pr, o, oPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:397
void PlotChartAsBox(Tparameters *pr, unsigned int xID, unsigned int yID, unsigned int zID, Tplot3d *p3d, Tchart *c)
Plots a 3d chart as a box.
Definition: chart.c:599