vgl_vector_2d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_vector_2d.h
2 #ifndef vgl_vector_2d_h_
3 #define vgl_vector_2d_h_
4 //:
5 // \file
6 // \brief direction vector in Euclidean 2D space
7 // \author Peter Vanroose
8 // \date 27 June, 2001
9 //
10 // \verbatim
11 // Modifications
12 // 2001-07-05 Peter Vanroose Added orthogonal(); operator* now accepts double
13 // 2009-05-21 Peter Vanroose istream operator>> re-implemented
14 // \endverbatim
15 
16 #include <iosfwd>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 //----------------------------------------------------------------------
22 
23 //: Direction vector in Euclidean 2D space, templated by type of element
24 // (typically float or double). A vgl_vector_2d<T> represents the
25 // difference (or connecting vector) between two vgl_point_2d<T>s.
26 //
27 // Use this class to do arithmetic (adding and scaling) in 2d geometric space.
28 //
29 template <class T>
30 class vgl_vector_2d
31 {
32  public:
33  T x_; // Data is public
34  T y_;
35  inline T x() const { return x_; }
36  inline T y() const { return y_; }
37 
38  //: Creates the vector (0,0) of zero length.
39  inline vgl_vector_2d () : x_(0) , y_(0) {}
40 
41  //: Creates the vector \a (x,y).
42  inline vgl_vector_2d (T vx, T vy) : x_(vx) , y_(vy) {}
43 
44 #if 0 // The defaults do exactly what they should do...
45  //: Copy constructor
46  inline vgl_vector_2d (vgl_vector_2d<T> const& v) : x_(v.x()) , y_(v.y()) {}
47  //: Assignment operator
48  inline vgl_vector_2d<T>& operator=(vgl_vector_2d<T> const& v) {
49  x_=v.x(); y_=v.y(); return *this; }
50  //: Destructor
51  inline ~vgl_vector_2d () {}
52 #endif
53 
54  //: Assignment
55  inline void set(T vx, T vy) { x_=vx; y_=vy; }
56 
57  //: Comparison
58  inline bool operator==(vgl_vector_2d<T>const& v)const{return x_==v.x()&&y_==v.y();}
59  inline bool operator!=(vgl_vector_2d<T>const& v)const{return !operator==(v);}
60 
61  //: Return the length of this vector.
62  double length() const; // return sqrt( x()*x()+y()*y() );
63 
64  //: Return the squared length of this vector.
65  inline T sqr_length() const { return x()*x()+y()*y(); }
66 
67  //: Read from stream, possibly with formatting
68  // Either just reads two blank-separated numbers,
69  // or reads two comma-separated numbers,
70  // or reads two numbers in parenthesized form "(123, 321)"
71  std::istream& read(std::istream& is);
72 };
73 
74 #define v vgl_vector_2d<T>
75 
76 // +-+-+ vector_2d simple I/O +-+-+
77 
78 //: Write "<vgl_vector_2d x,y> " to stream
79 // \relatesalso vgl_vector_2d
80 template <class T> std::ostream& operator<<(std::ostream& s, v const& p);
81 
82 //: Read from stream, possibly with formatting
83 // Either just reads two blank-separated numbers,
84 // or reads two comma-separated numbers,
85 // or reads two numbers in parenthesized form "(123, 321)"
86 // \relatesalso vgl_vector_2d
87 template <class T> std::istream& operator>>(std::istream& s, v& p);
88 
89 
90 // +-+-+ vector_2d geometry and algebra +-+-+
91 
92 //: Return the length of a vector.
93 // \relatesalso vgl_vector_2d
94 template <class T> inline double length(v const& a) { return a.length(); }
95 
96 //: Return the squared length of a vector.
97 // \relatesalso vgl_vector_2d
98 template <class T> inline T sqr_length(v const& a) { return a.sqr_length(); }
99 
100 //: c=a+b: add two vectors.
101 // \relatesalso vgl_vector_2d
102 template <class T> inline v operator+(v const& a, v const& b) { return v(a.x()+b.x(), a.y()+b.y()); }
103 
104 //: c=a-b: subtract two vectors.
105 // \relatesalso vgl_vector_2d
106 template <class T> inline v operator-(v const& a, v const& b) { return v(a.x()-b.x(), a.y()-b.y()); }
107 
108 //: a+=b: add b to a and return a.
109 // \relatesalso vgl_vector_2d
110 template <class T> inline v& operator+=(v& a, v const& b) { a.x_+=b.x_; a.y_+=b.y_; return a; }
111 
112 //: a-=b: subtract b from a and return a.
113 // \relatesalso vgl_vector_2d
114 template <class T> inline v& operator-=(v& a, v const& b) { a.x_-=b.x_; a.y_-=b.y_; return a; }
115 
116 //: +b: unary plus operator (no-op).
117 // \relatesalso vgl_vector_2d
118 template <class T> inline v operator+(v const& b) { return b; }
119 
120 //: -a: unary minus operator (additive inverse).
121 // \relatesalso vgl_vector_2d
122 template <class T> inline v operator-(v const& b) { return v(-b.x(), -b.y()); }
123 
124 //: c=f*b: return a scaled version of the vector.
125 // \relatesalso vgl_vector_2d
126 template <class T> inline v operator*(double s, v const& b) { return v(T(s*b.x()), T(s*b.y())); }
127 
128 //: c=a*f: return a scaled version of the vector.
129 // \relatesalso vgl_vector_2d
130 template <class T> inline v operator*(v const& a, double s) { return v(T(a.x()*s), T(a.y()*s)); }
131 
132 //: c=b/f: return an inversely scaled version of the vector (scale must be nonzero).
133 // Note that the argument type is double, not T, to avoid rounding errors
134 // when type T has no multiplicative inverses (like T=int).
135 // \relatesalso vgl_vector_2d
136 template <class T> inline v operator/(v const& a, double s) { return v(T(a.x()/s), T(a.y()/s)); }
137 
138 //: a*=f: scale the vector.
139 // \relatesalso vgl_vector_2d
140 template <class T> inline v& operator*=(v& a, double s) { a.set(T(a.x()*s), T(a.y()*s)); return a; }
141 
142 //: a/=f: inversely scale the vector (scale must be nonzero).
143 // \relatesalso vgl_vector_2d
144 template <class T> inline v& operator/=(v& a, double s) { a.set(T(a.x()/s), T(a.y()/s)); return a; }
145 
146 //: dot product or inner product of two vectors.
147 // \relatesalso vgl_vector_2d
148 template <class T> inline T dot_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y(); }
149 
150 //: dot product or inner product of two vectors.
151 // \relatesalso vgl_vector_2d
152 template <class T> inline T inner_product(v const& a, v const& b) { return a.x()*b.x()+a.y()*b.y(); }
153 
154 //: cross product of two vectors (area of enclosed parallellogram).
155 // \relatesalso vgl_vector_2d
156 template <class T> inline T cross_product(v const& a, v const& b) { return a.x()*b.y()-a.y()*b.x(); }
157 
158 //: cosine of the angle between two vectors.
159 // \relatesalso vgl_vector_2d
160 template <class T> inline double cos_angle(v const& a, v const& b) { return inner_product(a,b)/(a.length()*b.length()); }
161 
162 //: smallest angle between two vectors (in radians, between 0 and Pi).
163 // \relatesalso vgl_vector_2d
164 template <class T> double angle(v const& a, v const& b); // return acos(cos_angle(a,b));
165 
166 //: signed angle between two vectors (in radians, between -Pi and Pi).
167 // return the rotation angle to go from `a' to `b'
168 // \relatesalso vgl_vector_2d
169 template <class T> double signed_angle(v const& a, v const& b);
170 
171 //: are two vectors orthogonal, i.e., is their dot product zero?
172 // If the third argument is specified, it is taken as the "tolerance", i.e.
173 // in that case this function returns true if the vectors are almost orthogonal.
174 // \relatesalso vgl_vector_2d
175 template <class T> bool orthogonal(v const& a, v const& b, double eps=0.0);
176 
177 //: are two vectors parallel, i.e., is one a scalar multiple of the other?
178 // If the third argument is specified, it is taken as the "tolerance", i.e.
179 // in that case this function returns true if the vectors are almost parallel.
180 // \relatesalso vgl_vector_2d
181 template <class T> bool parallel(v const& a, v const& b, double eps=0.0);
182 
183 //: f=a/b: return the ratio of two vectors, if they are parallel.
184 // (If not, return a "least squares" approximation.)
185 // Note that the return type is double, not T, since the ratio of e.g.
186 // two vgl_vector_2d<int> need not be an int.
187 // \relatesalso vgl_vector_2d
188 template <class T> inline double operator/(v const& a, v const& b)
189 { return dot_product(a,b)/(double)dot_product(b,b); }
190 
191 //: Normalise by dividing through by the length, thus returning a length 1 vector.
192 // If a is zero length, return (0,0).
193 // \relatesalso vgl_vector_2d
194 template <class T> inline v& normalize(v& a) { double l=a.length(); return l?a/=l:a; }
195 
196 //: Return a normalised version of a.
197 // If a is zero length, return (0,0).
198 // \relatesalso vgl_vector_2d
199 template <class T> inline v normalized(v const& a) { double l=a.length(); return l?a/l:a; }
200 
201 //: Return a CCW rotated version of a (angle in radian)
202 // \relatesalso vgl_vector_2d
203 template <class T> v rotated(v const& a, double angle);
204 
205 #undef v
206 
207 #define VGL_VECTOR_2D_INSTANTIATE(T) extern "please include vgl/vgl_vector_2d.hxx first"
208 
209 #endif // vgl_vector_2d_h_
std::istream & read(std::istream &is)
Read from stream, possibly with formatting.
v normalized(v const &a)
Return a normalised version of a.
T dot_product(v const &a, v const &b)
dot product or inner product of two vectors.
T inner_product(v const &a, v const &b)
dot product or inner product of two vectors.
v & operator/=(v &a, double s)
a/=f: inversely scale the vector (scale must be nonzero).
Direction vector in Euclidean 2D space, templated by type of element.
Definition: vgl_fwd.h:12
v & normalize(v &a)
Normalise by dividing through by the length, thus returning a length 1 vector.
vgl_homg_point_1d< T > & operator-=(vgl_homg_point_1d< T > &p, T v)
Subtracting a number from a point is the same as adding the inverse number.
v & operator *=(v &a, double s)
a*=f: scale the vector.
T sqr_length() const
Return the squared length of this vector.
Definition: vgl_vector_2d.h:65
T y() const
Definition: vgl_vector_2d.h:36
vgl_homg_point_1d< T > & operator+=(vgl_homg_point_1d< T > &p, T v)
Adding a number to a 1-D point translates that point.
bool orthogonal(v const &a, v const &b, double eps=0.0)
are two vectors orthogonal, i.e., is their dot product zero?.
double length() const
Return the length of this vector.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_vector_2d(T vx, T vy)
Creates the vector (x,y).
Definition: vgl_vector_2d.h:42
v rotated(v const &a, double angle)
Return a CCW rotated version of a (angle in radian).
void set(T vx, T vy)
Assignment.
Definition: vgl_vector_2d.h:55
double length(v const &a)
Return the length of a vector.
Definition: vgl_vector_2d.h:94
#define v
Definition: vgl_vector_2d.h:74
vgl_vector_2d()
Creates the vector (0,0) of zero length.
Definition: vgl_vector_2d.h:39
T cross_product(v const &a, v const &b)
cross product of two vectors (area of enclosed parallellogram).
v operator/(v const &a, double s)
c=b/f: return an inversely scaled version of the vector (scale must be nonzero).
vgl_homg_point_1d< T > operator+(vgl_homg_point_1d< T > const &p, T v)
Adding a number to a 1-D point translates that point.
double signed_angle(v const &a, v const &b)
signed angle between two vectors (in radians, between -Pi and Pi).
bool operator==(vgl_vector_2d< T >const &v) const
Comparison.
Definition: vgl_vector_2d.h:58
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).
#define l
vgl_homg_point_1d< T > operator *(vnl_matrix_fixed< T, 2, 2 > const &m, vgl_homg_point_1d< T > const &p)
Transform a point through a 2x2 projective transformation matrix.
T x() const
Definition: vgl_vector_2d.h:35
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?.
bool operator!=(vgl_vector_2d< T >const &v) const
Definition: vgl_vector_2d.h:59
double cos_angle(v const &a, v const &b)
cosine of the angle between two vectors.
T operator-(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2)
The difference of two points is the distance between the two.