vgl_point_2d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_point_2d.h
2 #ifndef vgl_point_2d_h
3 #define vgl_point_2d_h
4 //:
5 // \file
6 // \brief a point in 2D nonhomogeneous space
7 // \author Don Hamilton, Peter Tu
8 //
9 // \verbatim
10 // Modifications
11 // 29 June 2001 Peter Vanroose moved arithmetic operators to new vgl_vector_2d
12 // 2 July 2001 Peter Vanroose implemented constructor from homg point
13 // 21 May 2009 Peter Vanroose istream operator>> re-implemented
14 // \endverbatim
15 
16 #include <iosfwd>
17 #include <vector>
18 #ifdef _MSC_VER
19 # include <vcl_msvc_warnings.h>
20 #endif
21 #include <vgl/vgl_fwd.h> // declare vgl_homg_point_2d and vgl_line_2d
22 #include <vgl/vgl_vector_2d.h>
23 #include <cassert>
24 
25 //: Represents a cartesian 2D point
26 template <class Type>
27 class vgl_point_2d
28 {
29  // the data associated with this point
30  Type x_;
31  Type y_;
32 
33  public:
34 
35  // Constructors/Initializers/Destructor------------------------------------
36 
37  //: Default constructor
38  inline vgl_point_2d () = default;
39 
40  //: Construct from two Types.
41  inline vgl_point_2d (Type px, Type py) : x_(px), y_(py) {}
42 
43  //: Construct from 2-array.
44  inline vgl_point_2d (Type const v[2]) : x_(v[0]), y_(v[1]) {}
45 
46  //: Construct from homogeneous point
48 
49  //: Construct from 2 lines (intersection).
51  vgl_line_2d<Type> const& l2);
52 
53 #if 0 // The compiler defaults for these are doing what they should do:
54  //: Copy constructor
55  inline vgl_point_2d(vgl_point_2d<Type> const& p) : x_(p.x()), y_(p.y()) {}
56  //: Destructor
57  inline ~vgl_point_2d () {}
58  //: Assignment
59  inline vgl_point_2d<Type>& operator=(const vgl_point_2d<Type>& p)
60  { x_ = p.x(); y_ = p.y(); return *this; }
61 #endif
62 
63  //: Test for equality
64  inline bool operator==(vgl_point_2d<Type>const& p) const
65  { return this==&p || (x_==p.x() && y_==p.y()); }
66  inline bool operator!=(vgl_point_2d<Type>const& p)const
67  { return !operator==(p); }
68 
69  // Data Access-------------------------------------------------------------
70 
71  inline Type &x() {return x_;}
72  inline Type &y() {return y_;}
73 
74  inline Type x() const {return x_;}
75  inline Type y() const {return y_;}
76 
77  //: Set \a x and \a y
78  // Note that \a x and \a y can also be set individually.
79  inline void set (Type px, Type py){ x_ = px; y_ = py; }
80  //: Set \a x and \a y
81  // Note that \a x and \a y can also be set individually.
82  inline void set (Type const p[2]) { x_ = p[0]; y_ = p[1]; }
83 
84  //: Return true iff the point is at infinity (an ideal point).
85  // Always returns false.
86  inline bool ideal(Type = (Type)0) const { return false; }
87 
88  //: Read from stream, possibly with formatting
89  // Either just reads two blank-separated numbers,
90  // or reads two comma-separated numbers,
91  // or reads two numbers in parenthesized form "(123, 321)"
92  std::istream& read(std::istream& is);
93 };
94 
95 // +-+-+ point_2d simple I/O +-+-+
96 
97 //: Write "<vgl_point_2d x,y>" to stream
98 // \relatesalso vgl_point_2d
99 template <class Type>
100 std::ostream& operator<<(std::ostream& s, vgl_point_2d<Type> const& p);
101 
102 //: Read from stream, possibly with formatting
103 // Either just reads two blank-separated numbers,
104 // or reads two comma-separated numbers,
105 // or reads two numbers in parenthesized form "(123, 321)"
106 // \relatesalso vgl_point_2d
107 template <class Type>
108 std::istream& operator>>(std::istream& s, vgl_point_2d<Type>& p);
109 
110 // +-+-+ point_2d arithmetic +-+-+
111 
112 //: Return true iff the point is at infinity (an ideal point).
113 // Always returns false.
114 template <class Type> inline
115 bool is_ideal(vgl_point_2d<Type> const&, Type = 0) { return false; }
116 
117 //: The difference of two points is the vector from second to first point
118 // \relatesalso vgl_point_2d
119 template <class Type> inline
121  vgl_point_2d<Type> const& p2)
122 { return vgl_vector_2d<Type>(p1.x()-p2.x(), p1.y()-p2.y()); }
123 
124 //: Adding a vector to a point gives a new point at the end of that vector
125 // Note that vector + point is not defined! It's always point + vector.
126 // \relatesalso vgl_point_2d
127 template <class Type> inline
129  vgl_vector_2d<Type> const& v)
130 { return vgl_point_2d<Type>(p.x()+v.x(), p.y()+v.y()); }
131 
132 //: Adding a vector to a point gives the point at the end of that vector
133 // \relatesalso vgl_point_2d
134 template <class Type> inline
136  vgl_vector_2d<Type> const& v)
137 { p.set(p.x()+v.x(), p.y()+v.y()); return p; }
138 
139 //: Subtracting a vector from a point is the same as adding the inverse vector
140 // \relatesalso vgl_point_2d
141 template <class Type> inline
143  vgl_vector_2d<Type> const& v)
144 { return p + (-v); }
145 
146 //: Subtracting a vector from a point is the same as adding the inverse vector
147 // \relatesalso vgl_point_2d
148 template <class Type> inline
150  vgl_vector_2d<Type> const& v)
151 { return p += (-v); }
152 
153 // +-+-+ point_2d geometry +-+-+
154 
155 //: cross ratio of four collinear points
156 // This number is projectively invariant, and it is the coordinate of p4
157 // in the reference frame where p2 is the origin (coordinate 0), p3 is
158 // the unity (coordinate 1) and p1 is the point at infinity.
159 // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
160 // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
161 // and is calculated as
162 // \verbatim
163 // p1 - p3 p2 - p3 (p1-p3)(p2-p4)
164 // ------- : -------- = --------------
165 // p1 - p4 p2 - p4 (p1-p4)(p2-p3)
166 // \endverbatim
167 // If three of the given points coincide, the cross ratio is not defined.
168 //
169 // In this implementation, a least-squares result is calculated when the
170 // points are not exactly collinear.
171 //
172 // \relatesalso vgl_point_2d
173 template <class T>
174 double cross_ratio(vgl_point_2d<T>const& p1, vgl_point_2d<T>const& p2,
175  vgl_point_2d<T>const& p3, vgl_point_2d<T>const& p4);
176 
177 //: Are three points collinear, i.e., do they lie on a common line?
178 // \relatesalso vgl_point_2d
179 template <class Type> inline
181  vgl_point_2d<Type> const& p2,
182  vgl_point_2d<Type> const& p3)
183 { return parallel(p1-p2, p1-p3); }
184 
185 //: Return the relative distance to p1 wrt p1-p2 of p3.
186 // The three points should be collinear and p2 should not equal p1.
187 // This is the coordinate of p3 in the affine 1D reference frame (p1,p2).
188 // If p3=p1, the ratio is 0; if p1=p3, the ratio is 1.
189 // The mid point of p1 and p2 has ratio 0.5.
190 // Note that the return type is double, not Type, since the ratio of e.g.
191 // two vgl_vector_2d<int> need not be an int.
192 // \relatesalso vgl_point_2d
193 template <class Type> inline
194 double ratio(vgl_point_2d<Type> const& p1,
195  vgl_point_2d<Type> const& p2,
196  vgl_point_2d<Type> const& p3)
197 { return (p3-p1)/(p2-p1); }
198 
199 //: Return the point at a given ratio wrt two other points.
200 // By default, the mid point (ratio=0.5) is returned.
201 // Note that the third argument is Type, not double, so the midpoint of e.g.
202 // two vgl_point_2d<int> is not a valid concept. But the reflection point
203 // of p2 wrt p1 is: in that case f=-1.
204 // \relatesalso vgl_point_2d
205 template <class Type> inline
207  vgl_point_2d<Type> const& p2,
208  Type f = (Type)0.5)
209 {
210  return vgl_point_2d<Type>((Type)((1-f)*p1.x() + f*p2.x()),
211  (Type)((1-f)*p1.y() + f*p2.y()));
212 }
213 
214 
215 //: Return the point at the centre of gravity of two given points.
216 // Identical to midpoint(p1,p2).
217 // \relatesalso vgl_point_2d
218 template <class Type> inline
220  vgl_point_2d<Type> const& p2)
221 {
222  return vgl_point_2d<Type>((p1.x() + p2.x())/2 ,
223  (p1.y() + p2.y())/2 );
224 }
225 
226 //: Return the point at the centre of gravity of three given points.
227 // \relatesalso vgl_point_2d
228 template <class Type> inline
230  vgl_point_2d<Type> const& p2,
231  vgl_point_2d<Type> const& p3)
232 {
233  return vgl_point_2d<Type>((p1.x() + p2.x() + p3.x())/3 ,
234  (p1.y() + p2.y() + p3.y())/3 );
235 }
236 
237 //: Return the point at the centre of gravity of four given points.
238 // \relatesalso vgl_point_2d
239 template <class Type> inline
241  vgl_point_2d<Type> const& p2,
242  vgl_point_2d<Type> const& p3,
243  vgl_point_2d<Type> const& p4)
244 {
245  return vgl_point_2d<Type>((p1.x() + p2.x() + p3.x() + p4.x())/4 ,
246  (p1.y() + p2.y() + p3.y() + p4.y())/4 );
247 }
248 
249 //: Return the point at the centre of gravity of a set of given points.
250 // Beware of possible rounding errors when Type is e.g. int.
251 // \relatesalso vgl_point_2d
252 template <class Type> inline
254 {
255  int n=v.size();
256  assert(n>0); // it is *not* correct to return the point (0,0) when n==0.
257  Type x = 0, y = 0;
258  for (int i=0; i<n; ++i) x+=v[i].x(), y+=v[i].y();
259  return vgl_point_2d<Type>(x/n,y/n);
260 }
261 
262 #define VGL_POINT_2D_INSTANTIATE(T) extern "please include vgl/vgl_point_2d.hxx first"
263 
264 #endif // vgl_point_2d_h
bool operator!=(vgl_point_2d< Type >const &p) const
Definition: vgl_point_2d.h:66
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.
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.
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_point_2d()=default
Default constructor.
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 operator==(vgl_point_2d< Type >const &p) const
Test for equality.
Definition: vgl_point_2d.h:64
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
#define v
Definition: vgl_vector_2d.h:74
bool ideal(Type=(Type) 0) const
Return true iff the point is at infinity (an ideal point).
Definition: vgl_point_2d.h:86
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?.
void set(Type px, Type py)
Set x and y.
Definition: vgl_point_2d.h:79
Represents a Euclidean 2D line.
Definition: vgl_fwd.h:16
Type & y()
Definition: vgl_point_2d.h:72
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.
Type y() const
Definition: vgl_point_2d.h:75
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 is_ideal(l const &line, T tol=(T) 0)
Return true iff line is the line at infinity.
direction vector in Euclidean 2D space
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
vgl_point_2d(Type const v[2])
Construct from 2-array.
Definition: vgl_point_2d.h:44
void set(Type const p[2])
Set x and y.
Definition: vgl_point_2d.h:82
Represents a cartesian 2D point.
Definition: vgl_area.h:7
vgl_point_2d(Type px, Type py)
Construct from two Types.
Definition: vgl_point_2d.h:41
Type x() const
Definition: vgl_point_2d.h:74
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?.
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.
Type & x()
Definition: vgl_point_2d.h:71