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