vgl_point_3d.hxx
Go to the documentation of this file.
1 // This is core/vgl/vgl_point_3d.hxx
2 #ifndef vgl_point_3d_hxx_
3 #define vgl_point_3d_hxx_
4 //:
5 // \file
6 
7 #include <iostream>
8 #include <string>
9 #include <iomanip>
10 #include <cmath>
11 #include "vgl_point_3d.h"
12 #include <vgl/vgl_homg_point_3d.h>
13 #include <vgl/vgl_plane_3d.h>
14 #include <vgl/vgl_homg_plane_3d.h>
15 #include <vgl/vgl_tolerance.h>
16 
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 //: Construct from homogeneous point
22 template <class Type>
24  : x_(p.x()/p.w()), y_(p.y()/p.w()), z_(p.z()/p.w()) // could be infinite!
25 {
26 }
27 
28 //: Construct from 3 planes (intersection).
29 template <class Type>
31  vgl_plane_3d<Type> const& pl2,
32  vgl_plane_3d<Type> const& pl3)
33 {
34  vgl_homg_plane_3d<Type> h1(pl1.nx(), pl1.ny(), pl1.nz(), pl1.d());
35  vgl_homg_plane_3d<Type> h2(pl2.nx(), pl2.ny(), pl2.nz(), pl2.d());
36  vgl_homg_plane_3d<Type> h3(pl3.nx(), pl3.ny(), pl3.nz(), pl3.d());
37  vgl_homg_point_3d<Type> p(h1, h2, h3); // do homogeneous intersection
38  set(p.x()/p.w(), p.y()/p.w(), p.z()/p.w()); // could be infinite!
39 }
40 
41 template <class Type>
43 {
44  return this==&p || (x_>=p.x()-vgl_tolerance<Type>::position && x_<=p.x()+vgl_tolerance<Type>::position &&
47 }
48 
49 template <class Type>
51  vgl_point_3d<Type> const& p2,
52  vgl_point_3d<Type> const& p3,
53  vgl_point_3d<Type> const& p4)
54 {
55  Type r = ( (p1.x()*p2.y()-p1.y()*p2.x())*p3.z()
56  +(p3.x()*p1.y()-p3.y()*p1.x())*p2.z()
57  +(p2.x()*p3.y()-p2.y()*p3.x())*p1.z()
58  +(p1.x()*p4.y()-p1.y()*p4.x())*p2.z()
59  +(p4.x()*p2.y()-p4.y()*p2.x())*p1.z()
60  +(p2.x()*p1.y()-p2.y()*p1.x())*p4.z()
61  +(p3.x()*p4.y()-p3.y()*p4.x())*p1.z()
62  +(p1.x()*p3.y()-p1.y()*p3.x())*p4.z()
63  +(p4.x()*p1.y()-p4.y()*p1.x())*p3.z()
64  +(p3.x()*p2.y()-p3.y()*p2.x())*p4.z()
65  +(p2.x()*p4.y()-p2.y()*p4.x())*p3.z()
66  +(p4.x()*p3.y()-p4.y()*p3.x())*p2.z() );
67  return r <= vgl_tolerance<Type>::point_3d_coplanarity && r >= -vgl_tolerance<Type>::point_3d_coplanarity;
68 }
69 
70 template <class T>
71 double cross_ratio(vgl_point_3d<T>const& p1, vgl_point_3d<T>const& p2,
72  vgl_point_3d<T>const& p3, vgl_point_3d<T>const& p4)
73 {
74  // least squares solution: (Num_x-CR*Den_x)^2 + (Num_y-CR*Den_y)^2 + (Num_z-CR*Den_z)^2 minimal.
75  double Num_x = (p1.x()-p3.x())*(p2.x()-p4.x());
76  double Num_y = (p1.y()-p3.y())*(p2.y()-p4.y());
77  double Num_z = (p1.z()-p3.z())*(p2.z()-p4.z());
78  double Den_x = (p1.x()-p4.x())*(p2.x()-p3.x());
79  double Den_y = (p1.y()-p4.y())*(p2.y()-p3.y());
80  double Den_z = (p1.z()-p4.z())*(p2.z()-p3.z());
81  if (Den_x == Den_y && Den_y == Den_z) return (Num_x+Num_y+Num_z)/3/Den_x;
82  else return (Den_x*Num_x+Den_y*Num_y+Den_z*Num_z)/(Den_x*Den_x+Den_y*Den_y+Den_z*Den_z);
83 }
84 
85 //: Write "<vgl_point_3d x,y,z> " to stream
86 template <class Type>
87 std::ostream& operator<<(std::ostream& s, vgl_point_3d<Type> const& p)
88 {
89  return s << "<vgl_point_3d "<< p.x() << ',' << p.y() << ',' << p.z() << "> ";
90 }
91 
92 //: Read from stream, possibly with formatting
93 // Either just reads three blank-separated numbers,
94 // or reads three comma-separated numbers,
95 // or reads three numbers in parenthesized form "(123, 321, 567)"
96 // \relatesalso vgl_point_3d
97 template <class Type>
98 std::istream& vgl_point_3d<Type>::read(std::istream& is)
99 {
100  if (! is.good()) return is; // (TODO: should throw an exception)
101  bool paren = false;
102  Type tx, ty, tz;
103  is >> std::ws; // jump over any leading whitespace
104  char c;
105  c=is.peek();
106  if(c == '<'){
107  std::string temp;
108  is >> temp;
109  }
110  if (is.eof()) return is; // nothing to be set because of EOF (TODO: should throw an exception)
111  if (is.peek() == '(') { is.ignore(); paren=true; }
112  is >> std::ws >> tx >> std::ws;
113  if (is.eof()) return is;
114  if (is.peek() == ',') is.ignore();
115  is >> std::ws >> ty >> std::ws;
116  if (is.eof()) return is;
117  if (is.peek() == ',') is.ignore();
118  is >> std::ws >> tz >> std::ws;
119  if (paren) {
120  if (is.eof()) return is;
121  if (is.peek() == ')') is.ignore();
122  else return is; // closing parenthesis is missing (TODO: throw an exception)
123  }
124  is >> std::ws;
125  if (is.peek() == '>') is.ignore();
126  set(tx,ty,tz);
127  return is;
128 }
129 
130 //: Read from stream, possibly with formatting
131 // Either just reads three blank-separated numbers,
132 // or reads three comma-separated numbers,
133 // or reads three numbers in parenthesized form "(123, 321, 567)"
134 // \relatesalso vgl_point_3d
135 template <class Type>
136 std::istream& operator>>(std::istream& is, vgl_point_3d<Type>& p)
137 {
138  return p.read(is);
139 }
140 
141 //: Return the "average deviation" of a set of given points from its centre of gravity.
142 // "Average" in the sense of the standard deviation (2-norm, i.e., square root
143 // of sum of squares) of the distances from that centre of gravity.
144 // \relatesalso vgl_point_3d
145 template <class Type>
146 double stddev(std::vector<vgl_point_3d<Type> > const& v)
147 {
148  int n = (int)(v.size());
149  double d = 0.0;
150  if (n<=1) return d;
152  Type cx = c.x(), cy = c.y(), cz = c.z();
153 #define vgl_sqr(x) double((x)*(x))
154  for (int i=0; i<n; ++i)
155  d += vgl_sqr(v[i].x()-cx) + vgl_sqr(v[i].y()-cy) + vgl_sqr(v[i].z()-cz);
156 #undef vgl_sqr
157  return std::sqrt(d);
158 }
159 
160 
161 #undef VGL_POINT_3D_INSTANTIATE
162 #define VGL_POINT_3D_INSTANTIATE(T) \
163 template class vgl_point_3d<T >; \
164 template double cross_ratio(vgl_point_3d<T >const&, vgl_point_3d<T >const&, \
165  vgl_point_3d<T >const&, vgl_point_3d<T >const&); \
166 template bool coplanar(vgl_point_3d<T > const&, vgl_point_3d<T > const&, \
167  vgl_point_3d<T > const&, vgl_point_3d<T > const&); \
168 template std::ostream& operator<<(std::ostream&, const vgl_point_3d<T >&); \
169 template std::istream& operator>>(std::istream&, vgl_point_3d<T >&); \
170 template double stddev(std::vector<vgl_point_3d<T > > const&)
171 
172 #endif // vgl_point_3d_hxx_
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.
homogeneous plane in 3D projective space
vgl_point_3d()=default
Default constructor.
point in projective 3D space
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.
Represents a homogeneous 3D plane.
Definition: vgl_fwd.h:22
T nz() const
Definition: vgl_plane_3d.h:96
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.
#define vgl_sqr(x)
Represents a cartesian 3D point.
Definition: vgl_fwd.h:11
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
T ny() const
Definition: vgl_plane_3d.h:93
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
a point in 3D nonhomogeneous space
Represents a Euclidean 3D plane.
Definition: vgl_fwd.h:23
T d() const
Return constant coefficient.
Definition: vgl_plane_3d.h:98
bool coplanar(l const &l1, l const &l2)
Are two lines coplanar, i.e., do they intersect?.
T nx() const
Definition: vgl_plane_3d.h:90
Type & x()
Definition: vgl_point_3d.h:71
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
a plane in 3D nonhomogeneous space
Type & y()
Definition: vgl_point_3d.h:72