Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_COLLISION_PLANE_BOX_H
00002 #define OPENTISSUE_COLLISION_COLLISION_PLANE_BOX_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 plane_type,typename box_type,typename real_type,typename vector3_type>
00032 int plane_box(
00033 coordsys_type const & PtoWCS
00034 , coordsys_type const & BtoWCS
00035 , plane_type const & plane
00036 , box_type const & box
00037 , real_type const & envelope
00038 , vector3_type * p
00039 , vector3_type & n
00040 , real_type * distance
00041 )
00042 {
00043
00044 typedef typename box_type::matrix3x3_type matrix3x3_type;
00045
00046 assert(p);
00047 assert(distance);
00048
00049
00050 coordsys_type BtoP = model_update(BtoWCS,PtoWCS);
00051
00052 vector3_type c = box.center();
00053 BtoP.xform_point(c);
00054 matrix3x3_type R = box.orientation();
00055 BtoP.xform_matrix(R);
00056
00057
00058 n = plane.n();
00059
00060 vector3_type i,j,k;
00061 i(0) = R(0,0); i(1) = R(1,0); i(2) = R(2,0);
00062 j(0) = R(0,1); j(1) = R(1,1); j(2) = R(2,1);
00063 k(0) = R(0,2); k(1) = R(1,2); k(2) = R(2,2);
00064
00065 p[0] = c;
00066 vector3_type a = box.ext();
00067 vector3_type delta;
00068
00069 if(n*i>0)
00070 {
00071 p[0] -= i*a(0);
00072 delta(0) = -1;
00073 }
00074 else
00075 {
00076 p[0] += i*a(0);
00077 delta(0) = +1;
00078 }
00079 if(n*j>0)
00080 {
00081 p[0] -= j*a(1);
00082 delta(1) = -1;
00083 }
00084 else
00085 {
00086 p[0] += j*a(1);
00087 delta(1) = +1;
00088 }
00089 if(n*k>0)
00090 {
00091 p[0] -= k*a(2);
00092 delta(2) = -1;
00093 }
00094 else
00095 {
00096 p[0] += k*a(2);
00097 delta(2) = +1;
00098 }
00099 real_type w = plane.w();
00100 distance[0] = n*p[0] - w;
00101
00102
00103
00104 if(distance[0]>envelope)
00105 return 0;
00106
00107
00108
00109
00110
00111
00112 vector3_type b;
00113 b(0) = -2.*a(0)*delta(0);
00114 b(1) = -2.*a(1)*delta(1);
00115 b(2) = -2.*a(2)*delta(2);
00116 vector3_type corner[3];
00117 corner[0] = p[0] + i*b(0);
00118 corner[1] = p[0] + j*b(1);
00119 corner[2] = p[0] + k*b(2);
00120
00121
00122
00123 real_type dist[3];
00124 dist[0] = corner[0]*n - w;
00125 dist[1] = corner[1]*n - w;
00126 dist[2] = corner[2]*n - w;
00127
00128
00129 int permutation[3] = {0,1,2};
00130 for(int s=1; s<3; ++s)
00131 {
00132 for(int t=s; t>0; --t)
00133 {
00134 if(dist[permutation[t]] < dist[permutation[t-1]])
00135 {
00136 int tmp = permutation[t-1];
00137 permutation[t-1] = permutation[t];
00138 permutation[t] = tmp;
00139 }
00140 }
00141 }
00142
00143 if(dist[permutation[0]]>envelope)
00144 {
00145 PtoWCS.xform_point(p[0]);
00146 PtoWCS.xform_vector(n);
00147 return 1;
00148 }
00149 p[1] = corner[permutation[0]];
00150 distance[1] = dist[permutation[0]];
00151
00152 if(dist[permutation[1]]>envelope)
00153 {
00154 PtoWCS.xform_point(p[0]);
00155 PtoWCS.xform_point(p[1]);
00156 PtoWCS.xform_vector(n);
00157 return 2;
00158 }
00159 p[2] = corner[permutation[1]];
00160 distance[2] = dist[permutation[1]];
00161
00162
00163
00164
00165
00166
00167 PtoWCS.xform_point(p[0]);
00168 PtoWCS.xform_point(p[1]);
00169 PtoWCS.xform_point(p[2]);
00170 PtoWCS.xform_vector(n);
00171 return 3;
00172 }
00173
00174 }
00175
00176 }
00177
00178
00179 #endif