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 world file does not exits -> try to read the cuik one */
639  DeleteFileName(&fn);
640  CreateFileName(NULL,name,NULL,WORLD_EXT,&fn);
641  fprintf(stderr,"Reading world from : %s\n",GetFileFullName(&fn));
642 
643  wcs->isCS=FALSE;
644  wcs->cs=NULL;
645  NEW(wcs->w,1,Tworld);
646  InitWorldFromFile(pr,&fn,wcs->w);
647  }
648  DeleteFileName(&fn);
649 }
650 
651 unsigned int InitChartInt(boolean trusted,boolean singular,boolean forceRS,Tparameters *pr,boolean simple,
652  Tbox *domain,unsigned int *tp,unsigned int m,unsigned int k,double *p,double e,
653  double eCurv,double r,double *T,TJacobian *sJ,TAtlasBase *w,Tchart *c)
654 {
655  double epsilon;
656  double error;
657  double sr;
658  unsigned int out;
659  double delta;
660  unsigned int nrJ,ncJ;
661 
662  out=0; /* no problem generating the chart. */
663 
664  epsilon=GetParameter(CT_EPSILON,pr);
665  delta=GetParameter(CT_DELTA,pr);
666 
667  sr=GetParameter(CT_SR,pr);
668  if (sr==0)
669  sr=(double)k;
670  if (sr<r+2*delta)
671  sr=r+2*delta;
672 
673  c->w=w;
674 
675  c->m=m; /*number of variables */
676  c->k=k; /*dimensionality of the manifold*/
677  c->n=c->m-c->k; /*number of non-redundant equations (equalities)*/
678 
679  if ((c->k==0)||(c->m==0)||(c->k>c->m))
680  Error("Dimension missmatch in InitChart (2)");
681 
682  GetJacobianSize(&nrJ,&ncJ,sJ);
683  if ((c->m!=ncJ)||(c->n>nrJ))
684  Error("Jacobian-system missmatch in InitChart (1)");
685 
686  /* Default initialization */
687  c->center=NULL;
688  c->T=NULL;
689  c->BJ=NULL;
690  c->singular=FALSE;
691  c->ml=0;
692  c->nl=0;
693  c->l=NULL;
694  c->degree=NO_UINT; /* We defer the computation of the degree until needed */
695  c->simple=simple;
696  c->p=NULL;
697  c->sp=NULL;
698 
699  /* Copy the center */
700  NEW(c->center,c->m,double);
701  memcpy(c->center,p,c->m*sizeof(double));
702 
703  /* Note that PointInBoxTopology can modify the center !! */
704  if (trusted)
705  c->frontier=FALSE;
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  if (c->n>0) /* no empty problem */
734  {
735  if (T!=NULL)
736  {
737  NEW(c->T,c->m*c->k,double);
738  memcpy(c->T,T,sizeof(double)*(c->m*c->k));
739  /* BJ is already NULL. Actually never used for singular charts */
740  }
741  else
742  {
743  /* Initialize c->T, c->BJ and c->singular */
744  out=ComputeJacobianKernelBasis(epsilon,sJ,c);
745 
746  if ((!singular)&&(forceRS)&&(c->singular))
747  Error("The point is not regular (and is supposed to be)");
748  }
749  }
750 
751  if (out<(singular?2:1)) /* If the chart could be actually created */
752  {
753  if ((singular)||(T!=NULL))
754  {
755  /* Even if ComputeJacobianKernelBasis determines that the point
756  is not singular, we force it to be singular (we are for sure
757  close to a singularity). */
758  if ((forceRS)||(T!=NULL))
759  c->singular=TRUE;
760 
761  c->ml=1;
762  NEW(c->l,c->ml,unsigned int);
763  }
764 
765  if (c->simple)
766  {
767  NEW(c->sp,1,Tscpolytope);
768  InitEmptySPolytope(delta,k,r,sr,c->sp);
769  }
770  else
771  {
772  NEW(c->p,1,Tcpolytope);
773  InitEmptyPolytope(k,r,c->p);
774  }
775  }
776  }
777 
778  /* If there was any error in the map definition release (possibly) used memory*/
779  if (out>(singular?1:0))
780  DeleteChart(c);
781 
782  /*
783  0 if we could actually define the chart, 1 if there the kernel is
784  too large (i.e., the given point is singular), 2 if the chart could not be defined
785  since the kernel is too small at the given point, 3 if there is an error while
786  performing QR decomposition, and 4 if the error w.r.t. the manifold is
787  too large. Most of these outputs come directly from \ref AnalyzeKernel.
788  */
789  return(out);
790 }
791 
792 unsigned int InitChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
793  unsigned int m,unsigned int k,double *p,double e,double eCurv,double r,
794  TJacobian *sJ,TAtlasBase *w,Tchart *c)
795 {
796  /* singular=FALSE forceRS=TRUE (error if not regular) */
797  return(InitChartInt(FALSE,FALSE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
798 }
799 
800 unsigned int InitPossiblySingularChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
801  unsigned int m,unsigned int k,double *p,double e, double eCurv, double r,
802  TJacobian *sJ,TAtlasBase *w,Tchart *c)
803 {
804  /* singular=TRUE forceRS=FALSE (no error if singular and do not force to mark it as singular) */
805  return(InitChartInt(FALSE,TRUE,FALSE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
806 }
807 
808 unsigned int InitSingularChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
809  unsigned int m,unsigned int k,double *p,double e, double eCurv,double r,
810  TJacobian *sJ,TAtlasBase *w,Tchart *c)
811 {
812  /* singular=TRUE forceRS=TRUE (mark as singular even if not detected as such) */
813  return(InitChartInt(FALSE,TRUE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
814 }
815 
816 unsigned int InitTrustedChart(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
817  unsigned int m,unsigned int k,double *p,double e, double eCurv,double r,
818  TJacobian *sJ,TAtlasBase *w,Tchart *c)
819 {
820  /* singular=TRUE forceRS=TRUE (mark as singular even if not detected as such) */
821  return(InitChartInt(TRUE,TRUE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,NULL,sJ,w,c));
822 }
823 
824 unsigned int InitChartWithTangent(Tparameters *pr,boolean simple,Tbox *domain,unsigned int *tp,
825  unsigned int m,unsigned int k,double *p,double *T,
826  double e, double eCurv, double r,
827  TJacobian *sJ,TAtlasBase *w,Tchart *c)
828 {
829  /* singular=TRUE forceRS=TRUE (but forceRS plays no role since we give T) */
830  return(InitChartInt(FALSE,TRUE,TRUE,pr,simple,domain,tp,m,k,p,e,eCurv,r,T,sJ,w,c));
831 }
832 
833 void CopyChart(Tchart *c_dst,Tchart *c_src)
834 {
835  /* Copy chart */
836  c_dst->w=c_src->w;
837 
838  c_dst->m=c_src->m;
839  c_dst->k=c_src->k;
840  c_dst->n=c_src->n;
841  c_dst->nrJ=c_src->nrJ;
842 
843  c_dst->error=c_src->error;
844  c_dst->eCurv= c_src->eCurv;
845  c_dst->r=c_src->r;
846  c_dst->degree=c_src->degree;
847  c_dst->frontier=c_src->frontier;
848  c_dst->singular=c_src->singular;
849 
850  NEW(c_dst->center,c_dst->m,double);
851  memcpy(c_dst->center,c_src->center,c_dst->m*sizeof(double));
852 
853  if ((c_src->n==0)||(c_src->T==NULL))
854  c_dst->T=NULL;
855  else
856  {
857  NEW(c_dst->T,c_dst->m*c_dst->k,double);
858  memcpy(c_dst->T,c_src->T,sizeof(double)*(c_dst->m*c_dst->k));
859  }
860 
861  /* maps defined with given tangent space don't have Jacobian basis */
862  if ((c_src->nrJ==0)||(c_src->BJ==NULL)) /* c_src->singular==TRUE */
863  c_dst->BJ=NULL;
864  else
865  {
866  NEW(c_dst->BJ,c_dst->nrJ,boolean);
867  memcpy(c_dst->BJ,c_src->BJ,c_dst->nrJ*sizeof(boolean));
868  }
869 
870  c_dst->ml=c_src->ml;
871  if (c_dst->ml>0)
872  {
873  c_dst->nl=c_src->nl;
874  NEW(c_dst->l,c_dst->ml,unsigned int);
875  memcpy(c_dst->l,c_src->l,c_dst->nl*sizeof(unsigned int));
876  }
877  else
878  {
879  c_dst->nl=0;
880  c_dst->l=NULL;
881  }
882 
883  /* Copy Polytope */
884  c_dst->simple=c_src->simple;
885 
886  if (c_src->sp!=NULL)
887  {
888  NEW(c_dst->sp,1,Tscpolytope);
889  CopySPolytope(c_dst->sp,c_src->sp);
890  c_dst->p=NULL;
891  }
892 
893  if (c_src->p!=NULL)
894  {
895  NEW(c_dst->p,1,Tcpolytope);
896  CopyPolytope(c_dst->p,c_src->p);
897  c_dst->sp=NULL;
898  }
899 }
900 
902 {
903  double d;
904  double *aData;
905 
906  if (c1->w!=c2->w)
907  Error("Comparing maps defined on diferent manifolds");
908 
909  NEW(aData,c1->k*c1->k,double);
910 
911  TMatrixMatrixProduct(c1->m,c1->k,c1->T,c2->k,c2->T,aData);
912 
913  d=fabs(MatrixDeterminant(c1->k,aData));
914 
915  free(aData);
916 
917  return(fabs(d-1)<=c1->eCurv);
918 }
919 
921 {
922  if (c1->w!=c2->w)
923  Error("Comparing maps defined on diferent manifolds");
924 
925  return(MinCosinusBetweenSubSpaces(c1->m,c1->k,c1->T,c2->T));
926 }
927 
929 {
930  return(c->w);
931 }
932 
934 {
935  return(c->center);
936 }
937 
939 {
940  return(c->r);
941 }
942 
944 {
945  if (!c->simple)
946  Error("GetChartSamplingRadius is only defined for simple charts");
947  return(SPolytopeGetSamplingRadius(c->sp));
948 }
949 
951 {
952  return(c->error);
953 }
954 
956 {
957  return(c->eCurv);
958 }
959 
960 unsigned int GetChartAmbientDim(Tchart *c)
961 {
962  return(c->m);
963 }
964 
965 unsigned int GetChartManifoldDim(Tchart *c)
966 {
967  return(c->k);
968 }
969 
971 {
972  return(c->T);
973 }
974 
976 {
977  return(c->BJ);
978 }
979 
981 {
982  return(c->singular);
983 }
984 
985 unsigned int GetChartDegree(Tparameters *pr,double *T,TJacobian *sJ,
986  boolean *singular,Tchart *c)
987 {
988  double *A;
989  int sg;
990  unsigned int d;
991 
992  d=0; /* default output*/
993 
994  if (c->singular)
995  *singular=TRUE;
996  else
997  {
998  if (c->BJ==NULL)
999  Error("A non-singular chart without Jacobian basis?");
1000 
1001  *singular=FALSE;
1002 
1003  if ((T==c->T)&&(c->degree!=NO_UINT))
1004  d=c->degree;
1005  else
1006  {
1007  /* Evaluate the Jacobian */
1008  NEW(A,c->m*c->m,double);
1009 
1010  /* We only take the c->n independent rows of the Jacobian */
1011  EvaluateJacobianSubSetInVector(c->center,c->BJ,c->m,c->m,A,sJ);
1012 
1013  /* The lower part of A is T' */
1014  SubMatrixFromTMatrix(c->m,c->k,T,c->n,0,c->m,c->m,A);
1015 
1016  #if (_DEBUG>4)
1017  PrintVector(stdout,NULL,c->m,c->center);
1018  PrintMatrix(stdout,NULL,c->m,c->m,A);
1019  #endif
1020 
1022 
1023  if (sg>0) d=1;
1024  else
1025  {
1026  if (sg<0) d=0;
1027  else *singular=TRUE;
1028  }
1029 
1030  free(A);
1031  }
1032  }
1033  return(d);
1034 }
1035 
1036 double Manifold2Chart(double *p,unsigned int *tp,double *t,Tchart *c)
1037 {
1038  if (c->n==0) /* k==m */
1039  {
1040  if (tp!=NULL)
1041  DifferenceVectorTopology(c->m,tp,p,c->center,t);
1042  else
1043  DifferenceVector(c->m,p,c->center,t);
1044  return(Norm(c->m,t));
1045  }
1046  else
1047  {
1048  double *p1;
1049 
1050  /* Project a point to the tangent space */
1051  /* t=T'*(p-center)*/
1052  NEW(p1,c->m,double);
1053 
1054  DifferenceVector(c->m,p,c->center,p1);
1055  if (tp!=NULL)
1056  ArrayPi2Pi(c->m,tp,p1);
1057  TMatrixVectorProduct(c->m,c->k,c->T,p1,t);
1058 
1059  free(p1);
1060  return(Norm(c->k,t));
1061  }
1062 }
1063 
1064 
1065 
1067  double *t,unsigned int *tp,double *pInit,
1068  double *p,Tchart *c)
1069 {
1070  if (c->n==0) /* k==m */
1071  {
1072  SumVector(c->m,c->center,t,p);
1073  if (tp!=NULL)
1074  ArrayPi2Pi(c->m,tp,p);
1075  return(0.0);
1076  }
1077  else
1078  {
1079  double d;
1080  double epsilon;
1081  unsigned int i,it,maxIterations,nr,nrJ;
1082  boolean converged;
1083 
1084  TLinearSystem ls;
1085  double *aData;
1086  double *bData;
1087  double *xData;
1088 
1089  double error;
1090  double *p0;
1091  int err;
1092  double *dif;
1093 
1094  epsilon=GetParameter(CT_EPSILON,pr);
1095  maxIterations=(unsigned int)GetParameter(CT_MAX_NEWTON_ITERATIONS,pr);
1096 
1097  if (maxIterations==0)
1098  Error("MAX_NEWTON_ITERATIONS must be larger than 0 to use Map2Manifold");
1099 
1100  /* If we already identified a basis of the Jacobian (most of the cases), we
1101  can use these rows only. This produces a smaller system without changing
1102  the solution. If actually produces a squared sytem which are solved faster
1103  (non-squared systems are solved via less-squares which is slower). */
1104  if (c->BJ==NULL)
1105  nrJ=c->nrJ;
1106  else
1107  nrJ=c->n; /* squared system */
1108  nr=nrJ+c->k;
1109 
1110  /* Initializes the structure to solve linear systems */
1111  InitLS(nr,c->m,&ls);
1112 
1113  /* direct acces to the LS structures */
1114  aData=GetLSMatrixBuffer(&ls);
1115  bData=GetLSRHBuffer(&ls);
1116  xData=GetLSSolutionBuffer(&ls);
1117 
1118  /* Point on the tangent space corresponding to the given paremeters 't' */
1119  NEW(p0,c->m,double);
1120  Local2Global(t,tp,p0,c);
1121 
1122  /* If the user provides an initial estimation for the output use it
1123  (otherwise we will depart from the tangent space estimation. */
1124  if (pInit!=NULL)
1125  {
1126  /* pInit can be pi2pi-ed and this can cause a large error in
1127  the intial estimation when there is not such error.
1128  This is why we have to use DifferenceVectorTopology inside
1129  the loop. */
1130  if (p!=pInit)
1131  memcpy(p,pInit,sizeof(double)*c->m);
1132  }
1133  else
1134  memcpy(p,p0,sizeof(double)*c->m);
1135 
1136  /* Space for the difference between current point (p) and p0
1137  taking into account topology */
1138  NEW(dif,c->m,double);
1139 
1140  /* Iterate from this point to a point on the manifold */
1141  it=0;
1142  converged=FALSE;
1143  err=0;
1144  while((!converged)&&(it<maxIterations))
1145  {
1146  /* Define the residual (right-had side of the system) */
1147  if (c->BJ==NULL)
1148  { CS_WD_EVALUATE_SIMP_EQUATIONS(pr,p,bData,c->w); }
1149  else
1150  { CS_WD_EVALUATE_SUBSET_SIMP_EQUATIONS(pr,c->BJ,p,bData,c->w); }
1151 
1152  /* Complete the the right-hand side of the system of equations */
1153  DifferenceVectorTopology(c->m,tp,p,p0,dif);
1154  TMatrixVectorProduct(c->m,c->k,c->T,dif,&(bData[nrJ]));
1155 
1156  error=Norm(nr,bData);
1157 
1158  if (error<epsilon)
1159  //if ((it>0)&&(error<epsilon))
1160  converged=TRUE;
1161  else
1162  {
1163  /* To avoid overflows we assume that convergence
1164  is impossible with too large errors */
1165  if (error>1e10)
1166  it=maxIterations;
1167  else
1168  {
1169  /* Fill in the part of the 'A' corresponding to the Jacobian */
1170  if (c->BJ==NULL)
1171  EvaluateJacobianInVector(p,nr,c->m,aData,sJ);
1172  else
1173  EvaluateJacobianSubSetInVector(p,c->BJ,nr,c->m,aData,sJ);
1174 
1175  /* Now the part of the 'A' matrix corresponding to the tangent
1176  space (transposed) */
1177  SubMatrixFromTMatrix(c->m,c->k,c->T,nrJ,0,nr,c->m,aData);
1178 
1179  /* Once A and b are defined, solve the system */
1180  err=LSSolve(&ls);
1181 
1182  /* Update the estimate */
1183  if (err)
1184  it=maxIterations;
1185  else
1186  {
1187  for(i=0;i<c->m;i++)
1188  {
1189  p[i]-=xData[i];
1190  if ((tp!=NULL)&&(tp[i]==TOPOLOGY_S))
1191  PI2PI(p[i]);
1192  }
1193  it++;
1194  }
1195  }
1196  }
1197  }
1198 
1199  free(dif);
1200  DeleteLS(&ls);
1201 
1202  if (it<maxIterations)
1203  d=DistanceTopology(c->m,tp,p,p0);
1204  else
1205  d=INF;
1206  free(p0);
1207 
1208  return(d);
1209  }
1210 }
1211 
1212 void Local2Global(double *t,unsigned int *tp,double *p,Tchart *c)
1213 {
1214  if (c->n==0) /* k==m */
1215  {
1216  /*p=center+t*/
1217  SumVector(c->m,c->center,t,p);
1218  }
1219  else
1220  {
1221  /*p=center+T*t*/
1222  MatrixVectorProduct(c->m,c->k,c->T,t,p);
1223  AccumulateVector(c->m,c->center,p);
1224  }
1225  if (tp!=NULL)
1226  ArrayPi2Pi(c->m,tp,p);
1227 }
1228 
1229 double ChartErrorFromParameters(double *t,double *p,unsigned int *tp,
1230  Tchart *c)
1231 {
1232  if (c->n==0)
1233  return(0.0);
1234  else
1235  {
1236  double *p2,e;
1237 
1238  NEW(p2,c->m,double);
1239  Local2Global(t,tp,p2,c);
1240  e=DistanceTopology(c->m,tp,p,p2);
1241  free(p2);
1242 
1243  return(e);
1244  }
1245 }
1246 
1247 double Error2Chart(double *p,unsigned int *tp,Tchart *c)
1248 {
1249  if (c->n==0)
1250  return(0.0);
1251  else
1252  {
1253  double *t,e;
1254 
1255  NEW(t,c->k,double);
1256  Manifold2Chart(p,tp,t,c);
1257  e=ChartErrorFromParameters(t,p,tp,c);
1258  free(t);
1259 
1260  return(e);
1261  }
1262 }
1263 
1264 inline boolean CloseCharts(Tparameters *pr,unsigned int *tp,
1265  Tchart *c1,Tchart *c2)
1266 {
1267  return(IntersectChartsInt(pr,FALSE,tp,NULL,NO_UINT,c1,NO_UINT,c2));
1268 }
1269 
1270 boolean IntersectCharts(Tparameters *pr,unsigned int *tp,Tbox *ambient,
1271  unsigned int id1,Tchart *c1,
1272  unsigned int id2,Tchart *c2)
1273 {
1274  return(IntersectChartsInt(pr,TRUE,tp,ambient,id1,c1,id2,c2));
1275 }
1276 
1277 inline boolean CollisionChart(Tchart *c)
1278 {
1279  return(c->collision);
1280 }
1281 
1282 inline boolean FrontierChart(Tchart *c)
1283 {
1284  return(c->frontier);
1285 }
1286 
1287 inline void ChartIsFrontier(Tchart *c)
1288 {
1289  c->frontier=TRUE;
1290 }
1291 
1292 inline boolean ExpandibleChart(Tchart *c)
1293 {
1294  if (c->simple)
1295  Error("ExpandibleChart is undefined for simple charts");
1296 
1297  return((!c->frontier)&&(ExpandiblePolytope(c->p)));
1298 }
1299 
1300 inline boolean OpenChart(Tchart *c)
1301 {
1302  return((c->simple)||(ExpandiblePolytope(c->p)));
1303 }
1304 
1305 void WrongCorner(unsigned int nv,Tchart *c)
1306 {
1307  if (c->simple)
1308  Error("WrongCorner is undefined for simple charts");
1309 
1310  WrongPolytopeCorner(nv,c->p);
1311 }
1312 
1313 boolean InsideChartPolytope(double *t,Tchart *c)
1314 {
1315  if (c->simple)
1316  return(InsideSPolytope(t,c->sp));
1317  else
1318  return(InsidePolytope(t,c->p));
1319 }
1320 
1321 unsigned int DetermineChartNeighbour(double epsilon,double *t,Tchart *c)
1322 {
1323  if (c->simple)
1324  return(DetermineSPolytopeNeighbour(epsilon,t,c->sp));
1325  else
1326  {
1327  Error("DetermineChartNeighbour is only defined for simple charts");
1328  return(NO_UINT);
1329  }
1330 }
1331 
1332 void EnlargeChart(double *t,Tchart *c)
1333 {
1334  if (c->simple)
1335  EnlargeSPolytope(t,c->sp);
1336  else
1337  Error("EnlargeChart is only defined for simple charts");
1338 }
1339 
1340 boolean BoundaryPointFromExternalCorner(boolean rand,unsigned int *nv,double *t,Tchart *c)
1341 {
1342  if (c->simple)
1343  Error("BoundaryPointFromExternalCorner is undefined for simple charts");
1344 
1345  return(PolytopeBoundaryPointFromExternalCorner(c->r,rand,nv,t,c->p));
1346 }
1347 
1348 void BoundaryPointsFromExternalCorners(unsigned int *n,unsigned int **nv,double ***t,Tchart *c)
1349 {
1350  if (c->simple)
1351  Error("BoundaryPointsFromExternalCorners is undefined for simple charts");
1352 
1354 }
1355 
1356 boolean RandomPointOnBoundary(double *t,Tchart *c)
1357 {
1358  if (c->simple)
1359  return(SPolytopeRandomPointOnBoundary(c->r,t,c->sp));
1360  else
1361  return(PolytopeRandomPointOnBoundary(c->r,t,c->p));
1362 }
1363 
1364 boolean RandomPointInChart(Tparameters *pr,double scale,unsigned int *tp,double *t,double *p,Tchart *c)
1365 {
1366  boolean canSample;
1367 
1368  if (c->simple)
1369  canSample=RandomPointInSPolytope(scale,t,c->sp);
1370  else
1371  canSample=RandomPointInPolytope(t,c->p);
1372 
1373  if (canSample)
1374  Local2Global(t,tp,p,c);
1375 
1376  return(canSample);
1377 }
1378 
1380 {
1381  if (c->simple)
1383 }
1384 
1386 {
1387  if (c->simple)
1389 }
1390 
1392 {
1393  double v;
1394 
1395  /* use the cached volume stored in the charts. This
1396  significantly speeds up the query if we ask for the
1397  volume of a chart many times */
1398  if (c->simple)
1399  v=SPolytopeVolume(c->sp);
1400  else
1401  v=PolytopeVolume(c->p);
1402 
1403  return(v);
1404 }
1405 
1406 double ChartVolume(Tparameters *pr,boolean collisionFree,
1407  unsigned int *tp,TJacobian *sJ,Tchart *c)
1408 {
1409  double v;
1410 
1411  if (!collisionFree)
1412  v=ChartMaxVolume(c);
1413  else
1414  {
1415  double *t,*s;
1416  unsigned int i,n,in;
1417  boolean valid,inCollision;
1418 
1419  /* If collisions must be taken into account, we have to replicate
1420  the rejection sampling implemented in Polytope and SPolytope
1421  but including rejection due to obstacles */
1422 
1423  NEW(t,c->k,double);
1424  NEW(s,c->m,double);
1425 
1426  n=(unsigned int)floor(pow(10,c->k));
1427  if (n>10000) n=10000;
1428  in=0;
1429  for(i=0;i<n;i++)
1430  {
1431  if (c->simple)
1432  valid=RandomPointInSPolytope(1.0,t,c->sp);
1433  else
1434  valid=RandomPointInPolytope(t,c->p);
1435  if (valid)
1436  {
1437  if (Chart2Manifold(pr,sJ,t,tp,NULL,s,c)<INF)
1438  {
1439  CS_WD_IN_COLLISION(inCollision,pr,s,NULL,c->w);
1440  if (!inCollision)
1441  in++;
1442  }
1443  }
1444  }
1445  free(t);
1446  free(s);
1447 
1448  if (c->simple)
1449  v=SPolytopeMaxVolume(c->sp);
1450  else
1451  v=PolytopeMaxVolume(c->p);
1452 
1453  v*=((double)in/(double)n);
1454  }
1455  return(v);
1456 }
1457 
1458 boolean FocusedPointOnBoundary(double *p,unsigned int *tp,
1459  double *t,Tchart *c)
1460 {
1461  if (c->simple)
1462  Error("FocusedPointOnBoundary is undefined for simple charts");
1463 
1464  if (ExpandibleChart(c))
1465  {
1466  double nt;
1467 
1468  nt=Manifold2Chart(p,tp,t,c);
1469  ScaleVector(c->r/nt,c->k,t);
1470 
1471  return(InsidePolytope(t,c->p));
1472  }
1473  else
1474  return(FALSE);
1475 }
1476 
1477 boolean PathInChart(Tparameters *pr,double *t,unsigned int *tp,TJacobian *sJ,
1478  unsigned int nvs,boolean *systemVars,
1479  unsigned int *ms,
1480  double *pl,unsigned int *ns,double ***path,
1481  Tchart *c)
1482 {
1483  double *nt,*p,*pPrev;
1484  double delta,n;
1485  boolean projectionOk,collision,reached,close;
1486  unsigned int step,nv;
1487  double *o,*oPrev;
1488 
1489  delta=GetParameter(CT_DELTA,pr);
1490 
1491  NEW(p,c->m,double);
1492  NEW(pPrev,c->m,double);
1493  NEW(nt,c->k,double);
1494 
1495  /* We move from the center of the chart toward 't' */
1496  step=0; /* start at 0 to add the center */
1497  projectionOk=TRUE;
1498  collision=FALSE;
1499  n=Norm(c->k,t);
1500  reached=(n<delta);
1501  close=FALSE;
1502 
1503  /* depart from the center */
1504  memcpy(pPrev,c->center,c->m*sizeof(double));
1505  nv=CS_WD_REGENERATE_ORIGINAL_POINT(pr,pPrev,&oPrev,c->w);
1506 
1507  while((projectionOk)&&(!reached))
1508  {
1509  memcpy(nt,t,c->k*sizeof(double));
1510 
1511  /* If in the last step we where close to 't' just use
1512  it as a new set of parameters. Otherwise approach it */
1513  if (close)
1514  reached=TRUE;
1515  else
1516  ScaleVector(((double)step)*delta/n,c->k,nt);
1517 
1518  projectionOk=(Chart2Manifold(pr,sJ,nt,tp,pPrev,p,c)<=c->error);
1519 
1520  if (projectionOk)
1521  {
1522  (*pl)+=DistanceTopology(c->m,tp,pPrev,p);
1523 
1524  nv=CS_WD_REGENERATE_ORIGINAL_POINT(pr,p,&o,c->w);
1525  AddSample2Samples(nv,o,nvs,systemVars,ms,ns,path);
1526 
1527  collision=((collision)||(CS_WD_ORIGINAL_IN_COLLISION(pr,o,oPrev,c->w)));
1528 
1529  memcpy(oPrev,o,nv*sizeof(double));
1530  free(o);
1531 
1532  memcpy(pPrev,p,c->m*sizeof(double));
1533  close=(Distance(c->k,nt,t)<delta);
1534  }
1535 
1536  step++;
1537  }
1538  free(p);
1539  free(pPrev);
1540  free(nt);
1541  free(oPrev);
1542 
1543  return(!collision);
1544 }
1545 
1546 double DistanceOnChart(Tparameters *pr,double *t,unsigned int *tp,TJacobian *sJ,
1547  Tchart *c)
1548 {
1549  double *nt,*p,*pPrev;
1550  double delta,n,d;
1551  boolean projectionOk,inCollision,reached;
1552  unsigned int step;
1553 
1554  delta=GetParameter(CT_DELTA,pr);
1555 
1556  NEW(p,c->m,double);
1557  NEW(pPrev,c->m,double);
1558  NEW(nt,c->k,double);
1559 
1560  /* We move from the center of the chart toward 't' */
1561  step=1;
1562  projectionOk=TRUE;
1563  inCollision=FALSE;
1564  n=Norm(c->k,t);
1565  reached=(n<delta);
1566  d=0.0;
1567  memcpy(pPrev,c->center,c->m*sizeof(double));
1568 
1569  while((projectionOk)&&(!inCollision)&&(!reached)&&(d<INF))
1570  {
1571  memcpy(nt,t,c->k*sizeof(double));
1572  ScaleVector(((double)step)*delta/n,c->k,nt);
1573 
1574  projectionOk=(Chart2Manifold(pr,sJ,nt,tp,pPrev,p,c)<=c->error);
1575 
1576  if (projectionOk)
1577  {
1578  CS_WD_IN_COLLISION(inCollision,pr,p,pPrev,c->w);
1579 
1580  if (!inCollision)
1581  {
1582  d+=DistanceTopology(c->m,tp,pPrev,p);
1583  memcpy(pPrev,p,c->m*sizeof(double));
1584  reached=(Distance(c->k,nt,t)<delta);
1585  }
1586  else
1587  d=INF;
1588  }
1589  else
1590  d=INF;
1591 
1592  step++;
1593  }
1594 
1595  free(p);
1596  free(pPrev);
1597  free(nt);
1598 
1599  return(d);
1600 }
1601 
1603  double *p,unsigned int *tp,
1604  double *t,Tchart *c)
1605 {
1606  boolean inside;
1607 
1608  inside=FALSE;
1609 
1610  if ((Manifold2Chart(p,tp,t,c)<c->r)&&
1611  (InsideChartPolytope(t,c)))
1612  {
1613  double eps;
1614  double *p1;
1615 
1616  eps=GetParameter(CT_EPSILON,pr);
1617 
1618  NEW(p1,c->m,double);
1619 
1620  inside=((Chart2Manifold(pr,sJ,t,tp,NULL,p1,c)<c->error)&&
1621  (DistanceTopology(c->m,tp,p1,p)<eps));
1622 
1623  free(p1);
1624  }
1625 
1626  return(inside);
1627 }
1628 
1629 unsigned int ClassifyPointInChart(Tparameters *pr,boolean error,TJacobian *sJ,
1630  double *p,unsigned int *tp,
1631  double *t,Tchart *c)
1632 {
1633  double eps;
1634  double *p1;
1635  unsigned int cs;
1636 
1637  eps=GetParameter(CT_EPSILON,pr);
1638  NEW(p1,c->m,double);
1639 
1640  if (Manifold2Chart(p,tp,t,c)>c->r)
1641  {
1642  /* out of the ball */
1643  if (InsideChartPolytope(t,c)) /* but still inside the polytope */
1644  cs=1; /* In the chart scope but out of the ball */
1645  else
1646  cs=4; /* Completely out of the scope of the chart */
1647  }
1648  else
1649  {
1650  /* In the ball */
1651  if (InsideChartPolytope(t,c))
1652  {
1653  if ((error)&&((Chart2Manifold(pr,sJ,t,tp,NULL,p1,c)>c->error)||
1654  (DistanceTopology(c->m,tp,p1,p)>eps)))
1655  cs=3; /* Out of the scope due to lack of convergence or large error */
1656  else
1657  cs=0; /* In inside the scope of this chart */
1658  }
1659  else
1660  cs=2; /* Was inside the scope of this chart but is in a neighbouring chart now */
1661  }
1662 
1663  free(p1);
1664 
1665  return(cs);
1666 }
1667 
1668 
1669 void LinkCharts(unsigned int id1,Tchart *c1,unsigned int id2,Tchart *c2)
1670 {
1671  LinkChart(id1,c2);
1672  LinkChart(id2,c1);
1673 }
1674 
1675 unsigned int ChartNumNeighbours(Tchart *c)
1676 {
1677  unsigned int n;
1678 
1679  if (c->simple)
1680  n=SPolytopeNumNeighbours(c->sp);
1681  else
1682  n=PolytopeNumNeighbours(c->p);
1683 
1684  return(c->nl+n);
1685 }
1686 
1687 unsigned int ChartNeighbourID(unsigned int n,Tchart *c)
1688 {
1689  unsigned int id;
1690 
1691  if (n<c->nl)
1692  id=c->l[n];
1693  else
1694  {
1695  if (c->simple)
1696  id=SPolytopeNeighbourID(n-c->nl,c->sp);
1697  else
1698  id=PolytopeNeighbourID(n-c->nl,c->p);
1699  }
1700 
1701  return(id);
1702 }
1703 
1705  unsigned int *nn,unsigned int **cID1,unsigned int **cID2,Tchart *c)
1706 {
1707  Tcpolytope *p;
1708 
1709  if (c->simple)
1710  {
1711  NEW(p,1,Tcpolytope);
1712  SPolytope2Polytope(pr,c->sp,p);
1713  }
1714  else
1715  p=c->p;
1716 
1717  GetPolytopeNeighboursFromVertices(nn,cID1,cID2,p);
1718 
1719  if (c->simple)
1720  {
1721  DeletePolytope(p);
1722  free(p);
1723  }
1724 }
1725 
1726 void PlotChart(Tparameters *pr,FILE *fcost,TJacobian *sJ,
1727  unsigned int xID,unsigned int yID,unsigned int zID,
1728  Tplot3d *p3d,Tchart *c)
1729 {
1730  if (c->k>3)
1731  Error("PlotChart only works for 2/3d manifolds");
1732 
1733  if ((PLOT_AS_POLYGONS)&&((c->k==2)||(c->k==3)))
1734  {
1735  if (c->k==2)
1736  PlotChartAsPolygon(pr,fcost,sJ,xID,yID,zID,p3d,c);
1737  else
1738  PlotChartAsBox(pr,xID,yID,zID,p3d,c);
1739  }
1740  else
1741  {
1742  unsigned int nv;
1743  double **v;
1744  Tcpolytope *p;
1745 
1746  if (c->simple)
1747  {
1748  NEW(p,1,Tcpolytope);
1749  SPolytope2Polytope(pr,c->sp,p);
1750  }
1751  else
1752  p=c->p;
1753 
1754  GetPolytopeVertices(&nv,&v,p);
1755 
1756  if (nv>0)
1757  {
1758  unsigned int i,k,n1,n2;
1759  unsigned int ne;
1760  unsigned int *v1;
1761  unsigned int *v2;
1762  double *x,*y,*z;
1763  double *g,*o;
1764  double ox,oy,oz;
1765  double cx,cy,cz;
1766 
1767  /* Collect the edges of the polytope bounding the chart (local coordinates) */
1768  GetPolytopeEdges(&ne,&v1,&v2,p);
1769 
1770  /* Transform the polytope edges from local to gobal */
1771 
1772  NEW(g,c->m,double); /* space for the points in global */
1773 
1774  NEW(x,2*ne,double); /* space for the vertices in global */
1775  NEW(y,2*ne,double);
1776  NEW(z,2*ne,double);
1777 
1778  for(i=0,k=0;i<ne;i++,k+=2)
1779  {
1780  /*Extremes of the edges*/
1781  n1=v1[i];
1782  n2=v2[i];
1783 
1784  if ((!PLOT_ON_MANIFOLD)||
1785  (Chart2Manifold(pr,sJ,v[n1],NULL,NULL,g,c)==INF))
1786  Local2Global(v[n1],NULL,g,c);
1787  CS_WD_REGENERATE_ORIGINAL_POINT(pr,g,&o,c->w);
1788  x[k]=o[xID];
1789  y[k]=o[yID];
1790  z[k]=o[zID];
1791  free(o);
1792 
1793  if ((!PLOT_ON_MANIFOLD)||
1794  (Chart2Manifold(pr,sJ,v[n2],NULL,NULL,g,c)==INF))
1795  Local2Global(v[n2],NULL,g,c);
1796  CS_WD_REGENERATE_ORIGINAL_POINT(pr,g,&o,c->w);
1797  x[k+1]=o[xID];
1798  y[k+1]=o[yID];
1799  z[k+1]=o[zID];
1800  free(o);
1801  }
1802 
1803  /* If any of the vertices is out of the box in global coordiantes
1804  offset the whole polygon */
1805  cx=GetParameter(CT_CUT_X,pr);
1806  cy=GetParameter(CT_CUT_Y,pr);
1807  cz=GetParameter(CT_CUT_Z,pr);
1808 
1809  ox=0;
1810  oy=0;
1811  oz=0;
1812 
1813  for(k=0;k<2*ne;k++)
1814  {
1815  if ((cx<0)&&(x[k]<cx))
1816  ox=+M_2PI;
1817  if ((cx>0)&&(x[k]>cx))
1818  ox=-M_2PI;
1819  if ((cy<0)&&(y[k]<cy))
1820  oy=+M_2PI;
1821  if ((cy>0)&&(y[k]>cy))
1822  oy=-M_2PI;
1823  if ((cz<0)&&(z[k]<cz))
1824  oz=+M_2PI;
1825  if ((cz>0)&&(z[k]>cz))
1826  oz=-M_2PI;
1827  }
1828 
1829  /* Apply the offset if any */
1830  for(k=0;k<2*ne;k++)
1831  {
1832  x[k]+=ox;
1833  y[k]+=oy;
1834  z[k]+=oz;
1835  }
1836 
1837  /* Plot the edges defining the polygon (possibly with offset) */
1838  for(k=0;k<2*ne;k+=2)
1839  PlotVect3d(2,&(x[k]),&(y[k]),&(z[k]),p3d);
1840 
1841  /* Release allocated space */
1842  free(g);
1843 
1844  free(x);
1845  free(y);
1846  free(z);
1847 
1848  for(i=0;i<nv;i++)
1849  free(v[i]);
1850  free(v);
1851  free(v1);
1852  free(v2);
1853  }
1854  if (c->simple)
1855  {
1856  DeletePolytope(p);
1857  free(p);
1858  }
1859  }
1860 }
1861 
1862 unsigned int ChartMemSize(Tchart *c)
1863 {
1864  unsigned int b;
1865 
1866  b=sizeof(double)*c->m; /* center */
1867  b+=sizeof(double)*(c->m*c->k); /* T */
1868 
1869  if (c->simple)
1870  b+=SPolytopeMemSize(c->sp);
1871  else
1872  b+=PolytopeMemSize(c->p);
1873 
1874  return(b);
1875 }
1876 
1877 void SaveChart(FILE *f,Tchart *c)
1878 {
1879  unsigned int i;
1880 
1881  /* Save map */
1882  fprintf(f,"%u\n",c->m);
1883  fprintf(f,"%u\n",c->k);
1884  fprintf(f,"%u\n",c->n);
1885  fprintf(f,"%u\n",c->nrJ);
1886 
1887  fprintf(f,"%f\n",c->error);
1888  fprintf(f,"%f\n",c->eCurv);
1889  fprintf(f,"%f\n0\n",c->r); /* the 0 is for rSample (back-compatibility) */
1890  fprintf(f,"%u\n",c->degree);
1891  fprintf(f,"%u\n",c->frontier);
1892  fprintf(f,"%u\n",c->singular);
1893 
1894  for(i=0;i<c->m;i++)
1895  fprintf(f,"%.16f ",c->center[i]);
1896  fprintf(f,"\n");
1897 
1898  if (c->n>0)
1899  {
1900  for(i=0;i<c->m*c->k;i++)
1901  fprintf(f,"%.16f ",c->T[i]);
1902  fprintf(f,"\n");
1903 
1904  if (c->BJ==NULL)
1905  fprintf(f,"0\n");
1906  else
1907  {
1908  fprintf(f,"1\n");
1909  for(i=0;i<c->nrJ;i++)
1910  fprintf(f,"%u ",c->BJ[i]);
1911  fprintf(f,"\n");
1912  }
1913  }
1914 
1915  fprintf(f,"%u\n",c->ml);
1916  if (c->ml>0)
1917  {
1918  fprintf(f,"%u\n",c->nl);
1919  for(i=0;i<c->nl;i++)
1920  fprintf(f,"%u ",c->l[i]);
1921  fprintf(f,"\n");
1922  }
1923 
1924  /* Save polytope */
1925  fprintf(f,"%u\n",c->simple);
1926  if (c->simple)
1927  SaveSPolytope(f,c->sp);
1928  else
1929  SavePolytope(f,c->p);
1930 }
1931 
1932 void LoadChart(FILE *f,TAtlasBase *w,Tchart *c)
1933 {
1934  unsigned int i,flag;
1935  double rSample;
1936 
1937  /* Load map */
1938  c->w=w;
1939 
1940  fscanf(f,"%u",&(c->m));
1941  fscanf(f,"%u",&(c->k));
1942  fscanf(f,"%u",&(c->n));
1943  fscanf(f,"%u",&(c->nrJ));
1944 
1945  fscanf(f,"%lf",&(c->error));
1946  fscanf(f,"%lf",&(c->eCurv));
1947  fscanf(f,"%lf",&(c->r));
1948  fscanf(f,"%lf",&rSample); /*for back-compatibility*/
1949  fscanf(f,"%u",&(c->degree));
1950  fscanf(f,"%u",&(c->frontier));
1951  fscanf(f,"%u",&(c->singular));
1952 
1953  NEW(c->center,c->m,double);
1954  for(i=0;i<c->m;i++)
1955  fscanf(f,"%lf",&(c->center[i]));
1956 
1957  if (c->n==0)
1958  {
1959  c->T=NULL;
1960  c->BJ=NULL;
1961  }
1962  else
1963  {
1964  NEW(c->T,c->m*c->k,double);
1965  for(i=0;i<c->m*c->k;i++)
1966  fscanf(f,"%lf",&(c->T[i]));
1967 
1968  /* Do not load the Jacobian Basis. We keep the
1969  read code for back-compatibility. */
1970  fscanf(f,"%u",&flag);
1971  if (flag)
1972  {
1973  NEW(c->BJ,c->nrJ,boolean);
1974  for(i=0;i<c->nrJ;i++)
1975  fscanf(f,"%u",&(c->BJ[i]));
1976  }
1977  else
1978  c->BJ=NULL;
1979  }
1980 
1981  fscanf(f,"%u",&(c->ml));
1982  if (c->ml>0)
1983  {
1984  NEW(c->l,c->ml,unsigned int);
1985  fscanf(f,"%u",&(c->nl));
1986  for(i=0;i<c->nl;i++)
1987  fscanf(f,"%u",&(c->l[i]));
1988  }
1989  else
1990  {
1991  c->nl=0;
1992  c->l=NULL;
1993  }
1994 
1995  /* Load Polytope */
1996  fscanf(f,"%u\n",&(c->simple));
1997  if (c->simple)
1998  {
1999  NEW(c->sp,1,Tscpolytope);
2000  LoadSPolytope(f,c->sp);
2001  c->p=NULL;
2002  }
2003  else
2004  {
2005  NEW(c->p,1,Tcpolytope);
2006  LoadPolytope(f,c->p);
2007  c->sp=NULL;
2008  }
2009 }
2010 
2012 {
2013  /* Delete map center */
2014  if (c->center!=NULL)
2015  free(c->center);
2016 
2017  /* Delete tangent space */
2018  if (c->T!=NULL)
2019  free(c->T);
2020 
2021  /* Delete Jacobian basis */
2022  if (c->BJ!=NULL)
2023  free(c->BJ);
2024 
2025  /* Delete the list of linked charts */
2026  if (c->l!=NULL)
2027  free(c->l);
2028 
2029  /* Delete Polytope */
2030  if (c->p!=NULL)
2031  {
2032  DeletePolytope(c->p);
2033  free(c->p);
2034  }
2035  if (c->sp!=NULL)
2036  {
2037  DeleteSPolytope(c->sp);
2038  free(c->sp);
2039  }
2040 }
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:833
double GetChartMaxCurvError(Tchart *c)
Returns the maximum oriented curvature error between the chart and the manifold.
Definition: chart.c:955
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:1602
void SaveChart(FILE *f, Tchart *c)
Stores the chart information on a file.
Definition: chart.c:1877
double * GetLSSolutionBuffer(TLinearSystem *ls)
Buffer to store the linear system solution.
Definition: algebra.c:1156
double PolytopeVolume(Tcpolytope *mp)
Polytope volume.
Definition: cpolytope.c:951
unsigned int ChartMemSize(Tchart *c)
Memory used by a given chart.
Definition: chart.c:1862
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:446
#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:901
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:137
Data structure to hold the information about the name of a file.
Definition: filename.h:248
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:1340
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:975
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 InitWorldFromFile(Tparameters *p, Tfilename *f, Tworld *w)
Constructor.
void LinkCharts(unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Connect charts at singularities.
Definition: chart.c:1669
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:1458
double GetChartMaxError(Tchart *c)
Returns the maximum error between the chart and the manifold.
Definition: chart.c:950
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:332
double SPolytopeMaxVolume(Tscpolytope *mp)
Maximum volume of the simple polytope.
Definition: scpolytope.c:304
void IncreaseChartSamplingRadius(Tchart *c)
Increase the sampling radious of the chart.
Definition: chart.c:1379
double MinCosinusBetweenCharts(Tchart *c1, Tchart *c2)
Computes the angle between the tangent spaces in the charts.
Definition: chart.c:920
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:1066
void Error(const char *s)
General error function.
Definition: error.c:80
All the necessary information to generate equations for mechanisms.
Definition: world.h:124
#define CUIK_EXT
File extension for equation files.
Definition: filename.h:70
A color.
Definition: color.h:23
void GetJacobianSize(unsigned int *nr, unsigned int *nc, TJacobian *j)
Returns the size of the Jacobian.
Definition: jacobian.c:43
double ChartMaxVolume(Tchart *c)
Estimate the volume of a chart.
Definition: chart.c:1391
#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:355
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:938
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:1348
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:150
A simpleifed polytope associated with chart on a manifold.
Definition: scpolytope.h:61
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:792
void EvaluateJacobianInVector(double *v, unsigned int nr, unsigned int nc, double *m, TJacobian *j)
Evaluates the Jacobian.
Definition: jacobian.c:97
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:1364
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:1277
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:943
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:970
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:415
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:1546
double ChartVolume(Tparameters *pr, boolean collisionFree, unsigned int *tp, TJacobian *sJ, Tchart *c)
Estimate the volume of a chart.
Definition: chart.c:1406
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:1704
unsigned int GetChartAmbientDim(Tchart *c)
Dimensionality of the ambient space.
Definition: chart.c:960
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:1282
void DeleteChart(Tchart *c)
Destructor.
Definition: chart.c:2011
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:1270
#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:816
#define CS_WD_REGENERATE_ORIGINAL_POINT(pr, p, o, wcs)
Completes an original point from a simplified one.
Definition: wcs.h:279
unsigned int nl
Definition: chart.h:102
boolean ExpandibleChart(Tchart *c)
Identifies boundary charts.
Definition: chart.c:1292
A box.
Definition: box.h:83
unsigned int SPolytopeMemSize(Tscpolytope *mp)
Computes the memory used by the polytope.
Definition: scpolytope.c:345
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:1287
#define WORLD_EXT
File extension for problem files.
Definition: filename.h:161
#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:381
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:933
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:114
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:1356
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:1313
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:1112
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:1212
boolean OpenChart(Tchart *c)
Identifies charts not fully sorrounded by other charts.
Definition: chart.c:1300
double Error2Chart(double *p, unsigned int *tp, Tchart *c)
Distance from the manifold to the tangent space.
Definition: chart.c:1247
#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:1036
boolean CloseCharts(Tparameters *pr, unsigned int *tp, Tchart *c1, Tchart *c2)
Identifies close local charts.
Definition: chart.c:1264
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:1305
double * GetLSRHBuffer(TLinearSystem *ls)
Buffer to store the linear system right hand (RH).
Definition: algebra.c:1151
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:1675
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:800
double * GetLSMatrixBuffer(TLinearSystem *ls)
Buffer to store the A matrix.
Definition: algebra.c:1146
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:651
#define CS_WD_IN_COLLISION(f, pr, s, sPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:319
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:824
#define INF
Infinite.
Definition: defines.h:70
void EnlargeChart(double *t, Tchart *c)
Ensures that a chart includes a given point.
Definition: chart.c:1332
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:295
#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:1687
unsigned int GetChartManifoldDim(Tchart *c)
Dimensionality of the manifold space.
Definition: chart.c:965
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:1726
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:309
void LoadChart(FILE *f, TAtlasBase *w, Tchart *c)
Defines a chart from the information on a file.
Definition: chart.c:1932
unsigned int GetChartDegree(Tparameters *pr, double *T, TJacobian *sJ, boolean *singular, Tchart *c)
Returns the chart degree.
Definition: chart.c:985
unsigned int SPolytopeNeighbourID(unsigned int n, Tscpolytope *mp)
Returns the identifier of one of the neighbours of a polytope.
Definition: scpolytope.c:337
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:1477
void DecreaseChartSamplingRadius(Tchart *c)
Decrease the sampling radious of the chart.
Definition: chart.c:1385
void CostColor(double cost, double minCost, Tcolor *c)
Definees a color in function of a cost.
Definition: color.c:40
boolean SingularChart(Tchart *c)
Identify charts defined on singularities.
Definition: chart.c:980
double ChartErrorFromParameters(double *t, double *p, unsigned int *tp, Tchart *c)
Identifies points inside the defined error.
Definition: chart.c:1229
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:1629
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:928
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:808
#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:350
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:1321
#define CS_WD_ORIGINAL_IN_COLLISION(pr, o, oPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:348
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