00001
00002 #ifndef vgl_orient_box_3d_txx_
00003 #define vgl_orient_box_3d_txx_
00004
00005
00006
00007 #include "vgl_orient_box_3d.h"
00008 #include <vgl/vgl_vector_3d.h>
00009 #include <vnl/vnl_det.h>
00010 #include <vcl_iostream.h>
00011
00012 template <class Type>
00013 vgl_orient_box_3d<Type>::vgl_orient_box_3d(vgl_box_3d<Type> box)
00014 : box_(box)
00015 {
00016 vnl_vector_fixed<double,3> axis;
00017 axis[0] = 0.0; axis[1] = 0.0; axis[2]=1.0;
00018 double angle = 0.0;
00019
00020 orient_ = vnl_quaternion<double> (axis, angle);
00021 }
00022
00023 template <class Type>
00024 vgl_orient_box_3d<Type>::vgl_orient_box_3d(vgl_box_3d<Type> box, vnl_quaternion<double> orient)
00025 : box_(box), orient_(orient)
00026 {
00027 }
00028
00029
00030
00031 template <class Type>
00032 vgl_orient_box_3d<Type>::vgl_orient_box_3d(vgl_point_3d<Type> const& p0,
00033 vgl_point_3d<Type> const& px,
00034 vgl_point_3d<Type> const& py,
00035 vgl_point_3d<Type> const& pz)
00036 {
00037
00038 vgl_vector_3d<Type> vx = px - p0, vy = py - p0, vz = pz - p0;
00039 double lx = vx.length(), ly = vy.length(), lz = vz.length();
00040
00041 vnl_matrix_fixed<double,3,3> rotation;
00042
00043 rotation(0,0) = vx.x()/lx; rotation(0,1) = vx.y()/lx; rotation(0,2) = vx.z()/lx;
00044 rotation(1,0) = vy.x()/ly; rotation(1,1) = vy.y()/ly; rotation(1,2) = vy.z()/ly;
00045 rotation(2,0) = vz.x()/lz; rotation(2,1) = vz.y()/lz; rotation(2,2) = vz.z()/lz;
00046
00047 double det = vnl_det(rotation);
00048 if (det < 0) {
00049 double t = rotation(0,0); rotation(0,0) = rotation(1,0); rotation(1,0) = t;
00050 t = rotation(0,1); rotation(0,1) = rotation(1,1); rotation(1,1) = t;
00051 t = rotation(0,2); rotation(0,2) = rotation(1,2); rotation(1,2) = t;
00052 }
00053 orient_ = vnl_quaternion<double>(rotation);
00054
00055
00056 vnl_vector_fixed<double,3> centroid(-0.5*p0.x()+0.5*px.x()+0.5*py.x()+0.5*pz.x(),
00057 -0.5*p0.y()+0.5*px.y()+0.5*py.y()+0.5*pz.y(),
00058 -0.5*p0.z()+0.5*px.z()+0.5*py.z()+0.5*pz.z());
00059 vnl_vector_fixed<double,3> p0_to_centroid = vnl_vector_fixed<double,3>(p0.x(),p0.y(),p0.z()) - centroid;
00060 vnl_vector_fixed<double,3> corner_0 = centroid + rotation * p0_to_centroid;
00061 vgl_point_3d<Type> corner0(corner_0[0], corner_0[1], corner_0[2]);
00062 vnl_vector_fixed<double,3> corner_1 = centroid - rotation * p0_to_centroid;
00063 vgl_point_3d<Type> corner1(corner_1[0], corner_1[1], corner_1[2]);
00064 box_ = vgl_box_3d<Type>(corner0, corner1);
00065 }
00066
00067
00068 template <class Type>
00069 vcl_vector<vgl_point_3d<Type> > vgl_orient_box_3d<Type>::corners()
00070 {
00071 vcl_vector<vgl_point_3d<Type> > corner_points(8);
00072
00073
00074 corner_points[0] = box_.min_point();
00075 corner_points[7] = box_.max_point();
00076
00077 corner_points[1] = vgl_point_3d<Type> (corner_points[0].x()+width(),
00078 corner_points[0].y(),
00079 corner_points[0].z());
00080 corner_points[2] = vgl_point_3d<Type> (corner_points[0].x(),
00081 corner_points[0].y(),
00082 corner_points[0].z()+depth());
00083 corner_points[3] = vgl_point_3d<Type> (corner_points[1].x(),
00084 corner_points[1].y(),
00085 corner_points[1].z()+depth());
00086 corner_points[4] = vgl_point_3d<Type> (corner_points[0].x(),
00087 corner_points[0].y()+height(),
00088 corner_points[0].z());
00089 corner_points[5] = vgl_point_3d<Type> (corner_points[1].x(),
00090 corner_points[1].y()+height(),
00091 corner_points[1].z());
00092 corner_points[6] = vgl_point_3d<Type> (corner_points[2].x(),
00093 corner_points[2].y()+height(),
00094 corner_points[2].z());
00095
00096 for (unsigned int i=0; i < corner_points.size(); i++) {
00097 vnl_vector_fixed<double,3> p;
00098 p[0] = corner_points[i].x() - box_.centroid_x();
00099 p[1] = corner_points[i].y() - box_.centroid_y();
00100 p[2] = corner_points[i].z() - box_.centroid_z();
00101 p = orient_.rotate(p);
00102 corner_points[i] = vgl_point_3d<Type> (Type(p[0]) + box_.centroid_x(),
00103 Type(p[1]) + box_.centroid_y(),
00104 Type(p[2]) + box_.centroid_z());
00105 }
00106 return corner_points;
00107 }
00108
00109
00110 template <class Type>
00111 bool vgl_orient_box_3d<Type>::contains(Type const& x,
00112 Type const& y,
00113 Type const& z) const
00114 {
00115
00116 vnl_quaternion<double> reverse_rot = orient_.inverse();
00117
00118 vnl_vector_fixed<double,3> p;
00119 p[0] = x - box_.centroid_x();
00120 p[1] = y - box_.centroid_y();
00121 p[2] = z - box_.centroid_z();
00122 p = reverse_rot.rotate(p);
00123 Type xt = static_cast<Type>(p[0] + box_.centroid_x());
00124 Type yt = static_cast<Type>(p[1] + box_.centroid_y());
00125 Type zt = static_cast<Type>(p[2] + box_.centroid_z());
00126 return box_.contains(xt, yt, zt);
00127 }
00128
00129 template <class Type>
00130 vcl_ostream& vgl_orient_box_3d<Type>::print(vcl_ostream& s) const
00131 {
00132 return s << "<vgl_orient_box_3d " << box_ << " dir=" << orient_ << '>' << vcl_endl;
00133 }
00134
00135 template <class Type>
00136 vcl_istream& vgl_orient_box_3d<Type>::read(vcl_istream& s)
00137 {
00138 return s >> box_ >> orient_ ;
00139 }
00140
00141 //: Write box to stream
00142 template <class Type>
00143 vcl_ostream& operator<<(vcl_ostream& s, vgl_orient_box_3d<Type> const& p)
00144 {
00145 return p.print(s);
00146 }
00147
00148 //: Read box from stream
00149 template <class Type>
00150 vcl_istream& operator>>(vcl_istream& is, vgl_orient_box_3d<Type>& p)
00151 {
00152 return p.read(is);
00153 }
00154
00155 #undef VGL_ORIENT_BOX_3D_INSTANTIATE
00156 #define VGL_ORIENT_BOX_3D_INSTANTIATE(T) \
00157 template class vgl_orient_box_3d<T >;\
00158 template vcl_ostream& operator<<(vcl_ostream&, vgl_orient_box_3d<T > const& p);\
00159 template vcl_istream& operator>>(vcl_istream&, vgl_orient_box_3d<T >& p)
00160
00161 #endif // vgl_orient_box_3d_txx_