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