Go to the documentation of this file.00001
00002 #ifndef vgl_infinite_line_3d_txx_
00003 #define vgl_infinite_line_3d_txx_
00004
00005 #include "vgl_infinite_line_3d.h"
00006 #include <vcl_cassert.h>
00007 #include <vcl_iostream.h>
00008 #include <vcl_cmath.h>
00009 template <class Type>
00010 vgl_infinite_line_3d<Type>::vgl_infinite_line_3d(vgl_point_3d<Type> const& p1,
00011 vgl_point_3d<Type> const& p2)
00012 {
00013 vgl_vector_3d<Type> dir = p2-p1;
00014 vgl_infinite_line_3d<Type> l(p1, dir);
00015 x0_ = l.x0();
00016 t_ = dir;
00017 }
00018
00019 template <class Type>
00020 void vgl_infinite_line_3d<Type>::
00021 compute_uv_vectors(vgl_vector_3d<Type>& u, vgl_vector_3d<Type>& v) const
00022 {
00023
00024
00025
00026 vgl_vector_3d<Type> x(Type(1), Type(0), Type(0));
00027 v = cross_product(t_,x);
00028 Type vmag = static_cast<Type>(v.length());
00029 double vmagd = static_cast<double>(vmag);
00030 if (vmagd < 1.0e-8) {
00031 vgl_vector_3d<Type> z(Type(0), Type(0), Type(1));
00032 v = cross_product(z, t_);
00033 vmag = static_cast<Type>(v.length());
00034 assert(vmag>Type(0));
00035 v/=vmag;
00036 }
00037 else v/=vmag;
00038
00039 u = cross_product(v,t_);
00040 Type umag = static_cast<Type>(u.length());
00041 u/=umag;
00042 }
00043
00044 template <class Type>
00045 vgl_infinite_line_3d<Type>::
00046 vgl_infinite_line_3d(vgl_point_3d<Type> const& p,
00047 vgl_vector_3d<Type> const& dir)
00048 {
00049
00050 double ttx = vcl_fabs(static_cast<double>(dir.x()));
00051 double tty = vcl_fabs(static_cast<double>(dir.y()));
00052 double ttz = vcl_fabs(static_cast<double>(dir.z()));
00053 double max_comp = ttx;
00054 double sign = static_cast<double>(dir.x());
00055 if (max_comp < tty) {
00056 max_comp = tty;
00057 sign = static_cast<double>(dir.y());
00058 }
00059 if (max_comp < ttz) {
00060 max_comp = ttz;
00061 sign = static_cast<double>(dir.z());
00062 }
00063
00064 Type sense = static_cast<Type>(sign/max_comp);
00065 t_ = normalized(dir*sense);
00066
00067
00068
00069
00070 Type mag = static_cast<Type>(t_.length());
00071 assert(mag>Type(0));
00072 vgl_vector_3d<Type> pv(p.x(), p.y(), p.z());
00073 Type dp = dot_product(pv, t_);
00074 Type k = -dp/(mag*mag);
00075
00076 vgl_vector_3d<Type> p0 = pv + k*t_, u, v;
00077 this->compute_uv_vectors(u, v);
00078
00079 Type u0 = dot_product(u, p0), v0 = dot_product(v, p0);
00080 x0_.set(u0, v0);
00081 }
00082
00083
00084 template <class Type>
00085 vgl_point_3d<Type> vgl_infinite_line_3d<Type>::point() const
00086 {
00087
00088 vgl_vector_3d<Type> u, v, pv;
00089 this->compute_uv_vectors(u, v);
00090 pv = x0_.x()*u + x0_.y()*v;
00091 return vgl_point_3d<Type>(pv.x(), pv.y(), pv.z());
00092 }
00093
00094 template <class Type>
00095 bool vgl_infinite_line_3d<Type>::contains(const vgl_point_3d<Type>& p ) const
00096 {
00097 vgl_point_3d<Type> point1 = this->point();
00098 vgl_point_3d<Type> point2 = this->point_t(Type(1));
00099 double seg = 1.0;
00100 double len1 = static_cast<double>((point1 - p).length());
00101 double len2 = static_cast<double>((point2 - p).length());
00102
00103
00104 double r = seg -(len1 + len2);
00105 if (len1>seg||len2>seg)
00106 r = seg - vcl_fabs(len1-len2);
00107 return r < 1e-8 && r > -1e-8;
00108 }
00109
00110
00111 template <class Type>
00112 vcl_ostream& operator<<(vcl_ostream& s, vgl_infinite_line_3d<Type> const & p)
00113 {
00114 return s << "<vgl_infinite_line_3d: origin" << p.x0() << " dir " << p.direction() << " >";
00115 }
00116
00117 template <class Type>
00118 vcl_istream& operator>>(vcl_istream& s, vgl_infinite_line_3d<Type>& p)
00119 {
00120 vgl_vector_2d<Type> x_0;
00121 vgl_vector_3d<Type> dir;
00122 s >> x_0 >> dir;
00123 p.set(x_0, dir);
00124 return s;
00125 }
00126
00127 #undef VGL_INFINITE_LINE_3D_INSTANTIATE
00128 #define VGL_INFINITE_LINE_3D_INSTANTIATE(Type) \
00129 template class vgl_infinite_line_3d<Type >;\
00130 template vcl_istream& operator>>(vcl_istream&, vgl_infinite_line_3d<Type >&);\
00131 template vcl_ostream& operator<<(vcl_ostream&, vgl_infinite_line_3d<Type > const&)
00132
00133 #endif // vgl_infinite_line_3d_txx_