From 5086631c287a954bae9c2bb4a987cb7f1eda3e57 Mon Sep 17 00:00:00 2001 From: Franz Zotter Date: Tue, 21 Aug 2012 08:10:42 +0000 Subject: convex hull algorithm added svn path=/trunk/externals/iem/iemmatrix/; revision=16165 --- src/mtx_qhull/list.c | 294 ++++++++++++++++++ src/mtx_qhull/list.h | 38 +++ src/mtx_qhull/mtx_xprod.pd | 32 ++ src/mtx_qhull/test.obj | 72 +++++ src/mtx_qhull/test_list.c | 94 ++++++ src/mtx_qhull/test_write_conv_hull_obj.pd | 201 +++++++++++++ src/mtx_qhull/vectors.c | 126 ++++++++ src/mtx_qhull/vectors.h | 40 +++ src/mtx_qhull/zhull.c | 482 ++++++++++++++++++++++++++++++ src/mtx_qhull/zhull.h | 25 ++ 10 files changed, 1404 insertions(+) create mode 100644 src/mtx_qhull/list.c create mode 100644 src/mtx_qhull/list.h create mode 100755 src/mtx_qhull/mtx_xprod.pd create mode 100644 src/mtx_qhull/test.obj create mode 100644 src/mtx_qhull/test_list.c create mode 100644 src/mtx_qhull/test_write_conv_hull_obj.pd create mode 100644 src/mtx_qhull/vectors.c create mode 100644 src/mtx_qhull/vectors.h create mode 100644 src/mtx_qhull/zhull.c create mode 100644 src/mtx_qhull/zhull.h (limited to 'src/mtx_qhull') diff --git a/src/mtx_qhull/list.c b/src/mtx_qhull/list.c new file mode 100644 index 0000000..07ce4f2 --- /dev/null +++ b/src/mtx_qhull/list.c @@ -0,0 +1,294 @@ + +// memory things: +list_t emptyList(void) { + list_t generated_list; + generated_list.length=0; + generated_list.entries=0; + return generated_list; +} + +list_t allocateList(const size_t length) { + list_t generated_list = emptyList(); + if (length>0) { + generated_list.entries= (entry_t*) malloc(length*sizeof(entry_t)); + if (generated_list.entries!=0) { + generated_list.length=length; + // printf("got list %li\n",generated_list.entries); + } + } + return generated_list; +} + +void reallocateList(list_t *list, + const size_t length) { + entry_t *old_entries = list->entries; + if (length>0) { + if (list->length==0) + *list = allocateList(length); + else { + if (list->length != length) + list->entries = (entry_t*) realloc(list->entries,length*sizeof(entry_t)); + if (list->entries!=0) + list->length=length; + else + *list=emptyList(); + } + } + else + freeList(list); + /* if ((list->entries!=old_entries)&&(old_entries!=0)) { + if (list->entries!=0) + printf("moved %li by realloc to %li\n",old_entries,list->entries); + else + printf("freed %li by realloc\n", old_entries); + }*/ +} + + +void freeList(list_t *list) { + if (list->entries!=0) { + // printf("deleting list %li\n",list->entries); + free(list->entries); + } + list->entries=0; + list->length=0; +} + +// programming interface: + +size_t getLength(const list_t list) { + return list.length; +} + +entry_t getEntry(const list_t list, const index_t index) { + if ((index>=0)&&(index=0)&&(index=start) { + length=(size_t) (stop-start+1); + incr=1; + } else { + length=(size_t) (start-stop+1); + incr=-1; + } + list_t l = allocateList(length); + if (l.entries!=0) + for (i=0,c=start; i0)&&(stop>0)&&(startstop) { + incr=-1; + new_list=allocateList(start-stop+1); + } else { + incr=1; + new_list=allocateList(start-stop+1); + } + for (j=start,i=0; i(size_t)i) { + setEntry(*list,i,entry); + } +} + +void removeEntryFromList(list_t *list, const index_t index) { + index_t i,j; + for (i=j=0; ilength; + reallocateList(list1, getLength(*list1) + getLength(list2)); + if (getLength(*list1)>siz_old) { + for (i=siz_old, j=0; ilength; i++, j++) + setEntry(*list1,i,getEntry(list2,j)); + } +} + +void removeEntryListFromList(list_t *list, const list_t indices) { + index_t i,j; + for (i=j=0; i0) + for (i=0, j=getLength(*list)-1; ientries[j]!=list->entries[i]); + if (keep) { + list->entries[i++]=list->entries[j]; + k++; + } + } + reallocateList(list, k); +} + +list_t findValueListInList(const list_t value_list, + const list_t list) { + list_t l=emptyList(); + index_t i,j; + for (i=0; i0) + printf("%d",getEntry(list,0)); + for (i=1; i +#include +#include "list.h" + +int main(char **argv, int argc) { + list_t l1=emptyList(); + list_t l2=emptyList(); + list_t l3=emptyList(); + int x[]={0, 2, 4, 6}; + + printf("empty list:\n"); + printList(l1); + freeList(&l1); + + printf("constant list with 10 1 entries:\n"); + l1=initConstantList(1,10); + printList(l1); + freeList(&l1); + + printf("list from 2 to 3:\n"); + l1=initListFromTo(2,3); + printList(l1); + printf("list from 7 to 1:\n"); + l2=initListFromTo(7,1); + printList(l2); + printf("duplicate list from 2 to 3:\n"); + l3=duplicateList(l1); + printList(l3); + freeList(&l3); + + printf("merge list from 1 to 7 with list from 2 to 3:\n"); + l3=mergeLists(l1,l2); + printList(l3); + + printf("remove entry 6 list from list:\n"); + removeValueFromList(&l3,6); + printList(l3); + + printf("remove entries [2, 3] from list:\n"); + removeValueListFromList(&l3,l1); + printList(l3); + + printf("reverse list:\n"); + reverseList (&l3); + printList(l3); + + printf("append entry 8 to list:\n"); + appendToList(&l3,8); + printList(l3); + + printf("is 8 not in list?: %d\n",notInList(8,l3)); + printf("is 3 not in list?: %d\n",notInList(3,l3)); + + printf("remove item 4 from list\n"); + removeEntryFromList(&l3,4); + printList(l3); + + printf("remove item 1 from list\n"); + removeEntryFromList(&l3,1); + printList(l3); + + printf("remove item 0 from list\n"); + removeEntryFromList(&l3,0); + printList(l3); + + printf("...taking a longer list\n"); + printList(l2); + freeList(&l3); + l3=initList(x,4); + printf("removing index list "); + printList(l3); + removeEntryListFromList(&l2,l3); + printList(l2); + freeList(&l1); + freeList(&l2); + freeList(&l3); + + l1=initListFromTo(1,3); + l2=initListFromTo(0,5); + printf("...taking a longer list\n"); + printList(l1); + printf("finding indices of values in list"); + printList(l2); + l3=findValueListInList(l2,l1); + printList(l3); + + + freeList(&l1); + freeList(&l2); + freeList(&l3); + +} + +// gcc list.c test_list.c && ./a.out diff --git a/src/mtx_qhull/test_write_conv_hull_obj.pd b/src/mtx_qhull/test_write_conv_hull_obj.pd new file mode 100644 index 0000000..d27370d --- /dev/null +++ b/src/mtx_qhull/test_write_conv_hull_obj.pd @@ -0,0 +1,201 @@ +#N canvas 534 0 850 668 10; +#X obj 595 205 convhull 0.001; +#X obj 595 176 t a a; +#N canvas 69 11 539 331 writeobject 0; +#X obj 163 270 textfile; +#X obj 163 161 mtx; +#X obj 163 123 until; +#X obj 200 123 f; +#X obj 226 123 + 1; +#X msg 225 102 1; +#X obj 163 81 t a a b; +#X obj 163 102 mtx_size; +#X obj 143 32 inlet; +#X obj 373 44 inlet; +#X msg 199 142 row \$1; +#X obj 163 238 list trim; +#X msg 269 196 add \$1; +#X msg 329 174 symbol v; +#X obj 373 65 t a b; +#X obj 143 54 t b a b; +#X msg 45 230 write test.obj cr; +#X msg 399 108 clear; +#X obj 164 218 list prepend; +#X msg 269 174 symbol f; +#X connect 1 0 18 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 3 0 10 0; +#X connect 4 0 3 1; +#X connect 5 0 3 1; +#X connect 6 0 7 0; +#X connect 6 1 1 1; +#X connect 6 2 5 0; +#X connect 7 0 2 0; +#X connect 8 0 15 0; +#X connect 9 0 14 0; +#X connect 10 0 1 0; +#X connect 11 0 0 0; +#X connect 12 0 18 1; +#X connect 13 0 12 0; +#X connect 14 0 6 0; +#X connect 14 1 13 0; +#X connect 14 1 17 0; +#X connect 15 0 16 0; +#X connect 15 1 6 0; +#X connect 15 2 19 0; +#X connect 16 0 0 0; +#X connect 17 0 0 0; +#X connect 18 0 11 0; +#X connect 19 0 12 0; +#X restore 116 490 pd writeobject; +#N canvas 0 22 450 300 gemwin 0; +#X obj 132 136 gemwin; +#X obj 67 89 outlet; +#X obj 67 10 inlet; +#X obj 67 41 route create; +#X msg 67 70 set destroy; +#X msg 142 68 set create; +#X msg 132 112 create \, 1 \, lighting 1; +#X msg 298 112 destroy \, reset; +#X msg 256 79 color 0.78 0.8 1; +#X obj 256 57 loadbang; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 3 0 6 0; +#X connect 3 1 5 0; +#X connect 3 1 7 0; +#X connect 4 0 1 0; +#X connect 5 0 1 0; +#X connect 6 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 0 0; +#X connect 9 0 8 0; +#X restore 556 423 pd gemwin; +#X msg 556 404 destroy; +#X obj 668 404 gemhead; +#X obj 668 423 world_light; +#X obj 362 -1 gemhead; +#X obj 393 151 model; +#X floatatom 377 79 5 0 0 0 - - -; +#X floatatom 420 80 5 0 0 0 - - -; +#X floatatom 460 80 5 0 0 0 - - -; +#X msg 17 196 open test.obj; +#X msg 500 97 rescale 0; +#X obj 364 38 color 0.9 0.9 0.9; +#X obj 595 227 extra_point; +#X obj 209 467 mtx_* 1.5; +#X obj 363 18 ortho; +#X obj 488 -3 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 485 38 f; +#X obj 540 38 % 360; +#X obj 480 17 metro 50; +#X msg 360 176 smooth 0; +#X obj 595 266 convhull 0.001; +#X obj 595 248 t a a; +#X obj 85 411 mtx; +#X obj 84 446 mtx_slice; +#X msg 123 425 1 1 \$1 end; +#X floatatom 18 250 5 0 0 0 - - -; +#X obj 221 440 mtx; +#X obj -7 284 t b b f b; +#X obj 125 394 mtx_size; +#X obj 101 375 t a a; +#X msg 184 396 set \$1; +#X obj 355 101 rotateXYZ -74 0 0; +#X obj 513 38 + 3; +#X obj 360 128 t b a; +#X obj 113 332 convhull 0.001; +#X obj 159 229 t a a; +#X msg 105 72 4 40; +#X msg 109 92 5 67; +#X msg 103 50 3 26; +#X msg 101 137 read designsN/N\$1_\$2.mtx \, bang; +#X obj 60 135 mtx; +#X obj 183 280 demux; +#X obj 210 213 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 +1; +#X obj 249 237 t b f; +#X obj 60 165 t b a b; +#X msg 111 111 9 180; +#X msg 97 1 1.5 6; +#X msg 104 27 2 14; +#X msg 181 43 2.5 12; +#X floatatom 323 280 5 0 0 0 - - -; +#X obj 327 301 t b f; +#X obj 416 257 mtx_rand; +#X msg 427 235 200 3; +#X obj 245 336 mtx_qhull 500; +#X msg 175 77 read designsN/dode.mtx \, bang; +#X msg 221 167 read Rls.mtx \, bang; +#X connect 0 0 15 0; +#X connect 1 0 0 0; +#X connect 1 1 15 1; +#X connect 3 0 4 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 7 0 17 0; +#X connect 9 0 34 1; +#X connect 10 0 34 2; +#X connect 11 0 34 3; +#X connect 12 0 36 0; +#X connect 13 0 8 0; +#X connect 14 0 34 0; +#X connect 15 0 24 0; +#X connect 16 0 2 1; +#X connect 17 0 14 0; +#X connect 18 0 21 0; +#X connect 19 0 11 0; +#X connect 19 0 35 0; +#X connect 20 0 19 1; +#X connect 21 0 19 0; +#X connect 22 0 8 0; +#X connect 23 0 32 0; +#X connect 24 0 23 0; +#X connect 24 1 29 0; +#X connect 25 0 26 0; +#X connect 26 0 2 0; +#X connect 27 0 26 1; +#X connect 28 0 30 0; +#X connect 29 0 16 0; +#X connect 30 0 12 0; +#X connect 30 1 25 0; +#X connect 30 2 27 0; +#X connect 30 3 29 0; +#X connect 31 0 27 0; +#X connect 31 0 33 0; +#X connect 32 0 25 0; +#X connect 32 1 31 0; +#X connect 33 0 28 0; +#X connect 34 0 8 0; +#X connect 35 0 20 0; +#X connect 36 0 22 0; +#X connect 36 1 8 0; +#X connect 37 0 32 0; +#X connect 38 0 44 0; +#X connect 38 1 29 0; +#X connect 39 0 42 0; +#X connect 40 0 42 0; +#X connect 41 0 42 0; +#X connect 42 0 43 0; +#X connect 43 0 47 0; +#X connect 44 0 37 0; +#X connect 44 1 56 0; +#X connect 45 0 46 0; +#X connect 46 0 43 0; +#X connect 46 1 44 1; +#X connect 47 0 12 0; +#X connect 47 1 38 0; +#X connect 48 0 42 0; +#X connect 49 0 42 0; +#X connect 50 0 42 0; +#X connect 51 0 42 0; +#X connect 52 0 53 0; +#X connect 53 0 43 0; +#X connect 53 1 56 0; +#X connect 54 0 43 0; +#X connect 55 0 54 0; +#X connect 56 0 32 0; +#X connect 57 0 43 0; +#X connect 58 0 43 0; diff --git a/src/mtx_qhull/vectors.c b/src/mtx_qhull/vectors.c new file mode 100644 index 0000000..909543e --- /dev/null +++ b/src/mtx_qhull/vectors.c @@ -0,0 +1,126 @@ + +vector_t initVector (float x, float y, float z) { + vector_t vec={x, y, z}; + return vec; +} + +vector_t normalizeVector(vector_t v) { + float r=sqrtf(v.c[0]*v.c[0]+v.c[1]*v.c[1]+v.c[2]*v.c[2]); + v.c[0]/=r; + v.c[1]/=r; + v.c[2]/=r; + return v; +}; + +plane_t initPlane (vector_t normal, vector_t point) { + plane_t plane; + plane.point = point; + plane.normal = normalizeVector(normal); + return plane; +} + +points_t initPoints (const float *x, + const float *y, const float *z, + size_t num_points) { + points_t points; + size_t i; + + points.v = (vector_t*) malloc (sizeof(vector_t)*num_points); + if (points.v!=0) { +// printf("created %li\n",points.v); + points.num_points = num_points; + for (i=0; iv); + if (points!=0) { + if (points->v!=0) + free(points->v); + points->v = 0; + points->num_points = 0; + } +} + +vector_t crossProduct (vector_t v1, vector_t v2) { + vector_t cp; + cp.c[0]= v1.c[1]*v2.c[2]-v1.c[2]*v2.c[1]; + cp.c[1]=-v1.c[0]*v2.c[2]+v1.c[2]*v2.c[0]; + cp.c[2]= v1.c[0]*v2.c[1]-v1.c[1]*v2.c[0]; + return cp; +} + +float innerProduct (vector_t v1, vector_t v2) { + return v1.c[0]*v2.c[0] + v1.c[1]*v2.c[1] + v1.c[2]*v2.c[2]; +} + +float distancePointPlane (vector_t point, plane_t plane) { + return innerProduct(point, plane.normal) - + innerProduct(plane.point, plane.normal); +} + +vector_t addVectors(vector_t v1, vector_t v2) { + vector_t v3; + v3.c[0]=v1.c[0]+v2.c[0]; + v3.c[1]=v1.c[1]+v2.c[1]; + v3.c[2]=v1.c[2]+v2.c[2]; + return v3; +} + +vector_t subtractVectors(vector_t v1, vector_t v2) { + vector_t v3; + v3.c[0]=v1.c[0]-v2.c[0]; + v3.c[1]=v1.c[1]-v2.c[1]; + v3.c[2]=v1.c[2]-v2.c[2]; + return v3; +} + +vector_t scaleVector(vector_t v1, float f) { + vector_t v2; + v2.c[0]=f*v1.c[0]; + v2.c[1]=f*v1.c[1]; + v2.c[2]=f*v1.c[2]; + return v2; +} + +vector_t averagePoints(points_t points) { + vector_t m = initVector(0.0f, 0.0f, 0.0f); + size_t i; + for (i=0; icorners); + printList(facet->outsideset); + printList(facet->insideset); + printList(facet->neighbors);*/ + freeList(&(facet->corners)); + freeList(&(facet->outsideset)); + freeList(&(facet->insideset)); + freeList(&(facet->neighbors)); +} + +list_t appendNewFacets(zhull_t * const zh, const size_t num_facets) { + facet_t *new_facet; + list_t new_facets=initConstantList(0,num_facets); + index_t i; + for (i=0; ineighbors=emptyList(); + new_facet->corners=emptyList(); + new_facet->outsideset=emptyList(); + new_facet->insideset=emptyList(); + new_facet->maxdistance=0; + new_facet->farthest_outside_point=0; +// printf("%li, %li\n", new_facet, (entry_t)new_facet); + setEntry(new_facets,i,(entry_t)new_facet); +// printf("created facet %li\n",new_facet); + } + appendListToList(&(zh->facets),new_facets); + return new_facets; +} + +/* facets, interface */ +/*entry_t getFacetCornerByIndex(const facet_t *facet, + index_t index_corner) { + if (facet!=0) + return getEntry(facet->corners, + index_corner%getLength(facet->corners)); + else + return 0; + } + */ + +facet_t *getFacetByIndex(const list_t facets, + const index_t index) { + return (facet_t*) getEntry(facets,index); +} + +facet_t *getFacetByPointer(const entry_t ptr) { + return (facet_t*) ptr; +} + +void getHorizonEdgeByIndex(index_t *corners, + const list_t horizon_fcts, const list_t horizon_fcts_edges, + const index_t index) { + index_t i=(index+getLength(horizon_fcts_edges)) + %getLength(horizon_fcts_edges); + facet_t *f = getFacetByIndex(horizon_fcts,i); + index_t j=getEntry(horizon_fcts_edges,i); + + corners[0]=getEntry(f->corners, j); + if (getLength(f->corners)>0) + corners[1]=getEntry(f->corners, (j+1) % getLength(f->corners)); + else + corners[1]=corners[0]; +} + + +void removeFacetByPointer(zhull_t * const zh, + facet_t * const pointer) { + removeValueFromList(&(zh->facets), (entry_t)pointer); + removeValueFromList(&(zh->facets_with_outsidepoints), + (entry_t)pointer); + removeValueFromList(&(zh->facets_with_insidepoints), + (entry_t)pointer); + freeFacet((facet_t*)pointer); +} + +void removeFacetByPointerList(zhull_t * const zh, + const list_t pointers) { + index_t i; + for (i=0; ifacets, index)); +} + +void removeFacetByIndexList(zhull_t * const zh, + const list_t indices) { + facet_t *f; + index_t i; + for (i=0; ifacets, getEntry(indices,i)); + removeFacetByPointer(zh,f); + } +} + + +void freeFacets(zhull_t * const zh) { + int i; + facet_t *f; + if (getLength(zh->facets)>0) { + for (i=0; ifacets); i++) { + f=getFacetByIndex(zh->facets,i); +// printf("deleting facet %li\n",i); + freeFacet(f); + } + freeList(&(zh->facets)); + } +} + +void freeZhull(zhull_t *zh) { + if (zh!=0) { +// printf("free zhull\n"); + freeFacets(zh); + freeList(&(zh->facets_with_insidepoints)); + freeList(&(zh->facets_with_outsidepoints)); + freePoints(&(zh->pts)); + } +} + + +// *********************************** +// +// interface + + +vector_t getPoint(const zhull_t * const zh, + const index_t index) { + return (vector_t) zh->pts.v[index]; +} + +zhull_t zhullInitPoints(const float *x, const float *y, + const float *z, const size_t num_points) { + zhull_t zh; + zh.pts=initPoints(x,y,z,num_points); + zh.facets=emptyList(); + zh.facets_with_outsidepoints=emptyList(); + zh.facets_with_insidepoints=emptyList(); + return zh; +} + + + +void dividePointsBetweenNewFacets ( + zhull_t * const zh, const list_t assoc, + const list_t new_facets, const list_t horizon_fcts) { + index_t i,j; + list_t new_and_horizon_fcts=mergeLists(new_facets,horizon_fcts); + printList(new_and_horizon_fcts); + uniquefyListEntries(&new_and_horizon_fcts); + printList(new_and_horizon_fcts); + float d; + for (i=0; iplane); + // printf("distance %5.2f to %d\n",d,findValueInList((entry_t)getFacetByIndex(new_and_horizon_fcts,j),zh->facets)); + /* + if ((d>=-TOL) && (d<=TOL)) { + appendToList(&(getFacetByIndex(new_facets,j)->insideset), + getEntry(assoc,i)); + if (notInList(getEntry(new_facets,j),zh->facets_with_insidepoints)) + appendToList(&(zh->facets_with_insidepoints), + getEntry(new_facets,j)); + break; + } + else */ + if (d>=-TOL) { + appendToList(&(getFacetByIndex(new_and_horizon_fcts,j)->outsideset), + getEntry(assoc,i)); + // printf("appended "); + if (notInList(getEntry(new_and_horizon_fcts,j),zh->facets_with_outsidepoints)) + appendToList(&(zh->facets_with_outsidepoints),getEntry(new_and_horizon_fcts,j)); + if (getFacetByIndex(new_and_horizon_fcts,j)->maxdistancemaxdistance=d; + getFacetByIndex(new_and_horizon_fcts,j)->farthest_outside_point=getEntry(assoc,i); + } + break; + } + } + } +} + +void zhullInitialFacets(zhull_t *zh) { + list_t assoc = emptyList(); + list_t new_facets = emptyList(); + index_t i; + if (zh->pts.num_points >= 3) { + assoc = initListFromTo(0,zh->pts.num_points-1); + new_facets = appendNewFacets(zh,2); + if (getLength(new_facets)==2) { + getFacetByIndex(new_facets,0)->corners = initListFromTo(0,2); + getFacetByIndex(new_facets,1)->corners = initListFromTo(2,0); + getFacetByIndex(new_facets,0)->neighbors = + initConstantList((entry_t)getFacetByIndex(new_facets,1),3); + getFacetByIndex(new_facets,1)->neighbors = + initConstantList((entry_t)getFacetByIndex(new_facets,0),3); + for (i=0; i<2; i++) { + getFacetByIndex(new_facets,i)->plane = + planeFromListedPoints(zh->pts, getFacetByIndex(new_facets,i)->corners); + getFacetByIndex(new_facets,i)->outsideset = emptyList(); + getFacetByIndex(new_facets,i)->insideset = emptyList(); + getFacetByIndex(new_facets,i)->maxdistance = 0.0f; + removeValueListFromList(&assoc,getFacetByIndex(new_facets,i)->corners); + } + dividePointsBetweenNewFacets(zh, assoc, new_facets, emptyList()); + } + freeList(&new_facets); + freeList(&assoc); + } +} + +void printHorizonEdges(list_t *horizon_fcts, + list_t *horizon_fcts_edges) { + index_t i; + index_t c1[2]; + + printf("horizon edges: "); + for (i=0; i%d",c1[0],c1[1]); + } + printf("\n"); +} + + +void sortHorizonEdges(list_t *horizon_fcts, + list_t *horizon_fcts_edges) { + index_t i,j; + facet_t *fi; + index_t ei; + index_t c1[2]; + index_t c2[2]; + + if (getLength(*horizon_fcts_edges)==0) + return; + for (i=0; ioutsideset); + appendListToList(avail_points, f->insideset); + for (j=0; jneighbors); j++) { + n=getFacetByIndex(f->neighbors,j); + if (notInList((entry_t) n, visible_fcts)) { + d=distancePointPlane(getPoint(zh,point_index), + n->plane); + if (d>-TOL) { + if (notInList((entry_t)n,visible_fcts)) + appendToList(&visible_fcts,(entry_t)n); + } + else { + appendToList(horizon_fcts,(entry_t)n); + k=getEntry(f->corners,(j+1)%getLength(f->corners)); + // printf("searching for corner with %d in\n",k); + // printList(n->corners); + k=findValueInList(k,n->corners); + // printf("found %d\n",k); + appendToList(horizon_fcts_edges,k); + } + } + } + } + printf("removing facets"); + indices_for_printing=findValueListInList(visible_fcts, zh->facets); + printList(indices_for_printing); + removeFacetByPointerList(zh,visible_fcts); + freeList(&visible_fcts); + // printHorizonEdges(horizon_fcts, horizon_fcts_edges); + sortHorizonEdges(horizon_fcts, horizon_fcts_edges); + printHorizonEdges(horizon_fcts, horizon_fcts_edges); +} + + +void initNewFacets(zhull_t *zh, int point_index, + list_t new_facets, list_t horizon_fcts, + list_t horizon_fcts_edges) { + index_t i,j; + entry_t array[3]; + + array[0]=point_index; + for (i=0; icorners=initList(array,3); + // printList(getFacetByIndex(new_facets,i)->corners); + + // neighbors + // previous new neighbor + j=(getLength(horizon_fcts)+i-1) % getLength(horizon_fcts); + array[1]=getEntry(new_facets,j); + // next new neighbor + j=(i+1) % getLength(horizon_fcts); + array[2]=getEntry(new_facets,j); + // old neighbor + array[0]=getEntry(horizon_fcts,i); + getFacetByIndex(new_facets,i)->neighbors= + initList(array,3); + + // registering at old neighbor: + setEntry(getFacetByIndex(horizon_fcts,i)->neighbors, + getEntry(horizon_fcts_edges,i), getEntry(new_facets,i)); + + // initializing normal vectors and lists + getFacetByIndex(new_facets,i)->plane = + planeFromListedPoints(zh->pts, + getFacetByIndex(new_facets,i)->corners); + } +} + +void makePyramidFacetsToHorizon(zhull_t *zh, index_t point_index, + list_t horizon_fcts, list_t horizon_fcts_edges, + list_t avail_points) { + list_t new_facets = appendNewFacets(zh, getLength(horizon_fcts_edges)); + initNewFacets(zh,point_index,new_facets,horizon_fcts,horizon_fcts_edges); + // printf("available points: "); + // printList(avail_points); + // printf("new facets : "); + // printList(new_facets); + dividePointsBetweenNewFacets(zh, avail_points, new_facets, horizon_fcts); + freeList(&new_facets); +} + +void calculateZHull(zhull_t *zh,int maxit) { + index_t fli=0; + index_t pi; + facet_t *f; + list_t outsideset; + int cnt=0; + list_t horizon_fcts=emptyList(); + list_t horizon_fcts_edges=emptyList(); + list_t available_points=emptyList(); + if (maxit>MAXIT) + maxit=MAXIT; + if (zh->pts.num_points!=0){ + zhullInitialFacets(zh); + printZhull(zh); + while((getLength(zh->facets_with_outsidepoints)>0)&&(cnt++facets_with_outsidepoints); + f=getFacetByIndex(zh->facets_with_outsidepoints,fli); + pi=f->farthest_outside_point; + removeVisibleFacetsGetHorizonAndAvailablePoints(zh,pi,f, + &horizon_fcts, &horizon_fcts_edges, + &available_points); + removeValueFromList(&available_points, pi); + makePyramidFacetsToHorizon(zh,pi,horizon_fcts,horizon_fcts_edges, + available_points); + printZhull(zh); + + freeList(&horizon_fcts); + freeList(&horizon_fcts_edges); + freeList(&available_points); + fli++; + } + } +} + +void printZhull(const zhull_t * const zh) { + index_t fi; + list_t indices = emptyList(); + printf("zhull from %d points\n", zh->pts.num_points); + printf("facets with outsidepoints: "); + indices=findValueListInList(zh->facets_with_outsidepoints,zh->facets); + printList(indices); + freeList(&indices); +// printf("facets with insidepoints: "); +// printList(zh->facets_with_insidepoints); + printf("zhull has %d facets\n", getLength(zh->facets)); + for (fi=0; fifacets); fi++) { + printf("facet %d<%d>: ",fi,getFacetByIndex(zh->facets,fi)); + printFacet(zh,getFacetByIndex(zh->facets,fi)); + } +} + +void printFacet(const zhull_t * const zh, + const facet_t * const f) { + list_t indices=emptyList(); + indices=findValueListInList(f->neighbors,zh->facets); + printf("plane: "); + printPlane(f->plane); + printf("\n"); + printf("corners: "); + printList(f->corners); + printf("outsideset: "); + printList(f->outsideset); + printf("insideset: "); + printList(f->insideset); + printf("neighbors: "); + printList(indices); + freeList(&indices); + printf("pt %d with maxdist %5.2f\n",f->farthest_outside_point, f->maxdistance); +} + diff --git a/src/mtx_qhull/zhull.h b/src/mtx_qhull/zhull.h new file mode 100644 index 0000000..dd520e1 --- /dev/null +++ b/src/mtx_qhull/zhull.h @@ -0,0 +1,25 @@ + +typedef struct facet_ { + plane_t plane; + list_t corners; + list_t outsideset; + list_t insideset; + size_t farthest_outside_point; + list_t neighbors; + float maxdistance; +} facet_t; + +typedef struct zhull_ { + points_t pts; + list_t facets; + list_t facets_with_outsidepoints; + list_t facets_with_insidepoints; +} zhull_t; + +void calculateZHull(zhull_t *zh,int maxit); +void printZhull(const zhull_t * const zh); +void freeZhull(zhull_t *zh); +zhull_t zhullInitPoints(const float *x, const float *y, + const float *z, const size_t num_points); +void printFacet(const zhull_t * const zh, + const facet_t * const f); -- cgit v1.2.1