Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_OBB_FIT_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_OBB_FIT_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_vector3.h>
00013 #include <OpenTissue/core/math/math_matrix3x3.h>
00014 #include <OpenTissue/core/containers/mesh/mesh.h>
00015 #include <OpenTissue/core/math/math_covariance.h>
00016 #include <OpenTissue/core/math/math_eigen_system_decomposition.h>
00017
00018 #include <algorithm>
00019 #include <cmath>
00020 #include <iostream>
00021
00022 #include <OpenTissue/core/math/math_constants.h>
00023
00024
00025 namespace OpenTissue
00026 {
00027 namespace geometry
00028 {
00029
00060 template <typename vector3_iterator,typename obb_type>
00061 void obb_fit(
00062 vector3_iterator begin
00063 , vector3_iterator end
00064 , obb_type & obb
00065 , bool const & use_convex_surface = true
00066 )
00067 {
00068 typedef typename obb_type::math_types math_types;
00069 typedef typename math_types::real_type real_type;
00070 typedef typename math_types::vector3_type vector3_type;
00071 typedef typename math_types::matrix3x3_type matrix3x3_type;
00072
00073 assert(begin!=end || !"obb_fit(): beging was equal to end");
00074
00075 matrix3x3_type cov;
00076 vector3_type mean;
00077 if(use_convex_surface)
00078 {
00079 polymesh::PolyMesh<math_types> mesh;
00080 mesh::convex_hull(begin, end,mesh);
00081 mesh::compute_surface_covariance(mesh,mean,cov);
00082 }
00083 else
00084 {
00085 math::covariance(begin, end, mean, cov);
00086 }
00087 matrix3x3_type R;
00088 vector3_type d;
00089 math::eigen(cov,R,d);
00090
00091 vector3_type v1 = vector3_type(R(0,0),R(1,0),R(2,0));
00092 vector3_type v2 = vector3_type(R(0,1),R(1,1),R(2,1));
00093 vector3_type v3 = vector3_type(R(0,2),R(1,2),R(2,2));
00094 vector3_type v1Xv2 = v1 % v2;
00095 if((v1Xv2 * v3)<0)
00096 {
00097 R(0,0) = v1(0); R(1,0) = v1(1); R(2,0) = v1(2);
00098 R(0,1) = v2(0); R(1,1) = v2(1); R(2,1) = v2(2);
00099 R(0,2) = -v3(0); R(1,2) = -v3(1); R(2,2) = -v3(2);
00100 }
00101 vector3_type min_coord;
00102 vector3_type max_coord;
00103 min_coord(0) = min_coord(1)= min_coord(2) = math::detail::highest<real_type>();
00104 max_coord(0) = max_coord(1)= max_coord(2) = math::detail::lowest<real_type>();
00105 real_type tst = 0;
00106 for(vector3_iterator v=begin; v!=end; ++v)
00107 {
00108 tst = v1 * (*v);
00109 min_coord(0) = (tst < min_coord(0))? tst : min_coord(0);
00110 max_coord(0) = (tst > max_coord(0))? tst : max_coord(0);
00111 tst = v2 * (*v);
00112 min_coord(1) = (tst < min_coord(1))? tst : min_coord(1);
00113 max_coord(1) = (tst > max_coord(1))? tst : max_coord(1);
00114 tst = v3 * (*v);
00115 min_coord(2) = (tst < min_coord(2))? tst : min_coord(2);
00116 max_coord(2) = (tst > max_coord(2))? tst : max_coord(2);
00117 }
00118 vector3_type half_extent = (max_coord - min_coord)*.5;
00119 vector3_type tmp = (max_coord + min_coord)*.5;
00120 vector3_type center = v1*tmp(0) + v2*tmp(1) + v3*tmp(2) ;
00121
00122 obb = obb_type(center,R,half_extent);
00123 }
00124
00125 }
00126 }
00127
00128
00129 #endif