vgl_homg_point_2d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_homg_point_2d.h
2 #ifndef vgl_homg_point_2d_h_
3 #define vgl_homg_point_2d_h_
4 //:
5 // \file
6 // \brief point in projective 2D space
7 // \author Don HAMILTON, Peter TU
8 //
9 // \verbatim
10 // Modifications
11 // Peter Vanroose - 4 July 2001 - Added geometric interface like vgl_point_2d
12 // Peter Vanroose - 1 July 2001 - Renamed data to x_ y_ w_, inlined constructors
13 // Peter Vanroose - 27 June 2001 - Added operator==
14 // \endverbatim
15 
16 #include <iosfwd>
17 #include <vgl/vgl_vector_2d.h>
18 #include <vgl/vgl_point_2d.h>
19 #include <vgl/vgl_fwd.h> // forward declare vgl_homg_line_2d
20 #ifdef _MSC_VER
21 # include <vcl_msvc_warnings.h>
22 #endif
23 #include <cassert>
24 
25 //: Represents a homogeneous 2D point
26 template <class T>
28 {
29  // the data associated with this point
30  T x_;
31  T y_;
32  T w_;
33 
34  public:
35 
36  // Constructors/Initializers/Destructor------------------------------------
37 
38  //: Default constructor with (0,0,1)
39  inline vgl_homg_point_2d() : x_(0), y_(0), w_((T)1) {}
40 
41  //: Construct from two (nonhomogeneous) or three (homogeneous) Types.
42  inline vgl_homg_point_2d(T px, T py, T pw = (T)1)
43  : x_(px), y_(py), w_(pw) {}
44 
45  //: Construct from homogeneous 3-array.
46  inline vgl_homg_point_2d(const T v[3]) : x_(v[0]), y_(v[1]), w_(v[2]) {}
47 
48  //: Construct point at infinity from direction vector.
49  inline vgl_homg_point_2d(vgl_vector_2d<T>const& v) : x_(v.x()), y_(v.y()), w_(0) {}
50 
51  //: Construct from (non-homogeneous) vgl_point_2d<T>
52  inline explicit vgl_homg_point_2d(vgl_point_2d<T> const& p)
53  : x_(p.x()), y_(p.y()), w_((T)1) {}
54 
55  //: Construct from 2 lines (intersection).
57  vgl_homg_line_2d<T> const& l2);
58 
59 #if 0
60  // Default copy constructor
62  : x_(p.x()), y_(p.y()), w_(p.w()) {}
63 
64  // Destructor
65  inline ~vgl_homg_point_2d() {}
66 
67  // Default assignment operator
68  inline vgl_homg_point_2d<T>& operator=(vgl_homg_point_2d<T>const& p)
69  {
70  set(p.x(),p.y(),p.w());
71  return *this;
72  }
73 #endif
74 
75  //: the comparison operator
76  inline bool operator==(vgl_homg_point_2d<T> const& p) const
77  {
78  return (this==&p) ||
79  (x()*p.w()==w()*p.x() && y()*p.w()==w()*p.y() && y()*p.x()==x()*p.y());
80  }
81 
82  inline bool operator!=(vgl_homg_point_2d<T> const& other)const{return !operator==(other);}
83 
84  // Data Access-------------------------------------------------------------
85 
86  inline T x() const { return x_; }
87  inline T y() const { return y_; }
88  inline T w() const { return w_; }
89 
90  //: Set \a x,y,w
91  // Note that it does not make sense to set \a x, \a y or \a w individually.
92  inline void set(T px, T py, T pw = (T)1)
93  { x_ = px, y_ = py, w_ = pw; }
94 
95  inline void set(T const p[3]) { x_ = p[0]; y_ = p[1]; w_ = p[2]; }
96 
97  //: Return true iff the point is at infinity (an ideal point).
98  // The method checks whether |w| <= tol * max(|x|,|y|)
99  inline bool ideal(T tol = (T)0) const
100  {
101 #define vgl_Abs(x) ((x)<0?-(x):(x)) // avoid #include of vcl_cmath.h AND vcl_cstdlib.h
102  return vgl_Abs(w()) <= tol * vgl_Abs(x()) ||
103  vgl_Abs(w()) <= tol * vgl_Abs(y());
104 #undef vgl_Abs
105  }
106 };
107 
108 // +-+-+ point_2d simple I/O +-+-+
109 
110 //: Write "<vgl_homg_point_2d (x,y,w) >" to stream
111 // \relatesalso vgl_homg_point_2d
112 template <class T>
113 std::ostream& operator<<(std::ostream& s, vgl_homg_point_2d<T> const& p);
114 
115 //: Read x y w from stream
116 // \relatesalso vgl_homg_point_2d
117 template <class T>
118 std::istream& operator>>(std::istream& s, vgl_homg_point_2d<T>& p);
119 
120 // +-+-+ homg_point_2d arithmetic +-+-+
121 
122 //: Return true iff the point is at infinity (an ideal point).
123 // The method checks whether |w| <= tol * max(|x|,|y|)
124 // \relatesalso vgl_homg_point_2d
125 template <class T> inline
126 bool is_ideal(vgl_homg_point_2d<T> const& p, T tol=(T)0){return p.ideal(tol);}
127 
128 //: The difference of two points is the vector from second to first point
129 // This function is only valid if the points are not at infinity.
130 // \relatesalso vgl_homg_point_2d
131 template <class T> inline
133  vgl_homg_point_2d<T> const& p2)
134 {
135  assert(p1.w() && p2.w());
136  return vgl_vector_2d<T>(p1.x()/p1.w()-p2.x()/p2.w(),
137  p1.y()/p1.w()-p2.y()/p2.w());
138 }
139 
140 //: Adding a vector to a point gives a new point at the end of that vector
141 // If the point is at infinity, nothing happens.
142 // Note that vector + point is not defined! It's always point + vector.
143 // \relatesalso vgl_homg_point_2d
144 template <class T> inline
146  vgl_vector_2d<T> const& v)
147 { return vgl_homg_point_2d<T>(p.x()+v.x()*p.w(), p.y()+v.y()*p.w(), p.w()); }
148 
149 //: Adding a vector to a point gives the point at the end of that vector
150 // If the point is at infinity, nothing happens.
151 // \relatesalso vgl_homg_point_2d
152 template <class T> inline
154  vgl_vector_2d<T> const& v)
155 { p.set(p.x()+v.x()*p.w(), p.y()+v.y()*p.w(), p.w()); return p; }
156 
157 //: Subtracting a vector from a point is the same as adding the inverse vector
158 // \relatesalso vgl_homg_point_2d
159 template <class T> inline
161  vgl_vector_2d<T> const& v)
162 { return p + (-v); }
163 
164 //: Subtracting a vector from a point is the same as adding the inverse vector
165 // \relatesalso vgl_homg_point_2d
166 template <class T> inline
168  vgl_vector_2d<T> const& v)
169 { return p += (-v); }
170 
171 // +-+-+ homg_point_2d geometry +-+-+
172 
173 //: cross ratio of four collinear points
174 // This number is projectively invariant, and it is the coordinate of p4
175 // in the reference frame where p2 is the origin (coordinate 0), p3 is
176 // the unity (coordinate 1) and p1 is the point at infinity.
177 // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
178 // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
179 // and is calculated as
180 // \verbatim
181 // p1 - p3 p2 - p3 (p1-p3)(p2-p4)
182 // ------- : -------- = --------------
183 // p1 - p4 p2 - p4 (p1-p4)(p2-p3)
184 // \endverbatim
185 // If three of the given points coincide, the cross ratio is not defined.
186 //
187 // In this implementation, a least-squares result is calculated when the
188 // points are not exactly collinear.
189 // \relatesalso vgl_homg_point_2d
190 //
191 template <class T>
192 double cross_ratio(vgl_homg_point_2d<T>const& p1, vgl_homg_point_2d<T>const& p2,
193  vgl_homg_point_2d<T>const& p3, vgl_homg_point_2d<T>const& p4);
194 
195 //: Are three points collinear, i.e., do they lie on a common line?
196 // \relatesalso vgl_homg_point_2d
197 template <class T> inline
199  vgl_homg_point_2d<T> const& p2,
200  vgl_homg_point_2d<T> const& p3)
201 {
202  return (p1.x()*p2.y()-p1.y()*p2.x())*p3.w()
203  +(p3.x()*p1.y()-p3.y()*p1.x())*p2.w()
204  +(p2.x()*p3.y()-p2.y()*p3.x())*p1.w()==0;
205 }
206 
207 //: Return the relative distance to p1 wrt p1-p2 of p3.
208 // The three points should be collinear and p2 should not equal p1.
209 // This is the coordinate of p3 in the affine 1D reference frame (p1,p2).
210 // If p3=p1, the ratio is 0; if p1=p3, the ratio is 1.
211 // The mid point of p1 and p2 has ratio 0.5.
212 // Note that the return type is double, not T, since the ratio of e.g.
213 // two vgl_vector_2d<int> need not be an int.
214 // \relatesalso vgl_homg_point_2d
215 template <class T> inline
216 double ratio(vgl_homg_point_2d<T> const& p1,
217  vgl_homg_point_2d<T> const& p2,
218  vgl_homg_point_2d<T> const& p3)
219 { return (p3-p1)/(p2-p1); }
220 
221 //: Return the point at a given ratio wrt two other points.
222 // By default, the mid point (ratio=0.5) is returned.
223 // Note that the third argument is T, not double, so the midpoint of e.g.
224 // two vgl_homg_point_2d<int> is not a valid concept. But the reflection point
225 // of p2 wrt p1 is: in that case f=-1.
226 template <class T> inline
228  vgl_homg_point_2d<T> const& p2,
229  T f = (T)0.5)
230 { return p1 + f*(p2-p1); }
231 
232 
233 //: Return the point at the centre of gravity of two given points.
234 // Identical to midpoint(p1,p2).
235 // Invalid when both points are at infinity.
236 // If only one point is at infinity, that point is returned.
237 // \relatesalso vgl_homg_point_2d
238 template <class T> inline
240  vgl_homg_point_2d<T> const& p2)
241 {
242  return vgl_homg_point_2d<T>(p1.x()*p2.w() + p2.x()*p1.w(),
243  p1.y()*p2.w() + p2.y()*p1.w(),
244  p1.w()*p2.w()*2 );
245 }
246 
247 //: Return the point at the centre of gravity of a set of given points.
248 // There are no rounding errors when T is e.g. int, if all w() are 1.
249 // \relatesalso vgl_homg_point_2d
250 template <class T> inline
252 {
253  int n=v.size();
254  assert(n>0); // it is *not* correct to return the point (0,0) when n==0.
255  T x = 0, y = 0;
256  for (int i=0; i<n; ++i) x+=v[i].x()/v[i].w(), y+=v[i].y()/v[i].w();
257  return vgl_homg_point_2d<T>(x,y,(T)n);
258 }
259 
260 #define VGL_HOMG_POINT_2D_INSTANTIATE(T) extern "please include vgl/vgl_homg_point_2d.hxx first"
261 
262 #endif // vgl_homg_point_2d_h_
void set(T const p[3])
vgl_homg_point_1d< T > centre(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2)
Return the point at the centre of gravity of two given points.
a point in 2D nonhomogeneous space
Represents a homogeneous 2D line.
Definition: vgl_fwd.h:14
Direction vector in Euclidean 2D space, templated by type of element.
Definition: vgl_fwd.h:12
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.
bool ideal(T tol=(T) 0) const
Return true iff the point is at infinity (an ideal point).
double cross_ratio(vgl_homg_point_1d< T >const &p1, vgl_homg_point_1d< T >const &p2, vgl_homg_point_1d< T >const &p3, vgl_homg_point_1d< T >const &p4)
cross ratio of four points.
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.
#define vgl_Abs(x)
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_homg_point_2d(vgl_vector_2d< T >const &v)
Construct point at infinity from direction vector.
#define v
Definition: vgl_vector_2d.h:74
bool collinear(l const &l1, vgl_homg_point_3d< Type > const &p)
Does a line pass through a point, i.e., are the point and the line collinear?.
bool operator==(vgl_homg_point_2d< T > const &p) const
the comparison operator.
vgl_homg_point_2d(T px, T py, T pw=(T) 1)
Construct from two (nonhomogeneous) or three (homogeneous) Types.
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 ratio(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2, vgl_homg_point_1d< T > const &p3)
Return the relative distance to p1 wrt p1-p2 of p3.
bool operator!=(vgl_homg_point_2d< T > const &other) const
bool is_ideal(l const &line, T tol=(T) 0)
Return true iff line is the line at infinity.
direction vector in Euclidean 2D space
void set(T px, T py, T pw=(T) 1)
Set x,y,w.
vgl_homg_point_2d(const T v[3])
Construct from homogeneous 3-array.
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
vgl_homg_point_2d(vgl_point_2d< T > const &p)
Construct from (non-homogeneous) vgl_point_2d<T>.
vgl_homg_point_2d()
Default constructor with (0,0,1).
Represents a homogeneous 2D point.
Definition: vgl_fwd.h:8
vgl_homg_point_1d< T > midpoint(vgl_homg_point_1d< T > const &p1, vgl_homg_point_1d< T > const &p2, T f=0.5)
Return the point at a given ratio wrt two other points.
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.