#include enum { batchsize=8 }; static double Ax[batchsize], Ay[batchsize], Az[batchsize]; static double Bx[batchsize], By[batchsize], Bz[batchsize]; static double Cx[batchsize], Cy[batchsize], Cz[batchsize]; static double Dx[batchsize], Dy[batchsize], Dz[batchsize]; /* def norm2(a): return a[0]*a[0]+a[1]*a[1]+a[2]*a[2] def norm(a): return np.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]) def cross_jit(a,b, c): c[0]=a[1]*b[2]-b[1]*a[2] c[1]=a[2]*b[0]-b[2]*a[0] c[2]=a[0]*b[1]-b[0]*a[1] def circum(A,B,C): # see Dubos et al., GMD 2015, appendix # the computation is stable, and valid whether a,b,c is clockwise or not b,c = B-A, C-A p1,p2 = cross(b,c), norm2(c)*b-norm2(b)*c p = A+.5*cross(p1,p2)/norm2(p1) return p/norm(p) */ static inline void circum_main(int N) { // Any decent compiler should vectorize this for(int i=0 ; ibatchsize) { circum_copyin(batchsize, ind, points); circum_main(batchsize); circum_copyout(batchsize, circ); ind += 3*batchsize; circ += 3*batchsize; N-=batchsize; } // finish the job circum_copyin(N, ind, points); circum_main(N); circum_copyout(N, circ); } static inline void fast_scale_vec(double scale, double * vec) { vec[0]*=scale; vec[1]*=scale; vec[2]*=scale; } /* def arc(a,b): return 2.*np.arcsin(.5*norm(a-b)) def area(a,b,c): # http://mathworld.wolfram.com/LHuiliersTheorem.html a,b,c = .25*arc(b,c), .25*arc(c,a), .25*arc(a,b) return 4.*arctan(sqrt(tan(a+b+c)*tan(a+b-c)*tan(b+c-a)*tan(a+c-b))) def barycenters_fast(regions_size, vert, points, vertices, weight): N = points.shape[0] bary = np.zeros((N,3)) i=0 # running index in vert1, vert2 for n in range(N): point = points[n,:] b = 0. for j in range(regions_size[n]): v1 = vertices[vert[i],:] i = i+1 v2 = vertices[vert[i],:] i = i+1 dA=area(point, v1, v2) bb = unit_vector(point+v1+v2) b = b + dA*bb*weight(bb) bary[n,:] = unit_vector(b) return bary */ static inline double arc4(double dx, double dy, double dz) // 1/4 geodesic length, as used in L'Huillier's formula { double dist; // printf("dx dy dz = %f %f %f\n", dx,dy,dz); dist=dx*dx+dy*dy+dz*dz; // printf("dist = %f\n", dist); dist=sqrt(dist); // printf("dist = %f\n", dist); dist = .5*asin(.5*dist); // printf("dist = %f\n", dist); return dist; } static inline double barycenters_fast_(int N, const long *degree, const long *ind, const double *point, const double *w_i, const double *vertex, const double *w_v, double *bary) { double A=0; // total area // loop over voronoi cells for(int cell=0; cell