Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_COLLISION_BOX_SPHERE_H
00002 #define OPENTISSUE_COLLISION_COLLISION_BOX_SPHERE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace collision
00015 {
00016
00031 template<typename coordsys_type,typename box_type,typename sphere_type,typename real_type,typename vector3_type>
00032 bool box_sphere(
00033 coordsys_type const & BtoWCS
00034 , coordsys_type const & StoWCS
00035 , box_type const & box
00036 , sphere_type const & sphere
00037 , real_type const & envelope
00038 , vector3_type & p
00039 , vector3_type & n
00040 , real_type & distance
00041 )
00042 {
00043 using std::fabs;
00044 using std::sqrt;
00045
00046
00047 coordsys_type StoB = model_update(StoWCS,BtoWCS);
00048 vector3_type c = sphere.center();
00049 StoB.xform_point(c);
00050
00051
00052 real_type r = sphere.radius();
00053 vector3_type a = box.ext();
00054
00055
00056 bool inside = true;
00057 p = c;
00058 if(c(0)>a(0))
00059 {
00060 p(0) = a(0);
00061 n(0) = 1;
00062 inside = false;
00063 }
00064 if(c(0) < -a(0))
00065 {
00066 p(0) = -a(0);
00067 n(0) = -1;
00068 inside = false;
00069 }
00070 if(c(1)>a(1))
00071 {
00072 p(1) = a(1);
00073 n(1) = 1;
00074 inside = false;
00075 }
00076 if(c(1) < -a(1))
00077 {
00078 p(1) = -a(1);
00079 n(1) = -1;
00080 inside = false;
00081 }
00082 if(c(2) > a(2))
00083 {
00084 p(2) = a(2);
00085 n(2) = 1;
00086 inside = false;
00087 }
00088 if(c(2) < -a(2))
00089 {
00090 p(2) = -a(2);
00091 n(2) = -1;
00092 inside = false;
00093 }
00094
00095
00096 if(inside)
00097 {
00098
00099
00100
00101
00102
00103
00104
00105
00106 int cnt_closest_faces = 0;
00107
00108 p.clear();
00109 vector3_type f = a - fabs( c );
00110
00111
00112
00113 if(f(0) <= f(1) && f(0) <= f(2))
00114 {
00115 distance = -f(0) -r;
00116 n(0) = (c(0) > 0)?1:-1;
00117 ++cnt_closest_faces;
00118 p(0) = (c(0) > 0)?a(0):-a(0);
00119 }
00120 if(f(1) <= f(0) && f(1) <= f(2))
00121 {
00122 distance = -f(1) -r;
00123 n(1) = (c(1) > 0)?1:-1;
00124 ++cnt_closest_faces;
00125 p(1) = (c(1) > 0)?a(1):-a(1);
00126 }
00127 if(f(2) <= f(0) && f(2) <= f(1))
00128 {
00129 distance = -f(2) -r;
00130 n(2) = (c(2) >0)?1:-1;
00131 ++cnt_closest_faces;
00132 p(2) = (c(2) > 0)?a(2):-a(2);
00133 }
00134 if(cnt_closest_faces>1)
00135 {
00136 n = unit(n);
00137 f = p-c;
00138 distance = - sqrt(f*f) - r;
00139 }
00140
00141 p = c - n*(distance+r);
00142 }
00143 else
00144 {
00145
00146
00147
00148
00149
00150
00151 real_type tmp = sqrt(n*n);
00152 n /= tmp;
00153 vector3_type diff = c - p;
00154
00155
00156 distance = sqrt(diff*diff) - r;
00157 }
00158 if(distance>envelope)
00159 return false;
00160 BtoWCS.xform_vector(n);
00161 BtoWCS.xform_point(p);
00162 return true;
00163 }
00164
00165 }
00166
00167 }
00168
00169
00170 #endif