cpolytope.c
Go to the documentation of this file.
1 #include "cpolytope.h"
2 
3 #include "defines.h"
4 #include "random.h"
5 #include "algebra.h"
6 #include "chart.h"
7 
8 #include "math.h"
9 #include "string.h"
10 
41 boolean HaveEdge(unsigned int i,unsigned int j,unsigned int *l,unsigned int *faces,Tcpolytope *mp);
42 
62 boolean PolytopeBoundaryPointFromExternalCornerInt(unsigned int nc,double rSample,
63  unsigned int *nv,double *t,Tcpolytope *mp);
64 
65 void InitEmptyPolytope(unsigned int k,double r,Tcpolytope *mp)
66 {
67  mp->r=r;
68  mp->k=k;
69 
70  mp->emptyPolytope=TRUE;
71 
72  mp->v=PolytopeMaxVolume(mp);
73 
74  mp->open=TRUE;
75 }
76 
78 {
79  if (mp->emptyPolytope)
80  {
81  unsigned int *c;
82  unsigned int i,j,nv;
83  double r;
84  Tinterval ri;
85 
86  /*The polytope is slighly larger than the ball*/
88 
89  /*make enough room for the vertices to define below and for many more*/
90  /*To save space non-used vertices are no initialized at all*/
91  mp->maxVertices=(1<<(mp->k+1)); /* 2^(k+1)*/
92  NEW(mp->vertex,mp->maxVertices,double *);
93  NEW(mp->maxIndices,mp->maxVertices,unsigned int);
94  NEW(mp->nIndices,mp->maxVertices,unsigned int);
95  NEW(mp->indices,mp->maxVertices,unsigned int *);
96  NEW(mp->expandible,mp->maxVertices,boolean);
97 
98  for(i=0;i<mp->maxVertices;i++)
99  {
100  mp->vertex[i]=NULL;
101  /* mp->maxIndices[i]==0 indicates a un-used vertex */
102  mp->maxIndices[i]=0;
103  /*nIndices is used to link free vertices.*/
104  mp->nIndices[i]=i+1;
105 
106  mp->indices[i]=NULL;
107 
108  mp->expandible[i]=FALSE; /*not used*/
109  }
110  mp->nExpandible=0;
111  mp->nVertices=0;
112  mp->nIndices[mp->maxVertices-1]=NO_UINT;
113  mp->freeVertex=0;
114 
115  /* Now define the faces */
116  mp->nFaces=2*mp->k;
117  mp->maxFaces=2*mp->nFaces;
118  NEW(mp->face,mp->maxFaces,double *);
119  NEW(mp->ID,mp->maxFaces,unsigned int);
120 
121  for(i=0;i<mp->k;i++)
122  {
123  NEW(mp->face[2*i],mp->k+1,double);
124  NEW(mp->face[2*i+1],mp->k+1,double);
125  for(j=0;j<mp->k+1;j++)
126  {
127  mp->face[2*i][j]=0;
128  mp->face[2*i+1][j]=0;
129  }
130  /* Faces are defined such that the center of the ball is
131  negative in the linear constraint. This corresponds to the
132  circle convention x^2+y^2-r^2=0 is negative for (0,0)*/
133  /* -x_i-r=0 (== x_i=-r) */
134  mp->face[2*i][i]=-1;
135  mp->face[2*i][mp->k]=-r;
136  /* x_i-r=0 (== x_i=+r) */
137  mp->face[2*i+1][i]=1;
138  mp->face[2*i+1][mp->k]=-r;
139 
140  mp->ID[2*i]=NO_UINT;
141  mp->ID[2*i+1]=NO_UINT;
142  }
143 
144  /* Now define the vertices and the indices*/
145  NEW(c,mp->k,unsigned int);
146  FirstCombination(mp->k,1,c);
147  do{
148  /*Take a free vertex. We know we have enough free
149  vertices -> no test for new space is done. */
150  nv=mp->freeVertex;
151  mp->freeVertex=mp->nIndices[mp->freeVertex];
152 
153  /*Allocate space for the vertex*/
154  NEW(mp->vertex[nv],mp->k,double);
155 
156  /*define the vertex*/
157  for(i=0;i<mp->k;i++)
158  mp->vertex[nv][i]=(c[i]==0?-r:r);
159 
160  /*and all vertices are valid for expansion */
161  mp->expandible[nv]=TRUE;
162  mp->nExpandible++;
163 
164  mp->nVertices++;
165 
166  /*set the planes defining the vertices*/
167  mp->maxIndices[nv]=mp->k;
168  mp->nIndices[nv]=mp->k;
169  NEW(mp->indices[nv],mp->k,unsigned int);
170  for(i=0;i<mp->k;i++)
171  mp->indices[nv][i]=(c[i]==0?2*i:2*i+1);
172  } while(NextCombination(mp->k,1,c));
173 
174  free(c);
175 
176  /*Bounding box for the polytope -> the polytope itself*/
177  InitBox(mp->k,NULL,&(mp->bb));
178  NewInterval(-r,r,&ri);
179  for(i=0;i<mp->k;i++)
180  SetBoxInterval(i,&ri,&(mp->bb));
181 
182  mp->emptyPolytope=FALSE;
183 
184  mp->open=TRUE;
185  }
186 }
187 
189 {
190  unsigned int k;
191  double *f;
192  unsigned int i,id,nf;
193  //double l;
194 
195  //l=GetSPolytopeBoxSide(sp);
196  k=GetSPolytopeDim(sp);
197  //InitEmptyPolytope(k,l/2,p);
198 
200  DefinePolytope(p);
201 
202  NEW(f,k+1,double);
203  nf=GetSPolytopeNFaces(sp);
204  for(i=0;i<nf;i++)
205  {
206  GetSPolytopeFace(i,f,sp);
207  id=SPolytopeNeighbourID(i,sp);
208  CutPolytopeWithFace(pr,f,f[k],id,NULL,NULL,0,NULL,NULL,p);
209  }
210 }
211 
213 {
214  unsigned int i;
215  double sr,delta;
216 
217  sr=GetParameter(CT_SR,pr);
218  delta=GetParameter(CT_DELTA,pr);
219 
220  InitEmptySPolytope(delta,p->k,p->r,sr,sp);
221  DefineSPolytope(sp);
222  for(i=0;i<p->nFaces;i++)
223  {
224  if (p->face[i]!=NULL)
225  CutSPolytopeWithFace(p->face[i],p->face[i][p->k],p->ID[i],sp);
226  }
227 }
228 
229 void CopyPolytope(Tcpolytope *mp_dst,Tcpolytope *mp_src)
230 {
231  mp_dst->k=mp_src->k;
232  mp_dst->r=mp_src->r;
233  mp_dst->v=mp_src->v;
234 
235  mp_dst->open=mp_src->open;
236 
237  mp_dst->emptyPolytope=mp_src->emptyPolytope;
238  if (!mp_src->emptyPolytope)
239  {
240  unsigned int i,j;
241 
242  mp_dst->nFaces=mp_src->nFaces;
243  mp_dst->maxFaces=mp_src->maxFaces;
244  NEW(mp_dst->face,mp_dst->maxFaces,double *);
245  NEW(mp_dst->ID,mp_dst->maxFaces,unsigned int);
246  for(i=0;i<mp_dst->nFaces;i++)
247  {
248  if (mp_src->face[i]==NULL)
249  mp_dst->face[i]=NULL;
250  else
251  {
252  NEW(mp_dst->face[i],mp_dst->k+1,double);
253  for(j=0;j<mp_dst->k+1;j++)
254  mp_dst->face[i][j]=mp_src->face[i][j];
255  }
256  mp_dst->ID[i]=mp_src->ID[i];
257  }
258 
259  mp_dst->maxVertices=mp_src->maxVertices;
260  NEW(mp_dst->vertex,mp_dst->maxVertices,double *);
261  NEW(mp_dst->nIndices,mp_dst->maxVertices,unsigned int);
262  NEW(mp_dst->maxIndices,mp_dst->maxVertices,unsigned int);
263  NEW(mp_dst->indices,mp_dst->maxVertices,unsigned int *);
264  NEW(mp_dst->expandible,mp_dst->maxVertices,boolean);
265 
266  for(i=0;i<mp_dst->maxVertices;i++)
267  {
268  if (mp_src->maxIndices[i]==0)
269  {
270  mp_dst->maxIndices[i]=0;
271  /*reproduce the free list*/
272  mp_dst->nIndices[i]=mp_src->nIndices[i];
273  mp_dst->vertex[i]=NULL;
274  mp_dst->indices[i]=NULL;
275  mp_dst->expandible[i]=FALSE; /*not used*/
276  }
277  else
278  {
279  NEW(mp_dst->vertex[i],mp_src->k,double);
280  for(j=0;j<mp_src->k;j++)
281  mp_dst->vertex[i][j]=mp_src->vertex[i][j];
282 
283  mp_dst->maxIndices[i]=mp_src->maxIndices[i];
284  mp_dst->nIndices[i]=mp_src->nIndices[i];
285  NEW(mp_dst->indices[i],mp_dst->maxIndices[i],unsigned int);
286  for(j=0;j<mp_dst->maxIndices[i];j++)
287  mp_dst->indices[i][j]=mp_src->indices[i][j];
288  mp_dst->expandible[i]=mp_src->expandible[i];
289  }
290  }
291  mp_dst->freeVertex=mp_src->freeVertex;
292 
293  mp_dst->nExpandible=mp_src->nExpandible;
294 
295  mp_dst->nVertices=mp_src->nVertices;
296 
297  CopyBox(&(mp_dst->bb),&(mp_src->bb));
298  }
299 }
300 
301 void PolytopeCenter(double *t,Tcpolytope *mp)
302 {
303  unsigned int i;
304 
305  for(i=0;i<mp->k;i++)
306  t[i]=0;
307 
308  if (!mp->emptyPolytope)
309  {
310  unsigned int j;
311  double w;
312 
313  if (mp->nVertices==0)
314  Error("Computing the center of a polytope with no vertices");
315 
316  w=1/(double)mp->nVertices;
317 
318  for(i=0;i<mp->maxVertices;i++)
319  {
320  if (mp->maxIndices[i]>0)
321  {
322  for(j=0;j<mp->k;j++)
323  t[j]+=(w*mp->vertex[i][j]);
324  }
325  }
326  }
327 }
328 
329 boolean InsidePolytope(double *t,Tcpolytope *mp)
330 {
331  unsigned int i;
332  boolean inside;
333 
334  if (mp->emptyPolytope)
335  {
336  inside=TRUE;
337  i=0;
338  while((i<mp->k)&&(inside))
339  {
340  inside=(fabs(t[i])<=mp->r);
341  i++;
342  }
343  }
344  else
345  {
346  if (mp->nVertices==0)
347  inside=FALSE;
348  else
349  {
350  inside=TRUE;
351  i=0;
352  while((i<mp->nFaces)&&(inside))
353  {
354  if (mp->face[i]!=NULL)
355  inside=(GeneralDotProduct(mp->k,mp->face[i],t)+mp->face[i][mp->k]<=0);
356  i++;
357  }
358  }
359  }
360  return(inside);
361 }
362 
363 
364 boolean HaveEdge(unsigned int i,unsigned int j,unsigned int *l,unsigned int *faces,Tcpolytope *mp)
365 {
366  if (mp->emptyPolytope)
367  return(FALSE);
368  else
369  {
370  unsigned int li,lj;
371 
372  li=0;
373  lj=0;
374  (*l)=0;
375  while((li<mp->nIndices[i])&&(lj<mp->nIndices[j]))
376  {
377  if (mp->indices[i][li]<mp->indices[j][lj])
378  li++;
379  else
380  {
381  if (mp->indices[i][li]>mp->indices[j][lj])
382  lj++;
383  else
384  {
385  faces[*l]=mp->indices[i][li];
386  (*l)++;
387  li++;
388  lj++;
389  }
390  }
391  }
392  return((*l)==mp->k-1);
393  }
394 }
395 
396 boolean CutPolytope(Tparameters *pr,double *t,double r,unsigned int id,void *wcs,void *c,
397  unsigned int m,unsigned int *tp,Tbox *ambient,Tcpolytope *mp)
398 {
399  double n;
400 
401  if (mp->emptyPolytope)
402  DefinePolytope(mp);
403 
404  /*The plane separating the two spheres has parameters 't'
405  and the offset is computed here */
406  n=Norm(mp->k,t);
407 
408  /* Note that typically mp->r==r and thus -(mp->r*mp->r-r*r+n*n)/2.0 = -n*n/2.0*/
409  return(CutPolytopeWithFace(pr,t,-(mp->r*mp->r-r*r+n*n)/2.0,id,wcs,c,m,tp,ambient,mp));
410 }
411 
412 boolean CutPolytopeWithFace(Tparameters *pr,double *t,double offset,unsigned int id,
413  void *wcs,void *c,unsigned int m,unsigned int *tp,Tbox *ambient,
414  Tcpolytope *mp)
415 {
416  if ((!mp->emptyPolytope)&&(mp->nVertices>0))
417  {
418  unsigned int i,j;
419  double *pos,*pt;
420  unsigned int *faces;
421  unsigned int ni;
422  unsigned int l,d,s,*mIndices,tv;
423  double o;
424  boolean *usedFace;
425  unsigned int nPos,nNeg;
426  boolean firstVertex;
427  double eps=0; /* tolerance. Used for debug only */
428 
429  NEW(pt,m,double);
430 
431  /*Evaluate the vertexes w.r.t. the plane */
432  nPos=0;
433  nNeg=0;
434  NEW(pos,mp->maxVertices,double);
435  for(i=0;i<mp->maxVertices;i++)
436  {
437  if (mp->maxIndices[i]>0)
438  {
439  pos[i]=GeneralDotProduct(mp->k,t,mp->vertex[i])+offset;
440  if (pos[i]<-eps)
441  nNeg++;
442  else
443  {
444  if (pos[i]>eps)
445  nPos++;
446  else
447  pos[i]=0.0;
448  }
449  }
450  }
451 
452  if ((nPos>0)&&(nNeg>0))
453  {
454  tv=mp->maxVertices; /*this can change inside the loop*/
455  /*The occupied vertices can also change -> backup the flags */
456  NEW(mIndices,tv,unsigned int);
457  memcpy(mIndices,mp->maxIndices,sizeof(unsigned int)*tv);
458 
459  /*Look for vertices at different position w.r.t. the plane
460  joined by an edge */
461  for(i=0;i<tv;i++)
462  {
463  if (mIndices[i]>0) /* if vertex in use */
464  {
465  ni=mp->nIndices[i]+1; /*max num common indices + 1 for current face */
466  NEW(faces,ni,unsigned int);
467  for(j=i+1;j<tv;j++)
468  {
469  /*if in-use and at the other side of the new face */
470  if ((mIndices[j]>0)&&(pos[i]*pos[j]<0))
471  {
472  /*check if there is an edge between the two vertices*/
473  if (HaveEdge(i,j,&l,faces,mp))
474  {
475  /*We have an edgge! -> cut it and add one new vertex*/
476  if (mp->freeVertex==NO_UINT)
477  {
478  /*Allocate new space for vertexes*/
479  d=mp->maxVertices;
480  MEM_DUP(mp->vertex,mp->maxVertices,double *);
481  MEM_EXPAND(mp->nIndices,mp->maxVertices,unsigned int);
482  MEM_EXPAND(mp->maxIndices,mp->maxVertices,unsigned int);
483  MEM_EXPAND(mp->indices,mp->maxVertices,unsigned int *);
484  MEM_EXPAND(mp->expandible,mp->maxVertices,boolean);
485 
486  for(s=d;s<mp->maxVertices;s++)
487  {
488  mp->vertex[s]=NULL;
489  mp->nIndices[s]=s+1;
490  mp->maxIndices[s]=0;
491  mp->indices[s]=NULL;
492  mp->expandible[s]=FALSE;
493  }
494  mp->nIndices[mp->maxVertices-1]=NO_UINT;
495  mp->freeVertex=d;
496  }
497  s=mp->freeVertex;
498  mp->freeVertex=mp->nIndices[mp->freeVertex];
499 
500  /*at a new vertex at position 's' interpolating between vi and vj*/
501  NEW(mp->vertex[s],mp->k,double);
502  o=-pos[i]/(pos[j]-pos[i]);
503  for(d=0;d<mp->k;d++)
504  mp->vertex[s][d]=mp->vertex[i][d]+(mp->vertex[j][d]-mp->vertex[i][d])*o;
505 
506  mp->maxIndices[s]=l+3;
507  NEW(mp->indices[s],mp->maxIndices[s],unsigned int);
508  memcpy(mp->indices[s],faces,sizeof(unsigned int)*l);
509  mp->indices[s][l]=mp->nFaces;
510  mp->nIndices[s]=l+1;
511 
512  /* Vertices outside the ball are suitable for expansion */
513  mp->expandible[s]=(Norm(mp->k,mp->vertex[s])>(mp->r+eps));
514  /* except if they are out of the domain. The following test is disconnected since
515  it can produce wrong results in some cases (large charts). Morever, the atlas
516  constructions tools already have strategies to detect the intersection with the
517  domain. */
518  if ((0)&&(mp->expandible[s])&&(c!=NULL)&&(ambient!=NULL)&&(m>0)&&(wcs!=NULL)&&(pr!=NULL))
519  {
520  /* We should use chart2manifold but it is more expensive, Local2Global
521  already provides a good indicator of vertexes out of the domain */
522  /* Note that this test is only meaningful if the charts are relatively small (large
523  charts might expand out of the domain but still beint useful. Large charts
524  are typically used in planning (AtlasRRT,...), but in this case we use
525  spolytopes instead than polytopes */
526  Local2Global(mp->vertex[s],tp,pt,(Tchart*)c);
527  mp->expandible[s]=((DistancePointToBoxTopology(pt,tp,ambient)>0.1*mp->r)||
528  (CS_WD_SIMP_INEQUALITIES_ERROR(pr,pt,(TAtlasBase*)wcs)>0.1*mp->r));
529  }
530  if (mp->expandible[s])
531  mp->nExpandible++;
532 
533  mp->nVertices++;
534  }
535  }
536  }
537  free(faces);
538  }
539  }
540 
541  /*Remove all vertexes outside the plane*/
542  for(i=0;i<tv;i++)
543  {
544  /* if vertex in use and outside the plane*/
545  if ((mIndices[i]>0)&&(pos[i]>0))
546  {
547  mp->nIndices[i]=mp->freeVertex;
548  mp->freeVertex=i;
549  mp->maxIndices[i]=0;
550  free(mp->indices[i]);
551  mp->indices[i]=NULL;
552  free(mp->vertex[i]);
553  mp->vertex[i]=NULL;
554 
555  if (mp->expandible[i])
556  mp->nExpandible--;
557 
558  mp->nVertices--;
559  mp->expandible[i]=FALSE; /* not used */
560  }
561 
562  if (eps>0)
563  {
564  /* Vertex on the new plane -> add face index to vertex list */
565  if ((mIndices[i]>0)&&(pos[i]==0))
566  {
567  /*Add a new plane to the list of*/
568  if (mp->nIndices[i]==mp->maxIndices[i])
569  MEM_DUP(mp->indices[i],mp->maxIndices[i],unsigned int);
570 
571  mp->indices[i][mp->nIndices[i]]=mp->nFaces;
572  mp->nIndices[i]++;
573  }
574  }
575  }
576 
577  free(mIndices);
578 
579  /*re-compute the bounding box*/
580  firstVertex=TRUE;
581  for(i=0;i<mp->maxVertices;i++)
582  {
583  if (mp->maxIndices[i]>0)
584  {
585  if (firstVertex)
586  {
587  DeleteBox(&(mp->bb));
588  InitBoxFromPoint(mp->k,mp->vertex[i],&(mp->bb));
589  firstVertex=FALSE;
590  }
591  else
592  ExpandBox(mp->vertex[i],&(mp->bb));
593  }
594  }
595 
596  /*Store the new face*/
597  if (mp->nFaces==mp->maxFaces)
598  {
599  MEM_DUP(mp->face,mp->maxFaces,double *);
600  MEM_EXPAND(mp->ID,mp->maxFaces,unsigned int);
601  }
602 
603  NEW(mp->face[mp->nFaces],mp->k+1,double);
604  for(i=0;i<mp->k;i++)
605  mp->face[mp->nFaces][i]=t[i];
606  mp->face[mp->nFaces][mp->k]=offset;
607  mp->ID[mp->nFaces]=id;
608  mp->nFaces++;
609 
610  /*Remove unused faces (faces that do not participate
611  of any vertex)*/
612  NEW(usedFace,mp->nFaces,boolean);
613  for(i=0;i<mp->nFaces;i++)
614  usedFace[i]=FALSE;
615 
616  for(i=0;i<mp->maxVertices;i++)
617  {
618  if (mp->maxIndices[i]>0)
619  {
620  for(j=0;j<mp->nIndices[i];j++)
621  usedFace[mp->indices[i][j]]=TRUE;
622  }
623  }
624 
625  /* While eliminating the unused faces, we update the "open" flag */
626  mp->open=FALSE;
627  for(i=0;i<mp->nFaces;i++)
628  {
629  if (usedFace[i])
630  mp->open=((mp->open)||(mp->ID[i]==NO_UINT));
631  else
632  {
633  if (mp->face[i]!=NULL)
634  {
635  mp->ID[i]=NO_UINT;
636 
637  free(mp->face[i]);
638  mp->face[i]=NULL;
639  }
640  }
641  }
642 
643  free(usedFace);
644  }
645  free(pos);
646 
647  mp->v=-1; /* the volume is invalidated */
648 
649  free(pt);
650  }
651  return(mp->open);
652 }
653 
655 {
656  return(mp->r);
657 }
658 
659 unsigned int GetPolytopeDim(Tcpolytope *mp)
660 {
661  return(mp->k);
662 }
663 
665 {
666  if (mp->emptyPolytope)
667  return(NULL);
668  else
669  return(&(mp->bb));
670 }
671 
673 {
674  if (!mp->emptyPolytope)
675  DeleteBox(&(mp->bb));
676  CopyBox(&(mp->bb),bb);
677 }
678 
680 {
681  return((mp->emptyPolytope)||(mp->nExpandible>0));
682 }
683 
684 void WrongPolytopeCorner(unsigned int nv,Tcpolytope *mp)
685 {
686  if ((!mp->emptyPolytope)&&(nv<mp->maxVertices)&&(mp->expandible[nv]))
687  {
688  mp->expandible[nv]=FALSE;
689  mp->nExpandible--;
690  }
691 }
692 
693 boolean GetPolytopeInteriorPoint(double rSample,double *t,Tcpolytope *mp)
694 {
695  boolean haveInterior;
696 
697  if (mp->nVertices==0)
698  haveInterior=FALSE;
699  else
700  {
701  unsigned int i,l;
702  double n,m;
703 
704  /* In most of the cases the center of the chart is
705  interior to the polytope */
706  for(i=0;i<mp->k;i++)
707  t[i]=0;
708 
709  if (InsidePolytope(t,mp))
710  haveInterior=TRUE;
711  else
712  {
713  /* If the center is not inside the polytope, use
714  the polytope vertex inside the ball with minor
715  norm (minor norm=closest to the chart center where
716  the chartping is more likely to be valid) */
717  haveInterior=FALSE;
718  m=INF;
719  i=0;
720  while(i<mp->maxVertices)
721  {
722  if (mp->maxIndices[i]>0)
723  {
724  n=Norm(mp->k,mp->vertex[i]);
725 
726  if ((n<=rSample)&&(n<m))
727  {
728  l=i;
729  n=m;
730  haveInterior=TRUE;
731  }
732  }
733  i++;
734  }
735  if (haveInterior)
736  {
737  for(i=0;i<mp->k;i++)
738  t[i]=mp->vertex[l][i];
739  }
740  else
741  {
742  PolytopeCenter(t,mp);
743  haveInterior=(Norm(mp->k,t)<=rSample);
744  }
745  }
746  }
747  return(haveInterior);
748 }
749 
750 boolean PolytopeBoundaryPointFromExternalCornerInt(unsigned int nc,double rSample,
751  unsigned int *nv,double *t,Tcpolytope *mp)
752 {
753  boolean ok;
754  unsigned int i,s;
755  double a,b,c,q,l,l1,l2;
756  boolean found;
757 
758  ok=TRUE;
759 
760  /* look for the 'nc' expangible vertex */
761  i=0;
762  found=FALSE;
763  s=0;
764  while((!found)&&(i<mp->maxVertices))
765  {
766  if ((mp->maxIndices[i]>0)&& /*if vertex in use*/
767  (mp->expandible[i])) /*and is expandible */
768  {
769  if (s==nc)
770  found=TRUE;
771  else
772  {
773  s++;
774  i++;
775  }
776  }
777  else
778  i++;
779  }
780  if (!found)
781  Error("Inconsistancy in the number of external vertices");
782 
783  /* We selected vertex 'i' */
784  (*nv)=i;
785 
786  if (Norm(mp->k,mp->vertex[i])<mp->r)
787  {
788  /* Not actually an external point, just return it .... (?) */
789  //memcpy(t,mp->vertex[i],mp->k*sizeof(double));
790  Warning("A vertex that should be exterior is interior (in PolytopeBoundaryPointFromExternalCornerInt)");
791  ok=FALSE;
792  }
793  else
794  {
795  /* Get a point inside the rSample ball (and inside the polytope) */
796  if (!GetPolytopeInteriorPoint(rSample,t,mp))
797  ok=FALSE;
798  else
799  {
800  /*Connect the external vertex and the point and
801  intersect with the ball (with radius rSample)*/
802  /* and we re-use t to store t-vertex[i] and we store the final
803  result in t also*/
804  SubtractVector(mp->k,t,mp->vertex[i]);
805 
806  /* intersect the line between t and vertex[i] and the ball with
807  radius rSample */
808  a=GeneralDotProduct(mp->k,t,t);
809  b=2.0*GeneralDotProduct(mp->k,mp->vertex[i],t);
810  c=GeneralDotProduct(mp->k,mp->vertex[i],mp->vertex[i])-rSample*rSample;
811 
812  q=-0.5*(b+SGN(b)*sqrt(b*b-4*a*c));
813  l1=q/a;
814  l2=c/q;
815 
816  /* If the two solutions are valid we pick the one closest
817  to the interior point (the largest one). At least
818  one of the solutions must be valid */
819  if ((l1>=0)&&(l1<=1))
820  {
821  if ((l2>=0)&&(l2<=1))
822  l=(l1>l2?l1:l2);
823  else
824  l=l1;
825  }
826  else
827  l=l2;
828 
829  ScaleVector(l,mp->k,t);
830  AccumulateVector(mp->k,mp->vertex[i],t);
831  }
832  }
833 
834  if (!ok)
835  {
836  /* The vertex is already in the ball (?) or there is no way
837  to generate a point on the ball -> just remove the vertex
838  from the list o candidates for expansion. This might leave
839  a chart without being fully expanded... */
840  WrongPolytopeCorner(*nv,mp);
841  *nv=NO_UINT;
842  }
843 
844  return(ok);
845 }
846 
847 boolean PolytopeBoundaryPointFromExternalCorner(double rSample,boolean rand,
848  unsigned int *nv,double *t,Tcpolytope *mp)
849 {
850  boolean ok;
851 
852  if (mp->emptyPolytope)
853  DefinePolytope(mp);
854 
855  if (mp->nExpandible==0)
856  {
857  ok=FALSE;
858  *nv=NO_UINT;
859  }
860  else
861  {
862  unsigned int nc;
863 
864  /* Pick one expandible vertex at random */
865  if (rand)
866  nc=randomMax(mp->nExpandible-1);
867  else
868  nc=0;
869 
870  /* Genereate the boundary point from the selected vertex */
871  ok=PolytopeBoundaryPointFromExternalCornerInt(nc,rSample,nv,t,mp);
872  }
873  return(ok);
874 }
875 
876 void PolytopeBoundaryPointsFromExternalCorners(double rSample,unsigned int *n,unsigned int **nv,
877  double ***t,Tcpolytope *mp)
878 {
879  if (mp->emptyPolytope)
880  DefinePolytope(mp);
881 
882  *n=mp->nExpandible;
883  if (*n==0)
884  {
885  *nv=NULL;
886  *t=NULL;
887  }
888  else
889  {
890  unsigned int i;
891 
892  NEW(*nv,*n,unsigned int);
893  NEW(*t,*n,double*);
894 
895  for(i=0;i<mp->nExpandible;i++)
896  {
897  NEW((*t)[i],mp->k,double);
898 
899  if (!PolytopeBoundaryPointFromExternalCornerInt(i,rSample,&((*nv)[i]),(*t)[i],mp))
900  {
901  free((*t)[i]);
902  (*t)[i]=NULL;
903  }
904  }
905  }
906 }
907 
908 boolean PolytopeRandomPointOnBoundary(double rSample,double *t,Tcpolytope *mp)
909 {
910  randomOnBall(rSample,mp->k,t);
911  return(InsidePolytope(t,mp));
912 }
913 
914 boolean RandomPointInPolytope(double *t,Tcpolytope *mp)
915 {
916  boolean havePoint;
917 
918  if (mp->emptyPolytope)
919  {
920  unsigned int i;
921  double v;
922  Tinterval r;
923 
924  /* For empty polytopes the bounding box is not yet
925  defined */
927  NewInterval(-v,+v,&r);
928 
929  for(i=0;i<mp->k;i++)
930  t[i]=randomInInterval(&r);
931 
932  havePoint=TRUE;
933  }
934  else
935  {
936  RandomPointInBox(NULL,t,&(mp->bb));
937  havePoint=InsidePolytope(t,mp);
938  }
939 
940  return(havePoint);
941 }
942 
944 {
945  if (mp->emptyPolytope)
946  return(pow(2*POLYTOPE_R_ENLARGEMENT*mp->r,mp->k));
947  else
948  return(GetBoxVolume(NULL,&(mp->bb)));
949 }
950 
952 {
953  if (mp->v<0)
954  {
955  unsigned int i,s,n;
956  double *t;
957 
958  NEW(t,mp->k,double);
959  s=0;
960  n=(unsigned int)floor(pow(10,mp->k));
961  if (n>10000) n=10000;
962  for(i=0;i<n;i++)
963  {
964  RandomPointInPolytope(t,mp);
965  if (InsidePolytope(t,mp))
966  s++;
967  }
968  free(t);
969  mp->v=PolytopeMaxVolume(mp)*((double)s)/((double)n);
970  }
971  return(mp->v);
972 }
973 
975 {
976  unsigned int k;
977 
978  k=0;
979  if (!mp->emptyPolytope)
980  {
981  unsigned int i;
982 
983  for(i=0;i<mp->nFaces;i++)
984  {
985  if (mp->ID[i]!=NO_UINT)
986  k++;
987  }
988  }
989  return(k);
990 }
991 
992 unsigned int PolytopeNeighbourID(unsigned int n,Tcpolytope *mp)
993 {
994  boolean found;
995  unsigned int i,k,nID;
996 
997  found=FALSE;
998  if (!mp->emptyPolytope)
999  {
1000  k=0;
1001  i=0;
1002  while((!found)&&(i<mp->nFaces))
1003  {
1004  if (mp->ID[i]==NO_UINT)
1005  i++;
1006  else
1007  {
1008  if (k==n)
1009  found=TRUE;
1010  else
1011  {
1012  k++;
1013  i++;
1014  }
1015  }
1016  }
1017  }
1018 
1019  if (found)
1020  nID=mp->ID[i];
1021  else
1022  nID=NO_UINT;
1023 
1024  return(nID);
1025 }
1026 
1027 void GetPolytopeVertices(unsigned int *nv,double ***v,Tcpolytope *mp)
1028 {
1029  unsigned int i;
1030 
1031  if (mp->emptyPolytope)
1032  DefinePolytope(mp);
1033 
1034  *nv=0;
1035  for(i=0;i<mp->maxVertices;i++)
1036  {
1037  if (mp->maxIndices[i]>0)
1038  (*nv)++;
1039  }
1040  if ((*nv)>0)
1041  {
1042  unsigned int k;
1043 
1044  NEW(*v,*nv,double*);
1045  k=0;
1046  for(i=0;i<mp->maxVertices;i++)
1047  {
1048  if (mp->maxIndices[i]>0)
1049  {
1050  NEW((*v)[k],mp->k,double);
1051  memcpy((*v)[k],mp->vertex[i],sizeof(double)*mp->k);
1052  k++;
1053  }
1054  }
1055  }
1056  else
1057  **v=NULL;
1058 }
1059 
1060 
1061 void GetPolytopeNeighboursFromVertices(unsigned int *nv,unsigned int **cID1,unsigned int **cID2,Tcpolytope *mp)
1062 {
1063  unsigned int i,j,k1,ne,ncf,*faces;
1064 
1065  if (mp->k!=2)
1066  Error("GetPolytopeNeighboursFromVertices only works for bidimensional manifolds");
1067 
1068  if (mp->emptyPolytope)
1069  DefinePolytope(mp);
1070 
1071  /* First count the number of vertices */
1072  *nv=0;
1073  for(i=0;i<mp->maxVertices;i++)
1074  {
1075  if (mp->maxIndices[i]>0)
1076  (*nv)++;
1077  }
1078  if ((*nv)>0)
1079  {
1080  NEW((*cID1),*nv,unsigned int);
1081  NEW((*cID2),*nv,unsigned int);
1082 
1083  /* Now, for all edges, determine their extremes */
1084  NEW(faces,mp->nFaces,unsigned int); /*space needed by HaveEdge*/
1085  k1=0;
1086  for(i=0;i<mp->maxVertices;i++)
1087  {
1088  if (mp->maxIndices[i]>0) /* if vertex in use */
1089  {
1090  ne=0; /* number of edges of vertex k1 */
1091  for(j=0;j<mp->maxVertices;j++)
1092  {
1093  if ((i!=j)&&(mp->maxIndices[j]>0)) /* if vertex in use */
1094  {
1095  if (HaveEdge(i,j,&ncf,faces,mp))
1096  {
1097  /* ncf (number of common faces) is 1 for k=2
1098  and faces[0] is the identifier of the
1099  face (edge) connecting vertices i and j */
1100  if (ne==0)
1101  (*cID1)[k1]=mp->ID[faces[0]];
1102  else
1103  {
1104  if (ne==1)
1105  (*cID2)[k1]=mp->ID[faces[0]];
1106  else
1107  Error("Three edges in the same vertex?");
1108  }
1109  ne++;
1110  }
1111  }
1112  }
1113  k1++;
1114  }
1115  }
1116  free(faces);
1117  }
1118  else
1119  {
1120  Error("A chart without vertices");
1121  cID1=NULL;
1122  cID2=NULL;
1123  }
1124 }
1125 
1126 void GetPolytopeEdges(unsigned int *ne,unsigned int **vID1,unsigned int **vID2,
1127  Tcpolytope *mp)
1128 {
1129  unsigned int i,j,k,k1,k2,ncf;
1130  unsigned int *faces;
1131 
1132  if (mp->emptyPolytope)
1133  DefinePolytope(mp);
1134 
1135  NEW(faces,mp->nFaces,unsigned int); /*space needed by HaveEdge*/
1136 
1137  k=mp->nVertices*mp->nVertices/2; /*bound to the maximum number of edges*/
1138  NEW(*vID1,k,unsigned int);
1139  NEW(*vID2,k,unsigned int);
1140 
1141  k1=0;
1142  k2=0;
1143  *ne=0;
1144  for(i=0;i<mp->maxVertices;i++)
1145  {
1146  if (mp->maxIndices[i]>0) /* if vertex in use */
1147  {
1148  k2=k1+1;
1149  for(j=i+1;j<mp->maxVertices;j++)
1150  {
1151  if (mp->maxIndices[j]>0) /* if vertex in use */
1152  {
1153  if (HaveEdge(i,j,&ncf,faces,mp))
1154  {
1155  (*vID1)[*ne]=k1;
1156  (*vID2)[*ne]=k2;
1157  (*ne)++;
1158  }
1159  k2++;
1160  }
1161  }
1162  k1++;
1163  }
1164  }
1165 
1166  free(faces);
1167 }
1168 
1169 unsigned int PolytopeMemSize(Tcpolytope *mp)
1170 {
1171  unsigned int i,b;
1172 
1173  b=sizeof(double)*mp->nFaces*(mp->k+1); /* face[][] */
1174  b+=sizeof(unsigned int)*mp->maxFaces; /* ID[] */
1175 
1176  b+=sizeof(double)*mp->nVertices*mp->k; /* vertex[][] */
1177  b+=sizeof(boolean)*mp->maxVertices; /* expandible[] */
1178 
1179  b+=sizeof(unsigned int)*mp->maxVertices; /* nIndices[] */
1180  b+=sizeof(unsigned int)*mp->maxVertices; /* maxIndices[] */
1181  for(i=0;i<mp->maxVertices;i++)
1182  b+=(sizeof(unsigned int)*mp->maxIndices[i]); /* indices[][] */
1183 
1184  return(b);
1185 }
1186 
1187 void SavePolytope(FILE *f,Tcpolytope *mp)
1188 {
1189  unsigned int i,j;
1190 
1191  fprintf(f,"%u\n",mp->k);
1192  fprintf(f,"%f\n",mp->r);
1193  fprintf(f,"%f\n",mp->v);
1194 
1195  fprintf(f,"%u\n",mp->open);
1196 
1197  fprintf(f,"%u\n",mp->emptyPolytope);
1198 
1199  if (!mp->emptyPolytope)
1200  {
1201  fprintf(f,"%u\n",mp->nExpandible);
1202  fprintf(f,"%u\n",mp->nVertices);
1203  fprintf(f,"%u\n",mp->maxVertices);
1204 
1205  if (mp->maxVertices>0)
1206  {
1207  for(i=0;i<mp->maxVertices;i++)
1208  {
1209  fprintf(f,"%u\n",mp->maxIndices[i]);
1210  if (mp->maxIndices[i]>0)
1211  {
1212  for(j=0;j<mp->k;j++)
1213  fprintf(f,"%.12f ",mp->vertex[i][j]);
1214  fprintf(f,"\n");
1215 
1216  fprintf(f,"%u\n",mp->nIndices[i]);
1217  for(j=0;j<mp->nIndices[i];j++)
1218  fprintf(f,"%u ",mp->indices[i][j]);
1219  fprintf(f,"\n");
1220  }
1221  else
1222  fprintf(f,"%u\n",mp->nIndices[i]);
1223 
1224  fprintf(f,"%u\n",mp->expandible[i]);
1225  }
1226  fprintf(f,"%u\n",mp->freeVertex);
1227 
1228  fprintf(f,"%u\n",mp->nFaces);
1229  if (mp->nFaces>0)
1230  {
1231  fprintf(f,"%u\n",mp->maxFaces);
1232  for(i=0;i<mp->nFaces;i++)
1233  {
1234  if (mp->face[i]==NULL)
1235  fprintf(f,"0\n");
1236  else
1237  {
1238  fprintf(f,"1\n");
1239  for(j=0;j<mp->k+1;j++)
1240  fprintf(f,"%.12f ",mp->face[i][j]);
1241  fprintf(f,"\n");
1242  fprintf(f,"%u\n",mp->ID[i]);
1243  }
1244  }
1245  }
1246  }
1247 
1248  PrintBox(f,&(mp->bb));
1249  }
1250 }
1251 
1252 void LoadPolytope(FILE *f,Tcpolytope *mp)
1253 {
1254  unsigned int i,j,flag;
1255 
1256  fscanf(f,"%u",&(mp->k));
1257  fscanf(f,"%lf",&(mp->r));
1258  fscanf(f,"%lf",&(mp->v));
1259 
1260  fscanf(f,"%u",&(mp->open));
1261 
1262  fscanf(f,"%u",&(mp->emptyPolytope));
1263 
1264  if (!mp->emptyPolytope)
1265  {
1266  fscanf(f,"%u",&(mp->nExpandible));
1267  fscanf(f,"%u",&(mp->nVertices));
1268  fscanf(f,"%u",&(mp->maxVertices));
1269 
1270  if (mp->maxVertices>0)
1271  {
1272  NEW(mp->vertex,mp->maxVertices,double*);
1273  NEW(mp->maxIndices,mp->maxVertices,unsigned int);
1274  NEW(mp->nIndices,mp->maxVertices,unsigned int);
1275  NEW(mp->indices,mp->maxVertices,unsigned int*);
1276  NEW(mp->expandible,mp->maxVertices,boolean);
1277  for(i=0;i<mp->maxVertices;i++)
1278  {
1279  fscanf(f,"%u",&(mp->maxIndices[i]));
1280  if (mp->maxIndices[i]>0)
1281  {
1282  NEW(mp->vertex[i],mp->k,double);
1283  for(j=0;j<mp->k;j++)
1284  fscanf(f,"%lf",&(mp->vertex[i][j]));
1285 
1286  NEW(mp->indices[i],mp->maxIndices[i],unsigned int);
1287  fscanf(f,"%u",&(mp->nIndices[i]));
1288  for(j=0;j<mp->nIndices[i];j++)
1289  fscanf(f,"%u",&(mp->indices[i][j]));
1290  }
1291  else
1292  {
1293  mp->vertex[i]=NULL;
1294  mp->indices[i]=NULL;
1295  fscanf(f,"%u",&(mp->nIndices[i]));
1296  }
1297  fscanf(f,"%u",&(mp->expandible[i]));
1298  }
1299  fscanf(f,"%u",&(mp->freeVertex));
1300 
1301  fscanf(f,"%u",&(mp->nFaces));
1302  if (mp->nFaces>0)
1303  {
1304  fscanf(f,"%u",&(mp->maxFaces));
1305  NEW(mp->face,mp->maxFaces,double *);
1306  NEW(mp->ID,mp->maxFaces,unsigned int);
1307  for(i=0;i<mp->nFaces;i++)
1308  {
1309  fscanf(f,"%u",&flag);
1310  if (flag)
1311  {
1312  NEW(mp->face[i],mp->k+1,double);
1313  for(j=0;j<mp->k+1;j++)
1314  fscanf(f,"%lf",&(mp->face[i][j]));
1315 
1316  fscanf(f,"%u",&(mp->ID[i]));
1317  }
1318  else
1319  {
1320  mp->face[i]=NULL;
1321  mp->ID[i]=NO_UINT;
1322  }
1323  }
1324  }
1325  else
1326  {
1327  mp->face=NULL;
1328  mp->maxFaces=0;
1329  }
1330 
1331  ReadBox(f,&(mp->bb));
1332  }
1333  else
1334  {
1335  mp->face=NULL;
1336  mp->nFaces=0;
1337  mp->maxFaces=0;
1338 
1339  mp->vertex=NULL;
1340  mp->nIndices=NULL;
1341  mp->maxIndices=NULL;
1342  mp->indices=NULL;
1343  mp->expandible=NULL;
1344 
1345  mp->freeVertex=NO_UINT;
1346  }
1347  }
1348 }
1349 
1351 {
1352  unsigned int i,j;
1353  unsigned int nf;
1354 
1355  if (mp->emptyPolytope)
1356  DefinePolytope(mp);
1357 
1358  nf=0;
1359  for (i=0;i<mp->maxFaces;i++)
1360  {
1361  if (mp->face!=NULL)
1362  nf++;
1363  }
1364  printf("Num vertices : %u\n",mp->nVertices);
1365  printf("Num faces : %u\n",nf);
1366  printf("New face : %u\n",mp->nFaces);
1367  for(i=0;i<mp->maxVertices;i++)
1368  {
1369  if (mp->maxIndices[i]>0)
1370  {
1371  printf("Vertex %u -> [ ",i);
1372  for(j=0;j<mp->nIndices[i];j++)
1373  printf("%u ",mp->indices[i][j]);
1374  printf("]\n");
1375  }
1376  }
1377  fflush(stdout);
1378 }
1379 
1381 {
1382  if (!mp->emptyPolytope)
1383  {
1384  unsigned int i;
1385 
1386  for(i=0;i<mp->nFaces;i++)
1387  {
1388  if (mp->face[i]!=NULL)
1389  free(mp->face[i]);
1390  }
1391  free(mp->face);
1392  mp->face=NULL;
1393  mp->nFaces=0;
1394  mp->maxFaces=0;
1395 
1396  free(mp->ID);
1397  mp->ID=NULL;
1398 
1399  for(i=0;i<mp->maxVertices;i++)
1400  {
1401  /* if the vertex is not-free. */
1402  if (mp->maxIndices>0) /* same as mp->vertices[i]!=NULL */
1403  {
1404  free(mp->vertex[i]);
1405  free(mp->indices[i]);
1406  }
1407  }
1408  free(mp->vertex);
1409  free(mp->nIndices);
1410  free(mp->maxIndices);
1411  free(mp->indices);
1412  free(mp->expandible);
1413 
1414  mp->nExpandible=0;
1415  mp->nVertices=0;
1416 
1417  mp->vertex=NULL;
1418  mp->nIndices=NULL;
1419  mp->maxIndices=NULL;
1420  mp->indices=NULL;
1421  mp->expandible=NULL;
1422 
1423  mp->maxVertices=0;
1424  mp->freeVertex=NO_UINT;
1425 
1426  DeleteBox(&(mp->bb));
1427  }
1428 }
#define CT_R
Ball radius in atlas.
Definition: parameters.h:257
void SetPolytopeBB(Tbox *bb, Tcpolytope *mp)
Modifies the bounding box of the polytope.
Definition: cpolytope.c:672
unsigned int GetPolytopeDim(Tcpolytope *mp)
Returns the simple polytope dimensionality.
Definition: cpolytope.c:659
CBLAS_INLINE void ScaleVector(double f, unsigned int s, double *v)
Scales a vector.
Definition: basic_algebra.c:30
double PolytopeVolume(Tcpolytope *mp)
Polytope volume.
Definition: cpolytope.c:951
boolean PolytopeRandomPointOnBoundary(double rSample, double *t, Tcpolytope *mp)
Random point on the boundary of the chart.
Definition: cpolytope.c:908
boolean open
Definition: cpolytope.h:88
unsigned int freeVertex
Definition: cpolytope.h:78
#define CT_SR
Sampling ball in atlas.
Definition: parameters.h:266
void GetPolytopeVertices(unsigned int *nv, double ***v, Tcpolytope *mp)
Gets the set of vertices of the polytope.
Definition: cpolytope.c:1027
#define FALSE
FALSE.
Definition: boolean.h:30
double GetPolytopeRadius(Tcpolytope *mp)
Returns the simple polytope radius.
Definition: cpolytope.c:654
unsigned int nExpandible
Definition: cpolytope.h:76
#define SGN(a)
Returns the sign of a floating point.
Definition: defines.h:185
void FirstCombination(unsigned int n, unsigned int m, unsigned int *cb)
Initializes a combination.
Definition: geom.c:706
unsigned int maxVertices
Definition: cpolytope.h:71
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
void WrongPolytopeCorner(unsigned int nv, Tcpolytope *mp)
Mark a vertex as wrong.
Definition: cpolytope.c:684
unsigned int randomMax(unsigned int m)
Returns a random integer in the range [0,m].
Definition: random.c:77
void SetBoxInterval(unsigned int n, Tinterval *is, Tbox *b)
Replaces a particular interval in a box.
Definition: box.c:259
void CutSPolytopeWithFace(double *t, double offset, unsigned int id, Tscpolytope *mp)
Cuts a simple polytope with a given plane.
Definition: scpolytope.c:199
unsigned int nFaces
Definition: cpolytope.h:65
#define POLYTOPE_R_ENLARGEMENT
Factor to expand the polytope w.r.t. the included box.
Definition: cpolytope.h:32
Tbox * GetPolytopeBB(Tcpolytope *mp)
Returns the simple polytope bounding box.
Definition: cpolytope.c:664
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
void DefineSPolytope(Tscpolytope *mp)
Initial definition of the simple polytope bounding the local chart.
Definition: scpolytope.c:43
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
double ** vertex
Definition: cpolytope.h:73
void SPolytope2Polytope(Tparameters *pr, Tscpolytope *sp, Tcpolytope *p)
Defines a chart polytope from a simple chart polytope.
Definition: cpolytope.c:188
unsigned int * ID
Definition: cpolytope.h:69
unsigned int * maxIndices
Definition: cpolytope.h:81
void PrintPolytopeInfo(Tcpolytope *mp)
Prints information about the polytope.
Definition: cpolytope.c:1350
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
void InitBox(unsigned int dim, Tinterval *is, Tbox *b)
Initializes a box.
Definition: box.c:23
void Error(const char *s)
General error function.
Definition: error.c:80
boolean * expandible
Definition: cpolytope.h:74
boolean emptyPolytope
Definition: cpolytope.h:59
Definition of a polytope associated to a chart.
A chart on a manifold.
Definition: chart.h:70
void RandomPointInBox(boolean *used, double *c, Tbox *b)
Returns the a random point along the selected dimensions.
Definition: box.c:706
void PolytopeCenter(double *t, Tcpolytope *mp)
Computes the center of the polytope.
Definition: cpolytope.c:301
boolean NextCombination(unsigned int n, unsigned int m, unsigned int *cb)
Moves to the next combination.
Definition: geom.c:714
double ** face
Definition: cpolytope.h:67
int ReadBox(FILE *f, Tbox *b)
Reads a box from a file.
Definition: box.c:1196
A simpleifed polytope associated with chart on a manifold.
Definition: scpolytope.h:45
unsigned int k
Definition: cpolytope.h:53
void Polytope2SPolytope(Tparameters *pr, Tcpolytope *p, Tscpolytope *sp)
Defines a simple chart polytope from a normal/full chart polytope.
Definition: cpolytope.c:212
CBLAS_INLINE double GeneralDotProduct(unsigned int s, double *v1, double *v2)
Computes the dot product of two general vectors.
Definition: basic_algebra.c:15
unsigned int PolytopeNumNeighbours(Tcpolytope *mp)
Number of neighbours of the polytope.
Definition: cpolytope.c:974
Definitions of constants and macros used in several parts of the cuik library.
boolean ExpandiblePolytope(Tcpolytope *mp)
Identifies polytopes not fully bounded.
Definition: cpolytope.c:679
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
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
boolean GetPolytopeInteriorPoint(double rSample, double *t, Tcpolytope *mp)
Returns a point inside the ball and the polytope.
Definition: cpolytope.c:693
void CopyBox(void *b_out, void *b_in)
Box copy operator.
Definition: box.c:160
void InitEmptySPolytope(double delta, unsigned int k, double r, double sr, Tscpolytope *mp)
Defines an empty chart simplieifed polytope.
Definition: scpolytope.c:21
void GetSPolytopeFace(unsigned int n, double *f, Tscpolytope *mp)
Gets a face.
Definition: scpolytope.c:249
boolean HaveEdge(unsigned int i, unsigned int j, unsigned int *l, unsigned int *faces, Tcpolytope *mp)
Identifies vertices connected by an edge.
Definition: cpolytope.c:364
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
void Warning(const char *s)
General warning function.
Definition: error.c:116
A table of parameters.
double DistancePointToBoxTopology(double *p, unsigned int *tp, Tbox *b)
Distance from a point to a box.
Definition: box.c:971
unsigned int GetSPolytopeNFaces(Tscpolytope *mp)
Number of faces of a simple chart polytope.
Definition: scpolytope.c:244
unsigned int maxFaces
Definition: cpolytope.h:66
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.
boolean InsidePolytope(double *t, Tcpolytope *mp)
Identifies points inside a chart polytope.
Definition: cpolytope.c:329
double v
Definition: cpolytope.h:57
A box.
Definition: box.h:83
#define CS_WD_SIMP_INEQUALITIES_ERROR(pr, p, wcs)
Maximum error in the inequalities.
Definition: wcs.h:223
Tbox bb
Definition: cpolytope.h:86
unsigned int PolytopeMemSize(Tcpolytope *mp)
Computes the memory used by the polytope.
Definition: cpolytope.c:1169
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
unsigned int GetSPolytopeDim(Tscpolytope *mp)
Returns the simple polytope dimensionality.
Definition: scpolytope.c:239
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
void InitBoxFromPoint(unsigned int dim, double *p, Tbox *b)
Initializes a box from a point.
Definition: box.c:43
unsigned int * nIndices
Definition: cpolytope.h:80
CBLAS_INLINE void SubtractVector(unsigned int s, double *v1, double *v2)
Substracts a vector from another vector.
A polytope associated with chart on a manifold.
Definition: cpolytope.h:52
void DeleteBox(void *b)
Destructor.
Definition: box.c:1283
void CopyPolytope(Tcpolytope *mp_dst, Tcpolytope *mp_src)
Copies the polytope from one chart to another.
Definition: cpolytope.c:229
double randomInInterval(Tinterval *t)
Returns a random double in the given interval.
Definition: random.c:67
void randomOnBall(double r, unsigned int k, double *p)
Random number on a k dimensional ball.
Definition: random.c:110
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
#define MEM_EXPAND(_var, _n, _type)
Expands a previously allocated memory space.
Definition: defines.h:404
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
unsigned int boolean
Boolean type.
Definition: boolean.h:13
void ExpandBox(double *p, Tbox *b)
Expands a box so that it includes a given point.
Definition: box.c:67
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define INF
Infinite.
Definition: defines.h:70
#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
void DefinePolytope(Tcpolytope *mp)
Initial definition of the polytope bounding the local chart.
Definition: cpolytope.c:77
Definition of basic randomization functions.
void PrintBox(FILE *f, Tbox *b)
Prints a box.
Definition: box.c:1142
Defines a interval.
Definition: interval.h:33
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 LoadPolytope(FILE *f, Tcpolytope *mp)
Reads the chart polytope from a file.
Definition: cpolytope.c:1252
double r
Definition: cpolytope.h:54
double GetBoxVolume(boolean *used, Tbox *b)
Computes the volume of the box.
Definition: box.c:980
unsigned int ** indices
Definition: cpolytope.h:82
boolean RandomPointInPolytope(double *t, Tcpolytope *mp)
Random point on the polytope with uniform distribution.
Definition: cpolytope.c:914
boolean PolytopeBoundaryPointFromExternalCornerInt(unsigned int nc, double rSample, unsigned int *nv, double *t, Tcpolytope *mp)
Auxiliary function to get a boundary point for a given external vertex.
Definition: cpolytope.c:750
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 nVertices
Definition: cpolytope.h:72