00001
00002 #ifndef vgl_vector_3d_txx_
00003 #define vgl_vector_3d_txx_
00004
00005
00006
00007 #include "vgl_vector_3d.h"
00008 #include "vgl_tolerance.txx"
00009
00010 #include <vcl_cmath.h>
00011 #include <vcl_iostream.h>
00012 #include <vcl_cassert.h>
00013 #include <vcl_deprecated.h>
00014
00015 template <class T>
00016 double vgl_vector_3d<T>::length() const
00017 {
00018 return vcl_sqrt( 0.0+sqr_length() );
00019 }
00020
00021
00022
00023 template <class T>
00024 vgl_vector_3d<T> vgl_vector_3d<T>::orthogonal_vectors(double s) const
00025 {
00026 VXL_DEPRECATED("vgl_vector_3d<T>::orthogonal_vectors(double s)");
00027 return ::orthogonal_vectors(*this, s);
00028 }
00029
00030 template<class T>
00031 double angle(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b)
00032 {
00033 double ca = cos_angle(a,b);
00034
00035 if (ca>=-1.0)
00036 {
00037 if (ca<=1.0)
00038 return vcl_acos(ca);
00039 else
00040 return 0;
00041 }
00042 else
00043 return vcl_acos(-1.0);
00044 }
00045
00046 template <class T>
00047 bool orthogonal(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b, double eps)
00048 {
00049 T dot = dot_product(a,b);
00050 if (eps <= 0 || dot == T(0)) return dot == T(0);
00051 eps *= eps * a.sqr_length() * b.sqr_length();
00052 dot *= dot;
00053 return dot < eps;
00054 }
00055
00056 template <class T>
00057 bool parallel(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b, double eps)
00058 {
00059 double cross = cross_product(a,b).sqr_length();
00060 if (eps <= 0 || cross == 0.0) return cross == 0.0;
00061 eps *= eps * a.sqr_length() * b.sqr_length();
00062 return cross < eps;
00063 }
00064
00065 template <class T>
00066 vgl_vector_3d<T> orthogonal_vectors(vgl_vector_3d<T> const& a, double s)
00067 {
00068 assert(a.length()>0.0);
00069
00070
00071 if (s<0.0) s=0.0;
00072 if (s>1.0) s = 1.0;
00073 double tol = static_cast<double>(vgl_tolerance<T>::position);
00074 double nx = static_cast<double>(a.x_);
00075 double ny = static_cast<double>(a.y_);
00076 double nz = static_cast<double>(a.z_);
00077 double two_pi = 2*vcl_acos(-1.0);
00078 double co = vcl_cos(two_pi*s);
00079 double si = vcl_sin(two_pi*s);
00080
00081 double mnz = vcl_fabs(nz);
00082 if (mnz>tol)
00083 {
00084 double rx = nx/nz;
00085 double ry = ny/nz;
00086 double q = co*rx +si*ry;
00087 double a = 1.0/vcl_sqrt(1+q*q);
00088 T vx = static_cast<T>(a*co);
00089 T vy = static_cast<T>(a*si);
00090 T vz = -static_cast<T>(rx*vx + ry*vy);
00091 return vgl_vector_3d<T>(vx, vy, vz);
00092 }
00093 else
00094 {
00095 double mny = vcl_fabs(ny);
00096 if (mny>tol)
00097 {
00098 double r = nx/ny;
00099 double a = 1/vcl_sqrt(1+co*co*r*r);
00100 T vx = static_cast<T>(a*co);
00101 T vz = static_cast<T>(a*si);
00102 T vy = -static_cast<T>(a*co*r);
00103 return vgl_vector_3d<T>(vx, vy, vz);
00104 }
00105 else
00106 {
00107
00108 double r = ny/nx;
00109 double a = 1/vcl_sqrt(1+co*co*r*r);
00110 T vy = static_cast<T>(a*co);
00111 T vz = static_cast<T>(a*si);
00112 T vx = -static_cast<T>(a*co*r);
00113 return vgl_vector_3d<T>(vx, vy, vz);
00114 }
00115 }
00116 }
00117
00118
00119 template <class T>
00120 vcl_ostream& operator<<(vcl_ostream& s, vgl_vector_3d<T> const& p)
00121 {
00122 return s << "<vgl_vector_3d "<< p.x() << ',' << p.y() << ',' << p.z() << "> ";
00123 }
00124
00125
00126
00127
00128
00129
00130 template <class T>
00131 vcl_istream& vgl_vector_3d<T>::read(vcl_istream& is)
00132 {
00133 if (! is.good()) return is;
00134 bool paren = false;
00135 T tx, ty, tz;
00136 is >> vcl_ws;
00137 if (is.eof()) return is;
00138 if (is.peek() == '(') { is.ignore(); paren=true; }
00139 is >> vcl_ws >> tx >> vcl_ws;
00140 if (is.eof()) return is;
00141 if (is.peek() == ',') is.ignore();
00142 is >> vcl_ws >> ty >> vcl_ws;
00143 if (is.eof()) return is;
00144 if (is.peek() == ',') is.ignore();
00145 is >> vcl_ws >> tz >> vcl_ws;
00146 if (paren) {
00147 if (is.eof()) return is;
00148 if (is.peek() == ')') is.ignore();
00149 else return is;
00150 }
00151 set(tx,ty,tz);
00152 return is;
00153 }
00154
00155
00156
00157
00158
00159
00160 template <class T>
00161 vcl_istream& operator>>(vcl_istream& is, vgl_vector_3d<T>& p)
00162 {
00163 return p.read(is);
00164 }
00165
00166 #undef VGL_VECTOR_3D_INSTANTIATE
00167 #define VGL_VECTOR_3D_INSTANTIATE(T) \
00168 template class vgl_vector_3d<T >;\
00169 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator+ (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00170 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator- (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00171 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T >& operator+= (vgl_vector_3d<T >&, vgl_vector_3d<T > const&));\
00172 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T >& operator-= (vgl_vector_3d<T >&, vgl_vector_3d<T > const&));\
00173 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator+ (vgl_vector_3d<T > const&));\
00174 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator- (vgl_vector_3d<T > const&));\
00175 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator* (double, vgl_vector_3d<T > const&));\
00176 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator* (vgl_vector_3d<T > const&, double));\
00177 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > operator/ (vgl_vector_3d<T > const&, double));\
00178 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T >& operator*= (vgl_vector_3d<T >&, double));\
00179 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T >& operator/= (vgl_vector_3d<T >&, double));\
00180 VCL_INSTANTIATE_INLINE(T dot_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00181 VCL_INSTANTIATE_INLINE(T inner_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00182 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > cross_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00183 VCL_INSTANTIATE_INLINE(double cos_angle (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00184 template double angle (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&);\
00185 template bool orthogonal (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&, double);\
00186 template bool parallel (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&, double);\
00187 template vgl_vector_3d<T > orthogonal_vectors(vgl_vector_3d<T > const&, double);\
00188 VCL_INSTANTIATE_INLINE(double operator/ (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&));\
00189 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T >& normalize (vgl_vector_3d<T >&));\
00190 VCL_INSTANTIATE_INLINE(vgl_vector_3d<T > normalized (vgl_vector_3d<T > const&));\
00191 template vcl_ostream& operator<< (vcl_ostream&, vgl_vector_3d<T >const&);\
00192 template vcl_istream& operator>> (vcl_istream&, vgl_vector_3d<T >&)
00193
00194 #endif // vgl_vector_3d_txx_