Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_INTERSECT_INTERSECT_SPHERE_TRIANGLE_H
00002 #define OPENTISSUE_COLLISION_INTERSECT_INTERSECT_SPHERE_TRIANGLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/collision/intersect/intersect_line_sphere.h>
00013 #include <OpenTissue/core/math/math_precision.h>
00014 #include <OpenTissue/core/geometry/geometry_barycentric.h>
00015 #include <OpenTissue/core/geometry/geometry_plane.h>
00016
00017 namespace OpenTissue
00018 {
00019 namespace intersect
00020 {
00021
00022
00033 template<typename sphere_type, typename triangle_type>
00034 bool sphere_triangle(sphere_type const & sphere, triangle_type const & triangle)
00035 {
00036 using std::fabs;
00037
00038 typedef typename sphere_type::math_types math_types;
00039 typedef typename math_types::real_type real_type;
00040 typedef typename math_types::vector3_type vector3_type;
00041
00042 static real_type const threshold = math::working_precision<real_type>();
00043
00044 OpenTissue::geometry::Plane<math_types> plane(triangle.p0(),triangle.p1(),triangle.p2());
00045
00046 vector3_type c = sphere.center();
00047 real_type r = sphere.radius();
00048
00049 real_type d = plane.signed_distance(c);
00050 if( fabs(d) > (threshold+r) )
00051 return false;
00052
00053
00054 if(sphere.contains(triangle.p0()))
00055 return true;
00056 if(sphere.contains(triangle.p1()))
00057 return true;
00058 if(sphere.contains(triangle.p2()))
00059 return true;
00060
00061
00062 if(line_sphere(triangle.p0(),triangle.p1(),sphere))
00063 return true;
00064 if(line_sphere(triangle.p1(),triangle.p2(),sphere))
00065 return true;
00066 if(line_sphere(triangle.p2(),triangle.p0(),sphere))
00067 return true;
00068
00069
00070 static const real_type lower = -threshold;
00071 static const real_type upper = 1.+threshold;
00072
00073 real_type w1,w2,w3;
00074 OpenTissue::geometry::barycentric_algebraic(triangle.p0(),triangle.p1(),triangle.p2(),c,w1,w2,w3);
00075 if(
00076 (w1>lower)&&(w1<upper)
00077 &&
00078 (w2>lower)&&(w2<upper)
00079 &&
00080 (w3>lower)&&(w3<upper)
00081 )
00082 {
00083 return true;
00084 }
00085 return false;
00086 }
00087
00088 }
00089
00090 }
00091
00092
00093 #endif