vgl_vector_3d.hxx
Go to the documentation of this file.
1 // This is core/vgl/vgl_vector_3d.hxx
2 #ifndef vgl_vector_3d_hxx_
3 #define vgl_vector_3d_hxx_
4 //:
5 // \file
6 
7 #include <cmath>
8 #include <iostream>
9 #include <string>
10 #include "vgl_vector_3d.h"
11 #include "vgl_tolerance.h"
12 
13 #include <vcl_compiler_detection.h>
14 #ifdef _MSC_VER
15 # include <vcl_msvc_warnings.h>
16 #endif
17 #include <cassert>
18 #include <vcl_deprecated.h>
19 
20 template <class T>
22 {
23  return std::sqrt( 0.0+sqr_length() );
24 }
25 
26 //: The one-parameter family of unit vectors that are orthogonal to *this, v(s).
27 // The parameterization is such that 0<=s<1, v(0)==v(1)
28 template <class T>
30 {
31  VXL_DEPRECATED_MACRO("vgl_vector_3d<T>::orthogonal_vectors(double s)");
33 }
34 
35 template<class T>
36 double angle(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b)
37 {
38  double ca = cos_angle(a,b);
39  // Deal with numerical errors giving values slightly outside range.
40  if (ca>=-1.0)
41  {
42  if (ca<=1.0)
43  return std::acos(ca);
44  else
45  return 0;
46  }
47  else
48  return std::acos(-1.0); // pi
49 }
50 
51 template <class T>
52 bool orthogonal(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b, double eps)
53 {
54  T dot = dot_product(a,b); // should be zero
55  if (eps <= 0 || dot == T(0)) return dot == T(0);
56  eps *= eps * a.sqr_length() * b.sqr_length();
57  dot *= dot;
58  return dot < eps;
59 }
60 
61 template <class T>
62 bool parallel(vgl_vector_3d<T> const& a, vgl_vector_3d<T> const& b, double eps)
63 {
64  double cross = cross_product(a,b).sqr_length(); // should be zero
65  if (eps <= 0 || cross == 0.0) return cross == 0.0;
66  eps *= eps * a.sqr_length() * b.sqr_length();
67  return cross < eps;
68 }
69 
70 template <class T>
72 {
73  assert(a.length()>0.0);
74 
75  // enforce parameter range
76  if (s<0.0) s=0.0;
77  if (s>1.0) s = 1.0;
78  double tol = static_cast<double>(vgl_tolerance<T>::position);
79  double nx = static_cast<double>(a.x_);
80  double ny = static_cast<double>(a.y_);
81  double nz = static_cast<double>(a.z_);
82  double two_pi = 2*std::acos(-1.0);
83  double co = std::cos(two_pi*s);
84  double si = std::sin(two_pi*s);
85 
86  double mnz = std::fabs(nz);
87  if (mnz>tol) // General case
88  {
89  double rx = nx/nz;
90  double ry = ny/nz;
91  double q = co*rx +si*ry;
92  double a = 1.0/std::sqrt(1+q*q);
93  T vx = static_cast<T>(a*co);
94  T vy = static_cast<T>(a*si);
95  T vz = -static_cast<T>(rx*vx + ry*vy);
96  return vgl_vector_3d<T>(vx, vy, vz);
97  }
98  else // Special cases, nz ~ 0
99  {
100  double mny = std::fabs(ny);
101  if (mny>tol)
102  {
103  double r = nx/ny;
104  double a = 1/std::sqrt(1+co*co*r*r);
105  T vx = static_cast<T>(a*co);
106  T vz = static_cast<T>(a*si);
107  T vy = -static_cast<T>(a*co*r);
108  return vgl_vector_3d<T>(vx, vy, vz);
109  }
110  else
111  {
112  // assume mnx>tol provided that input vector was not null
113  double r = ny/nx;
114  double a = 1/std::sqrt(1+co*co*r*r);
115  T vy = static_cast<T>(a*co);
116  T vz = static_cast<T>(a*si);
117  T vx = -static_cast<T>(a*co*r);
118  return vgl_vector_3d<T>(vx, vy, vz);
119  }
120  }
121 }
122 
123 //: Write "<vgl_vector_3d x,y,z> " to stream
124 template <class T>
125 std::ostream& operator<<(std::ostream& s, vgl_vector_3d<T> const& p)
126 {
127  return s << "<vgl_vector_3d "<< p.x() << ',' << p.y() << ',' << p.z() << "> ";
128 }
129 
130 //: Read from stream, possibly with formatting
131 // Either just reads three blank-separated numbers,
132 // or reads three comma-separated numbers,
133 // or reads three numbers in parenthesized form "(123, 321, 567)"
134 // \relatesalso vgl_vector_3d
135 template <class T>
136 std::istream& vgl_vector_3d<T>::read(std::istream& is)
137 {
138  if (! is.good()) return is; // (TODO: should throw an exception)
139  bool paren = false;
140  T tx, ty, tz;
141  is >> std::ws; // jump over any leading whitespace
142  if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
143  char c = is.peek();
144  if (c == '(') { is.ignore(); paren=true; }
145  if(paren){
146  is >> std::ws >> tx >> std::ws;
147  if (is.eof()) return is;
148  if (is.peek() == ',') is.ignore();
149  is >> std::ws >> ty >> std::ws;
150  if (is.eof()) return is;
151  if (is.peek() == ',') is.ignore();
152  is >> std::ws >> tz >> std::ws;
153  if (is.eof()) return is;
154  if (is.peek() == ')') is.ignore();
155  else return is; // closing parenthesis is missing (TODO: throw an exception)
156  }else if( c == '<'){
157  std::string temp;
158  is >> temp >> std::ws; // read <vgl_vector_3d
159  is >> tx >> std::ws;
160  c = is.peek();
161  if(c != ','){
162  std::cout << "Invalid syntax: >> vgl_vector_3d" << std::endl;
163  set(0.0, 0.0, 0.0);
164  return is;
165  }else is.ignore();
166  is >> ty >> std::ws;
167  c = is.peek();
168  if(c != ','){
169  std::cout << "Invalid syntax: >> vgl_vector_3d" << std::endl;
170  set(0.0, 0.0, 0.0);
171  return is;
172  }else is.ignore();
173  is >> tz >> std::ws;
174  if(is.peek() != '>'){
175  std::cout << "Invalid syntax: >> vgl_vector_3d" << std::endl;
176  set(0.0, 0.0,0.0);
177  return is;
178  }else is.ignore();
179  }else{
180  is >> tx >> std::ws;
181  c = is.peek();
182  if(c == ',') is.ignore();
183  is >> std::ws >> ty >> std::ws;
184  c = is.peek();
185  if(c == ',') is.ignore();
186  is >> std::ws >> tz >> std::ws;
187  }
188  set(tx,ty,tz);
189  return is;
190 }
191 
192 //: Read from stream, possibly with formatting
193 // Either just reads three blank-separated numbers,
194 // or reads three comma-separated numbers,
195 // or reads three numbers in parenthesized form "(123, 321, 567)"
196 // \relatesalso vgl_vector_3d
197 template <class T>
198 std::istream& operator>>(std::istream& is, vgl_vector_3d<T>& p)
199 {
200  return p.read(is);
201 }
202 
203 #undef VGL_VECTOR_3D_INSTANTIATE
204 #define VGL_VECTOR_3D_INSTANTIATE(T) \
205 template class vgl_vector_3d<T >;\
206 /*template vgl_vector_3d<T > operator+ (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
207 /*template vgl_vector_3d<T > operator- (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
208 /*template vgl_vector_3d<T >& operator+= (vgl_vector_3d<T >&, vgl_vector_3d<T > const&); */\
209 /*template vgl_vector_3d<T >& operator-= (vgl_vector_3d<T >&, vgl_vector_3d<T > const&); */\
210 /*template vgl_vector_3d<T > operator+ (vgl_vector_3d<T > const&); */\
211 /*template vgl_vector_3d<T > operator- (vgl_vector_3d<T > const&); */\
212 /*template vgl_vector_3d<T > operator* (double, vgl_vector_3d<T > const&); */\
213 /*template vgl_vector_3d<T > operator* (vgl_vector_3d<T > const&, double); */\
214 /*template vgl_vector_3d<T > operator/ (vgl_vector_3d<T > const&, double); */\
215 /*template vgl_vector_3d<T >& operator*= (vgl_vector_3d<T >&, double); */\
216 /*template vgl_vector_3d<T >& operator/= (vgl_vector_3d<T >&, double); */\
217 /*template T dot_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
218 /*template T inner_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
219 /*template vgl_vector_3d<T > cross_product (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
220 /*template double cos_angle (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
221 template double angle (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&);\
222 template bool orthogonal (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&, double);\
223 template bool parallel (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&, double);\
224 template vgl_vector_3d<T > orthogonal_vectors(vgl_vector_3d<T > const&, double);\
225 /*template double operator/ (vgl_vector_3d<T > const&, vgl_vector_3d<T > const&); */\
226 /*template vgl_vector_3d<T >& normalize (vgl_vector_3d<T >&); */\
227 /*template vgl_vector_3d<T > normalized (vgl_vector_3d<T > const&); */\
228 template std::ostream& operator<< (std::ostream&, vgl_vector_3d<T >const&);\
229 template std::istream& operator>> (std::istream&, vgl_vector_3d<T >&)
230 
231 #endif // vgl_vector_3d_hxx_
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
vgl_vector_3d< T > orthogonal_vectors(vgl_vector_3d< T > const &a, double s)
direction vector in Euclidean 3D space
bool orthogonal(v const &a, v const &b, double eps=0.0)
are two vectors orthogonal, i.e., is their dot product zero?.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
#define dot(p, q)
vgl_vector_3d< T > orthogonal_vectors(double s) const
One-parameter family of unit vectors that are orthogonal to *this, v(s).
double length() const
Return the length of this vector.
T cross_product(v const &a, v const &b)
cross product of two vectors (area of enclosed parallellogram).
T y() const
Definition: vgl_vector_3d.h:37
T x() const
Definition: vgl_vector_3d.h:36
T sqr_length() const
Return the squared length of this vector.
Definition: vgl_vector_3d.h:74
T z() const
Definition: vgl_vector_3d.h:38
Direction vector in Euclidean 3D space, templated by type of element.
Definition: vgl_fwd.h:13
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
T sqr_length(v const &a)
Return the squared length of a vector.
Definition: vgl_vector_2d.h:98
double angle(v const &a, v const &b)
smallest angle between two vectors (in radians, between 0 and Pi).
std::istream & read(std::istream &is)
Read from stream, possibly with formatting.
bool parallel(v const &a, v const &b, double eps=0.0)
are two vectors parallel, i.e., is one a scalar multiple of the other?.
double cos_angle(v const &a, v const &b)
cosine of the angle between two vectors.