vgl_homg_point_1d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_homg_point_1d.h
2 #ifndef vgl_homg_point_1d_h_
3 #define vgl_homg_point_1d_h_
4 //:
5 // \file
6 // \brief a point in homogeneous 1-D space, i.e., a homogeneous pair \a (x,w)
7 // \author Peter Vanroose
8 // \date 8 July 2001
9 //
10 // \verbatim
11 // Modifications
12 // \endverbatim
13 
14 #include <iosfwd>
15 #include <vector>
16 #ifdef _MSC_VER
17 # include <vcl_msvc_warnings.h>
18 #endif
19 #include <cassert>
20 
21 //: Represents a homogeneous 1-D point, i.e., a homogeneous pair \a (x,w)
22 template <class T>
24 {
25  T x_;
26  T w_;
27 
28  public:
29  //: Default constructor with (0,1)
30  inline vgl_homg_point_1d() : x_(0), w_(T(1)) {}
31 
32  //: Construct from one (nonhomogeneous) or two (homogeneous) T's.
33  inline vgl_homg_point_1d(T px, T pw = T(1)) : x_(px), w_(pw) {}
34 
35  //: Construct from homogeneous 2-array.
36  inline vgl_homg_point_1d(const T v[2]) : x_(v[0]), w_(v[1]) {}
37 
38 #if 0 // the compiler defaults are better...
39  // Default copy constructor
40  inline vgl_homg_point_1d(const vgl_homg_point_1d<T>& that) : x_(p.x()), w_(p.w()) {}
41 
42  // Destructor
43  inline ~vgl_homg_point_1d() {}
44 
45  // Default assignment operator
46  inline vgl_homg_point_1d<T>& operator=(const vgl_homg_point_1d<T>& p) {
47  set(p.x(),p.w()); return *this; }
48 #endif
49 
50  //: comparison
51  inline bool operator==(vgl_homg_point_1d<T> const& p) const {
52  return this==&p || x()*p.w() == w()*p.x(); }
53  inline bool operator!=(vgl_homg_point_1d<T> const& p)const { return !operator==(p); }
54 
55  // Data Access-------------------------------------------------------------
56 
57  inline T x() const { return x_; }
58  inline T w() const { return w_; }
59 
60  //: Set \a x,w
61  // Note that it does not make sense to set \a x or \a w individually.
62  inline void set(T px, T pw) { x_ = px, w_ = pw; }
63  inline void set(T const p[2]) { x_ = p[0]; w_ = p[1]; }
64 
65  //: Return true iff the point is at infinity (an ideal point).
66  // The method checks whether |w| <= tol * |x|
67  inline bool ideal(T tol = T(0)) const {
68 #define vgl_Abs(x) ((x)<0?-(x):(x)) // avoid #include of vcl_cmath.h AND vcl_cstdlib.h
69  return vgl_Abs(w()) <= tol * vgl_Abs(x());
70 #undef vgl_Abs
71  }
72 };
73 
74 // +-+-+ point_1d simple I/O +-+-+
75 
76 //: Write "<vgl_homg_point_1d (x,w) > " to stream
77 // \relatesalso vgl_homg_point_1d
78 template <class T>
79 std::ostream& operator<<(std::ostream& s, vgl_homg_point_1d<T> const& p);
80 
81 //: Read x w from stream
82 // \relatesalso vgl_homg_point_1d
83 template <class T>
84 std::istream& operator>>(std::istream& s, vgl_homg_point_1d<T>& p);
85 
86 // +-+-+ homg_point_1d arithmetic +-+-+
87 
88 //: Return true iff the point is at infinity (an ideal point).
89 // The method checks whether |w| <= tol * |x|
90 // \relatesalso vgl_homg_point_1d
91 template <class T> inline
92 bool is_ideal(vgl_homg_point_1d<T> const& p, T tol = T(0)) { return p.ideal(tol); }
93 
94 //: The difference of two points is the distance between the two.
95 // This function is only valid if the points are not at infinity.
96 // \relatesalso vgl_homg_point_1d
97 template <class T> inline
99  vgl_homg_point_1d<T> const& p2) {
100  assert(p1.w() && p2.w());
101  return p1.x()/p1.w()-p2.x()/p2.w();
102 }
103 
104 //: Adding a number to a 1-D point translates that point.
105 // If the point is at infinity, nothing happens.
106 // Note that number + point is not defined! It's always point + number.
107 // \relatesalso vgl_homg_point_1d
108 template <class T> inline
110 { return vgl_homg_point_1d<T>(p.x()+v*p.w(), p.w()); }
111 
112 //: Adding a number to a 1-D point translates that point.
113 // If the point is at infinity, nothing happens.
114 // \relatesalso vgl_homg_point_1d
115 template <class T> inline
117 { p.set(p.x()+v*p.w(), p.w()); return p; }
118 
119 //: Subtracting a number from a point is the same as adding the inverse number
120 // \relatesalso vgl_homg_point_1d
121 template <class T> inline
123 { return p + (-v); }
124 
125 //: Subtracting a number from a point is the same as adding the inverse number
126 // \relatesalso vgl_homg_point_1d
127 template <class T> inline
129 { return p += (-v); }
130 
131 // +-+-+ homg_point_1d geometry +-+-+
132 
133 //: cross ratio of four points
134 // This number is projectively invariant, and it is the coordinate of p4
135 // in the reference frame where p2 is the origin (coordinate 0), p3 is
136 // the unity (coordinate 1) and p1 is the point at infinity.
137 // This cross ratio is often denoted as ((p1, p2; p3, p4)) (which also
138 // equals ((p3, p4; p1, p2)) or ((p2, p1; p4, p3)) or ((p4, p3; p2, p1)) )
139 // and is calculated as
140 // \verbatim
141 // p1 - p3 p2 - p3 (p1-p3)(p2-p4)
142 // ------- : -------- = --------------
143 // p1 - p4 p2 - p4 (p1-p4)(p2-p3)
144 // \endverbatim
145 // If three of the given points coincide, the cross ratio is not defined.
146 // \relatesalso vgl_homg_point_1d
147 
148 template <class T> inline
150  vgl_homg_point_1d<T>const& p3, vgl_homg_point_1d<T>const& p4)
151 { return (p1.x()*p3.w()-p3.x()*p1.w())*(p2.x()*p4.w()-p4.x()*p2.w())
152  /((p1.x()*p4.w()-p4.x()*p1.w())*(p2.x()*p3.w()-p3.x()*p2.w())); }
153 
154 //: Return the relative distance to p1 wrt p1-p2 of p3.
155 // p2 should not equal p1.
156 // This is the coordinate of p3 in the affine 1D reference frame (p1,p2).
157 // If p3=p1, the ratio is 0; if p1=p3, the ratio is 1.
158 // The mid point of p1 and p2 has ratio 0.5.
159 // Note that the return type is double, not T, since the ratio of e.g.
160 // two int's need not be an int.
161 // \relatesalso vgl_homg_point_1d
162 template <class T> inline
163 double ratio(vgl_homg_point_1d<T> const& p1,
164  vgl_homg_point_1d<T> const& p2,
165  vgl_homg_point_1d<T> const& p3)
166 { return (p3-p1)/(p2-p1); }
167 
168 //: Are three points collinear? This is always true.
169 // \relatesalso vgl_homg_point_1d
170 template <class T> inline
172  vgl_homg_point_1d<T> const&,
173  vgl_homg_point_1d<T> const&)
174 { return true; }
175 
176 //: Return the point at a given ratio wrt two other points.
177 // By default, the mid point (ratio=0.5) is returned.
178 // Note that the third argument is T, not double, so the midpoint of e.g.
179 // two vgl_homg_point_1d<int> is not a valid concept. But the reflection point
180 // of p2 wrt p1 is: in that case f=-1.
181 // \relatesalso vgl_homg_point_1d
182 template <class T> inline
184  vgl_homg_point_1d<T> const& p2,
185  T f = 0.5)
186 { return p1 + f*(p2-p1); }
187 
188 //: Return the point at the centre of gravity of two given points.
189 // Identical to midpoint(p1,p2).
190 // If one point or both points are at infinity, that point is returned.
191 // \relatesalso vgl_homg_point_1d
192 template <class T> inline
194  vgl_homg_point_1d<T> const& p2)
195 {
196  if (p1 == p2) return p1;
197  return vgl_homg_point_1d<T> (p1.x()*p2.w() + p2.x()*p1.w(), p1.w()*p2.w()*2);
198 }
199 
200 //: Return the point at the centre of gravity of a set of given points.
201 // There are no rounding errors when T is e.g. int, if all w() are 1.
202 // \relatesalso vgl_homg_point_1d
203 template <class T> inline
205 {
206  int n=v.size();
207  assert(n>0); // it is *not* correct to return the point (0,1) when n==0.
208  T x = 0;
209  for (int i=0; i<n; ++i) x+=v[i].x()/v[i].w();
210  return vgl_homg_point_1d<T>(x,T(n));
211 }
212 
213 #define VGL_HOMG_POINT_1D_INSTANTIATE(T) extern "please include vgl/vgl_homg_point_1d.hxx first"
214 
215 #endif // vgl_homg_point_1d_h_
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_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.
void set(T px, T pw)
Set x,w.
#define v
Definition: vgl_vector_2d.h:74
bool operator!=(vgl_homg_point_1d< T > const &p) const
vgl_homg_point_1d(const T v[2])
Construct from homogeneous 2-array.
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_1d< T > const &p) const
comparison.
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 is_ideal(l const &line, T tol=(T) 0)
Return true iff line is the line at infinity.
bool ideal(T tol=T(0)) const
Return true iff the point is at infinity (an ideal point).
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
void set(T const p[2])
Represents a homogeneous 1-D point, i.e., a homogeneous pair (x,w).
Definition: vgl_fwd.h:7
vgl_homg_point_1d()
Default constructor with (0,1).
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.
vgl_homg_point_1d(T px, T pw=T(1))
Construct from one (nonhomogeneous) or two (homogeneous) T's.