Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_COMPUTE_VORONOI_H
00002 #define OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_UTIL_POLYMESH_COMPUTE_VORONOI_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_compute_delaunay2D.h>
00013 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_compute_dual.h>
00014 #include <OpenTissue/core/containers/mesh/polymesh/util/polymesh_valency.h>
00015
00016 #include <cmath>
00017 #include <stdexcept>
00018
00019
00020 namespace OpenTissue
00021 {
00022 namespace polymesh
00023 {
00024
00025
00031 struct voronoi_vertex_policy
00032 {
00033
00034 template<typename face_type, typename vector3_type>
00035 static void compute_position( face_type const & face, vector3_type & coord )
00036 {
00037 using std::fabs;
00038
00039 typedef typename face_type::mesh_type mesh_type;
00040 typedef typename mesh_type::math_types math_types;
00041 typedef typename math_types::vector3_type vector3_type;
00042 typedef typename math_types::real_type real_type;
00043 typedef typename math_types::value_traits value_traits;
00044
00045 typedef typename mesh_type::const_face_vertex_circulator circulator;
00046
00047 if(valency( face ) != 3 )
00048 throw std::logic_error( "voronoi_vertex_policy: only triangular faces are allowed" );
00049
00050
00051 circulator v(face);
00052 vector3_type x0 = v->m_coord;
00053 ++v;
00054 vector3_type x1 = v->m_coord;
00055 ++v;
00056 vector3_type x2 = v->m_coord;
00057
00058
00059 vector3_type e10 = x1 - x0;
00060 vector3_type e21 = x2 - x1;
00061
00062
00063 vector3_type p0 = (x1 + x0) / value_traits::two();
00064 vector3_type p1 = (x2 + x1) / value_traits::two();
00065
00066
00067 vector3_type d0( - e10(1), e10(0), value_traits::zero() );
00068 vector3_type d1( - e21(1), e21(0), value_traits::zero() );
00069
00070 if( fabs(d0(0)) > value_traits::zero() && fabs(d1(0)) > value_traits::zero())
00071 {
00072
00073 real_type a0 = d0(1)/d0(0);
00074 real_type a1 = d1(1)/d1(0);
00075
00076
00077 real_type b0 = p0(1) - a0*p0(0);
00078 real_type b1 = p1(1) - a1*p1(0);
00079
00080
00081 real_type x = (b1-b0)/(a0-a1);
00082 real_type y = a0*x+b0;
00083
00084 coord(0) = x;
00085 coord(1) = y;
00086 coord(2) = value_traits::zero();
00087 }
00088
00089 else if( fabs(d0(0)) > value_traits::zero())
00090 {
00091
00092
00093
00094 real_type a0 = d0(1)/d0(0);
00095
00096
00097 real_type b0 = p0(1) - a0*p0(0);
00098
00099
00100 real_type x = p1(0);
00101 real_type y = a0*x+b0;
00102
00103 coord(0) = x;
00104 coord(1) = y;
00105 coord(2) = value_traits::zero();
00106 }
00107
00108 else if( fabs(d1(0)) > value_traits::zero())
00109 {
00110
00111
00112
00113 real_type a1 = d1(1)/d1(0);
00114
00115
00116 real_type b1 = p1(1) - a1*p1(0);
00117
00118
00119 real_type x = p0(0);
00120 real_type y = a1*x+b1;
00121
00122 coord(0) = x;
00123 coord(1) = y;
00124 coord(2) = value_traits::zero();
00125
00126 }
00127 else
00128 {
00129 throw std::logic_error("voronoi_vertex_policy(): No common intersection point exist, giving up!");
00130 }
00131 }
00132
00133 template<typename face_type, typename vector3_type>
00134 static void compute_normal( face_type const & face, vector3_type & normal )
00135 {
00136 normal.clear();
00137 }
00138
00139 };
00140
00141
00142
00143
00144
00145
00157 template< typename point_container, typename mesh_type >
00158 void compute_voronoi(point_container const & sites, mesh_type & mesh, mesh_type & delaunay)
00159 {
00160 mesh.clear();
00161 compute_delaunay2D( sites, delaunay );
00162 compute_dual(delaunay, mesh, voronoi_vertex_policy() );
00163 }
00164
00165
00176 template< typename point_container, typename mesh_type >
00177 void compute_voronoi(point_container const & sites, mesh_type & mesh)
00178 {
00179 mesh_type delaunay;
00180 compute_voronoi( sites, mesh, delaunay );
00181 }
00182
00183 }
00184 }
00185
00186
00187 #endif