Doxygen Source Code Documentation
cs_qhull.c File Reference
#include "cs.h"
Go to the source code of this file.
Defines | |
#define | SCL(a, b, c) 1.0/sqrt(a*a+b*b+c*c) |
#define | xVV xcc |
#define | yVV ycc |
#define | zVV zcc |
#define | ANG(u1, u2, u3, v1, v2, v3) acos(u1*v1+u2*v2+u3*v3) |
#define | SS(a, b, c) ((a+b+c)/2) |
#define | ATR(s, a, b, c) (4*atan(sqrt(tan(s/2)*tan((s-a)/2)*tan((s-b)/2)*tan((s-c)/2)))) |
Functions | |
int | qhull_wrap (int npt, float *xyz, int **ijk) |
int | sphere_voronoi_angles (int npt, float *pol, float *azi, float **wt) |
int | sphere_voronoi_vectors (int npt, float *xyz, float **wt) |
Define Documentation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Function Documentation
|
Definition at line 31 of file cs_qhull.c. References close(), fd, fdopen(), free, malloc, pclose, and popen. Referenced by sphere_voronoi_vectors().
00032 { 00033 int ii,jj , nfac , *fac ; 00034 int fd ; FILE *fp ; 00035 char qbuf[128] ; 00036 00037 #ifndef DONT_USE_MKSTEMP 00038 char fname[] = "/tmp/afniXXXXXX" ; 00039 #else 00040 char *fname ; 00041 #endif 00042 00043 if( npt < 3 || xyz == NULL || ijk == NULL ){ 00044 fprintf(stderr,"qhull_wrap: bad inputs\n") ; 00045 return 0 ; 00046 } 00047 00048 #ifndef DONT_USE_MKSTEMP 00049 fd = mkstemp( fname ) ; 00050 if( fd == -1 ){ fprintf(stderr,"qhull_wrap: mkstemp fails\n"); return 0; } 00051 fp = fdopen( fd , "w" ) ; 00052 if( fp == NULL ){ fprintf(stderr,"qhull_wrap: fdopen fails\n"); close(fd); return 0; } 00053 #else 00054 fname = tmpnam(NULL) ; 00055 if( fname == NULL ){ fprintf(stderr,"qhull_wrap: tmpnam fails\n"); return 0; } 00056 fp = fopen( fname , "w" ) ; 00057 if( fp == NULL ){ fprintf(stderr,"qhull_wrap: fopen fails\n"); return 0; } 00058 #endif 00059 00060 fprintf(fp,"3\n%d\n",npt) ; 00061 for( ii=0 ; ii < npt ; ii++ ) 00062 fprintf(fp,"%g %g %g\n",xyz[3*ii],xyz[3*ii+1],xyz[3*ii+2]) ; 00063 00064 fclose(fp) ; 00065 00066 sprintf(qbuf,"qhull -i -Pp < %s",fname) ; 00067 fp = popen( qbuf , "r" ) ; 00068 if( fp == NULL ){ fprintf(stderr,"qhull_wrap: popen fails\n"); remove(fname); return 0; } 00069 00070 jj = fscanf(fp,"%d",&nfac) ; 00071 if( jj != 1 || nfac < 1 ){ fprintf(stderr,"qhull_wrap: 1st fscanf fails\n"); pclose(fp); remove(fname); return 0; } 00072 00073 fac = (int *) malloc( sizeof(int)*3*nfac ) ; 00074 if( fac == NULL ){ fprintf(stderr,"qhull_wrap: malloc fails\n"); pclose(fp); remove(fname); return 0; } 00075 00076 for( ii=0 ; ii < nfac ; ii++ ){ 00077 jj = fscanf(fp,"%d %d %d",fac+(3*ii),fac+(3*ii+1),fac+(3*ii+2)) ; 00078 if( jj < 3 ){ 00079 fprintf(stderr,"qhull_wrap: fscanf fails at ii=%d\n",ii) ; 00080 pclose(fp); remove(fname); free(fac); return 0; 00081 } 00082 } 00083 00084 pclose(fp); remove(fname); 00085 00086 *ijk = fac ; return nfac ; 00087 } |
|
Definition at line 101 of file cs_qhull.c. References free, malloc, and sphere_voronoi_vectors().
00102 { 00103 float *xyz ; 00104 double cp,sp,ca,sa ; 00105 int ii ; 00106 00107 if( npt < 3 || pol == NULL || azi == NULL || wt == NULL ){ 00108 fprintf(stderr,"sphere_voronoi_angles: bad inputs\n"); return 0; 00109 } 00110 00111 /* make 3-vectors of the points on the sphere */ 00112 00113 xyz = (float *) malloc( sizeof(float) * (3*npt) ) ; 00114 00115 for( ii=0 ; ii < npt ; ii++ ){ 00116 cp = cos(pol[ii]) ; sp = sin(pol[ii]) ; 00117 ca = cos(azi[ii]) ; sa = sin(azi[ii]) ; 00118 xyz[3*ii] = sp * ca ; 00119 xyz[3*ii+1] = sp * sa ; 00120 xyz[3*ii+2] = cp ; 00121 } 00122 00123 ii = sphere_voronoi_vectors( npt , xyz , wt ) ; 00124 free(xyz) ; return ii ; 00125 } |
|
Definition at line 134 of file cs_qhull.c. References free, malloc, and qhull_wrap(). Referenced by sphere_voronoi_angles().
00135 { 00136 int ntri , *tri , ii,jj , pp,qq,rr ; 00137 float *ww ; 00138 double cp,sp,ca,sa ; 00139 double xpq,ypq,zpq , xpr,ypr,zpr , xqr,yqr,zqr , xcc,ycc,zcc ; 00140 double xpp,ypp,zpp , xqq,yqq,zqq , xrr,yrr,zrr , xnn,ynn,znn ; 00141 double pp_pq , pp_pr , pp_cc , 00142 qq_pq , qq_qr , qq_cc , 00143 rr_qr , rr_cc , rr_pr , 00144 pq_cc , qr_cc , pr_cc , ss ; 00145 double a_pp_pq_cc , a_pp_pr_cc , 00146 a_qq_pq_cc , a_qq_qr_cc , 00147 a_rr_qr_cc , a_rr_pr_cc ; 00148 00149 if( npt < 3 || xyz == NULL || wt == NULL ){ 00150 fprintf(stderr,"sphere_voronoi: bad inputs\n"); return 0; 00151 } 00152 00153 /* compute convex hull triangular facets */ 00154 00155 ntri = qhull_wrap( npt , xyz , &tri ) ; 00156 if( ntri == 0 ){ fprintf(stderr,"sphere_voronoi: qhull_wrap fails\n"); free(xyz); return 0; } 00157 00158 /* initialize output */ 00159 00160 ww = (float *) malloc( sizeof(float) * npt ) ; 00161 for( ii=0 ; ii < npt ; ii++ ) ww[ii] = 0.0 ; 00162 00163 for( jj=0 ; jj < ntri ; jj++ ){ /* loop over triangles */ 00164 00165 00166 /* triangle vertices pp,qq,rr * pp 00167 / \ 00168 / \ 00169 pq * * pr 00170 / * \ 00171 / cc \ 00172 qq *-----------* rr */ 00173 00174 pp = tri[3*jj ] ; 00175 xpp = xyz[3*pp ] ; ypp = xyz[3*pp+1] ; zpp = xyz[3*pp+2] ; 00176 qq = tri[3*jj+1] ; 00177 xqq = xyz[3*qq ] ; yqq = xyz[3*qq+1] ; zqq = xyz[3*qq+2] ; 00178 rr = tri[3*jj+2] ; 00179 xrr = xyz[3*rr ] ; yrr = xyz[3*rr+1] ; zrr = xyz[3*rr+2] ; 00180 00181 /* midpoints pq,pr,qr, and centroid cc */ 00182 /*** Q: should centroid be replaced by normal? 00183 what about orientation, largeness? ***/ 00184 00185 xpq = 0.5*(xpp+xqq) ; ypq = 0.5*(ypp+yqq) ; zpq = 0.5*(zpp+zqq) ; 00186 xpr = 0.5*(xpp+xrr) ; ypr = 0.5*(ypp+yrr) ; zpr = 0.5*(zpp+zrr) ; 00187 xqr = 0.5*(xqq+xrr) ; yqr = 0.5*(yqq+yrr) ; zqr = 0.5*(zqq+zrr) ; 00188 00189 xcc = 0.3333333*(xpp+xqq+xrr) ; 00190 ycc = 0.3333333*(ypp+yqq+yrr) ; 00191 zcc = 0.3333333*(zpp+zqq+zrr) ; 00192 00193 #undef SCL 00194 #define SCL(a,b,c) 1.0/sqrt(a*a+b*b+c*c) 00195 00196 #undef USE_NORMAL 00197 #ifdef USE_NORMAL 00198 # define XCROSS(a,b,c,x,y,z) ((b)*(z)-(c)*(y)) 00199 # define YCROSS(a,b,c,x,y,z) ((c)*(x)-(a)*(z)) 00200 # define ZCROSS(a,b,c,x,y,z) ((a)*(y)-(b)*(x)) 00201 { double apq=xpp-xqq , bpq=ypp-yqq , cpq=zpp-zqq , 00202 aqr=xqq-xrr , bqr=yqq-yrr , cqr=zqq-zrr ; 00203 00204 xnn = XCROSS(apq,bpq,cpq,aqr,bqr,cqr) , 00205 ynn = YCROSS(apq,bpq,cpq,aqr,bqr,cqr) , 00206 znn = ZCROSS(apq,bpq,cpq,aqr,bqr,cqr) ; 00207 00208 cp = SCL(xnn,ynn,znn) ; xnn *= cp ; ynn *= cp ; znn *= cp ; 00209 if( xnn*xcc + ynn*ycc + znn*zcc < 0 ){ 00210 xnn = -xnn ; ynn = -ynn ; znn = -znn ; 00211 } 00212 } 00213 00214 # define xVV xnn 00215 # define yVV ynn 00216 # define zVV znn 00217 00218 #else 00219 00220 # define xVV xcc 00221 # define yVV ycc 00222 # define zVV zcc 00223 00224 #endif 00225 00226 /* project pq,pr,qr,cc to sphere (nn is already on sphere) */ 00227 00228 cp = SCL(xpq,ypq,zpq) ; xpq *= cp ; ypq *= cp ; zpq *= cp ; 00229 cp = SCL(xpr,ypr,zpr) ; xpr *= cp ; ypr *= cp ; zpr *= cp ; 00230 cp = SCL(xqr,yqr,zqr) ; xqr *= cp ; yqr *= cp ; zqr *= cp ; 00231 cp = SCL(xcc,ycc,zcc) ; xcc *= cp ; ycc *= cp ; zcc *= cp ; 00232 00233 #undef ANG 00234 #define ANG(u1,u2,u3,v1,v2,v3) acos(u1*v1+u2*v2+u3*v3) 00235 00236 /* compute distance on surface between points: 00237 aa_bb = between points aa and bb, from the picture above */ 00238 00239 pp_pq = ANG( xpp,ypp,zpp , xpq,ypq,zpq ) ; 00240 pp_cc = ANG( xpp,ypp,zpp , xVV,yVV,zVV ) ; 00241 pp_pr = ANG( xpp,ypp,zpp , xpr,ypr,zpr ) ; 00242 00243 qq_pq = ANG( xqq,yqq,zqq , xpq,ypq,zpq ) ; 00244 qq_qr = ANG( xqq,yqq,zqq , xqr,yqr,zqr ) ; 00245 qq_cc = ANG( xqq,yqq,zqq , xVV,yVV,zVV ) ; 00246 00247 rr_qr = ANG( xrr,yrr,zrr , xqr,yqr,zqr ) ; 00248 rr_pr = ANG( xrr,yrr,zrr , xpr,ypr,zpr ) ; 00249 rr_cc = ANG( xrr,yrr,zrr , xVV,yVV,zVV ) ; 00250 00251 pq_cc = ANG( xpq,ypq,zpq , xVV,yVV,zVV ) ; 00252 qr_cc = ANG( xqr,yqr,zqr , xVV,yVV,zVV ) ; 00253 pr_cc = ANG( xpr,ypr,zpr , xVV,yVV,zVV ) ; 00254 00255 /* for each vertex, 00256 compute areas of 2 subtriangles it touches, 00257 add these into the area weight for that vertex */ 00258 00259 #undef SS 00260 #define SS(a,b,c) ((a+b+c)/2) 00261 #undef ATR 00262 #define ATR(s,a,b,c) (4*atan(sqrt(tan(s/2)*tan((s-a)/2)*tan((s-b)/2)*tan((s-c)/2)))) 00263 00264 ss = SS(pp_pq,pp_cc,pq_cc) ; /* subtriangle pp,pq,cc */ 00265 ww[pp] += a_pp_pq_cc = ATR(ss,pp_pq,pp_cc,pq_cc) ; 00266 00267 ss = SS(pp_pr,pp_cc,pr_cc) ; /* subtriangle pp,pr,cc */ 00268 ww[pp] += a_pp_pr_cc = ATR(ss,pp_pr,pp_cc,pr_cc) ; 00269 00270 ss = SS(qq_pq,qq_cc,pq_cc) ; /* subtriangle qq,pq,cc */ 00271 ww[qq] += a_qq_pq_cc = ATR(ss,qq_pq,qq_cc,pq_cc) ; 00272 00273 ss = SS(qq_qr,qq_cc,qr_cc) ; /* subtriangle qq,qr,cc */ 00274 ww[qq] += a_qq_qr_cc = ATR(ss,qq_qr,qq_cc,qr_cc) ; 00275 00276 ss = SS(rr_qr,rr_cc,qr_cc) ; /* subtriangle rr,qr,cc */ 00277 ww[rr] += a_rr_qr_cc = ATR(ss,rr_qr,rr_cc,qr_cc) ; 00278 00279 ss = SS(rr_pr,rr_cc,pr_cc) ; /* subtriangle rr,pr,cc */ 00280 ww[rr] += a_rr_pr_cc = ATR(ss,rr_pr,rr_cc,pr_cc) ; 00281 00282 00283 #if 0 /* debugging printouts */ 00284 # undef DDD 00285 # define DDD(x,y,z,a,b,c) sqrt((x-a)*(x-a)+(y-b)*(y-b)+(z-c)*(z-c)) 00286 00287 cp = DDD(xpp,ypp,zpp,xqq,yqq,zqq) ; 00288 sp = DDD(xpp,ypp,zpp,xrr,yrr,zrr) ; 00289 ca = DDD(xqq,yqq,zqq,xrr,yrr,zrr) ; 00290 sa = (cp+sp+ca)/2 ; 00291 ss = sqrt(sa*(sa-cp)*(sa-sp)*(sa-ca)) ; 00292 00293 fprintf(stderr,"triangle %d: pp=%d qq=%d rr=%d AREA=%6.3f PLANAR=%6.3f\n" 00294 " xpp=%6.3f ypp=%6.3f zpp=%6.3f\n" 00295 " xqq=%6.3f yqq=%6.3f zqq=%6.3f\n" 00296 " xrr=%6.3f yrr=%6.3f zrr=%6.3f\n" 00297 " xpq=%6.3f ypq=%6.3f zpq=%6.3f\n" 00298 " xqr=%6.3f yqr=%6.3f zqr=%6.3f\n" 00299 " xpr=%6.3f ypr=%6.3f zpr=%6.3f\n" 00300 " xcc=%6.3f ycc=%6.3f zcc=%6.3f\n" 00301 #ifdef USE_NORMAL 00302 " xnn=%6.3f ynn=%6.3f znn=%6.3f\n" 00303 #endif 00304 " pp_pq=%6.3f pp_pr=%6.3f pp_cc=%6.3f\n" 00305 " qq_pq=%6.3f qq_qr=%6.3f qq_cc=%6.3f\n" 00306 " rr_qr=%6.3f rr_cc=%6.3f rr_pr=%6.3f\n" 00307 " pq_cc=%6.3f qr_cc=%6.3f pr_cc=%6.3f\n" 00308 " a_pp_pq_cc=%6.3f a_pp_pr_cc=%6.3f\n" 00309 " a_qq_pq_cc=%6.3f a_qq_qr_cc=%6.3f\n" 00310 " a_rr_qr_cc=%6.3f a_rr_pr_cc=%6.3f\n" , 00311 jj,pp,qq,rr , 00312 a_pp_pq_cc+a_pp_pr_cc+a_qq_pq_cc+a_qq_qr_cc+a_rr_qr_cc+a_rr_pr_cc , ss , 00313 xpp, ypp, zpp, 00314 xqq, yqq, zqq, 00315 xrr, yrr, zrr, 00316 xpq, ypq, zpq, 00317 xqr, yqr, zqr, 00318 xpr, ypr, zpr, 00319 xcc, ycc, zcc, 00320 #ifdef USE_NORMAL 00321 xnn, ynn, znn, 00322 #endif 00323 pp_pq, pp_pr, pp_cc, 00324 qq_pq, qq_qr, qq_cc, 00325 rr_qr, rr_cc, rr_pr, 00326 pq_cc, qr_cc, pr_cc, 00327 a_pp_pq_cc, a_pp_pr_cc, 00328 a_qq_pq_cc, a_qq_qr_cc, 00329 a_rr_qr_cc, a_rr_pr_cc ) ; 00330 #endif 00331 00332 } /* end of loop over triangles */ 00333 00334 /* exit stage left */ 00335 00336 *wt = ww ; return 1 ; 00337 } |