From db10df9787c56986c3d6bbbaa635a71c9deca8ba Mon Sep 17 00:00:00 2001 From: chr Date: Wed, 27 May 2015 02:27:36 +0000 Subject: [PATCH] Added volume / surface area routines. git-svn-id: https://codeforge.lbl.gov/anonscm/voro@584 6221c96e-593b-4ce1-a500-64c4038a1943 --- trunk/src/cell.cc | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ trunk/src/cell.hh | 4 ++ 2 files changed, 119 insertions(+) diff --git a/trunk/src/cell.cc b/trunk/src/cell.cc index d0340fa..dfa3d92 100644 --- a/trunk/src/cell.cc +++ b/trunk/src/cell.cc @@ -1610,6 +1610,121 @@ double voronoicell_base::volume() { return vol*fe; } +/** Calculates the contributions to the Minkowski functionals for this Voronoi cell. + * \param[in] r the radius to consider. + * \param[out] ar the area functional. + * \param[out] vo the volume functional. */ +void voronoicell_base::minkowski(double r,double &ar,double &vo) { + int i,j,k,l,m,n; + ar=vo=0; + for(i=1;i=0) { + ed[i][j]=-1-k; + l=cycle_up(ed[i][nu[i]+j],k); + m=ed[k][l];ed[k][l]=-1-m; + while(m!=i) { + n=cycle_up(ed[k][nu[k]+l],m); + minkowski_contrib(i,k,m,r,ar,vo); + k=m;l=n; + m=ed[k][l];ed[k][l]=-1-m; + } + } + } + vo*=0.125; + ar*=0.25; + reset_edges(); +} + +inline void voronoicell_base::minkowski_contrib(int i,int k,int m,double r,double &ar,double &vo) { + double ix=pts[4*i],iy=pts[4*i+1],iz=pts[4*i+2], + kx=pts[4*k],ky=pts[4*k+1],kz=pts[4*k+2], + mx=pts[4*m],my=pts[4*m+1],mz=pts[4*m+2], + ux=kx-ix,uy=ky-iy,uz=kz-iz,vx=mx-kx,vy=my-ky,vz=mz-kz, + e1x=uz*vy-uy*vz,e1y=ux*vz-uz*vx,e1z=uy*vx-ux*vy,e2x,e2y,e2z, + wmag=e1x*e1x+e1y*e1y+e1z*e1z; + if(wmag0.5) { + e2x=-e1y;e2y=e1x;e2z=0; + } else if(fabs(e1y)>0.5) { + e2x=0;e2y=-e1z;e2z=e1y; + } else { + e2x=e1z;e2y=0;e2z=-e1x; + } + wmag=1/sqrt(e2x*e2x+e2y*e2y+e2z*e2z); + e2x*=wmag;e2y*=wmag;e2z*=wmag; + + // Compute third orthonormal vector + double e3x=e1z*e2y-e1y*e2z, + e3y=e1x*e2z-e1z*e2x, + e3z=e1y*e2x-e1x*e2y, + x0=e1x*ix+e1y*iy+e1z*iz; + if(x0 &v); void output_vertices(double x,double y,double z,FILE *fp=stdout); void face_areas(std::vector &v); + void minkowski(double r,double &ar,double &vo); /** Outputs the areas of the faces. * \param[in] fp the file handle to write to. */ inline void output_face_areas(FILE *fp=stdout) { @@ -292,6 +293,9 @@ class voronoicell_base { bool definite_max(int &lp,int &ls,double &l,double &u,unsigned int &uw); inline bool search_upward(unsigned int &lw,int &lp,int &ls,int &us,double &l,double &u); bool definite_min(int &lp,int &us,double &l,double &u,unsigned int &lw); + inline void minkowski_contrib(int i,int k,int m,double r,double &ar,double &vo); + void minkowski_edge(double x0,double r1,double s1,double r2,double s2,double r,double &ar,double &vo); + void minkowski_formula(double x0,double y0,double z0,double r,double &ar,double &vo); inline bool plane_intersects_track(double x,double y,double z,double rs,double g); inline void normals_search(std::vector &v,int i,int j,int k); inline bool search_edge(int l,int &m,int &k); -- 2.11.4.GIT