vgl_quadric_3d.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_quadric.h
2 #ifndef vgl_quadric_h_
3 #define vgl_quadric_h_
4 //:
5 // \file
6 // \brief A 2nd order algebraic surface in 3-d
7 // \author J.L. Mundy
8 // \date June 4, 2017
9 // \verbatim
10 // Modifications
11 // none
12 // \endverbatim
13 //
14 //-----------------------------------------------------------------------------
15 
16 #include <list>
17 #include <string>
18 #include <iosfwd>
19 #ifdef _MSC_VER
20 # include <vcl_msvc_warnings.h>
21 #endif
22 #include <vnl/vnl_math.h>
23 
24 #include <vgl/vgl_homg_point_3d.h>
25 #include <vgl/vgl_point_3d.h>
26 // the implicit equation for a quadric surface is:
27 // 1) ax^2 + by^2 + cz^2 + dxy + exz + fyz + gxw +hyw +izw +jw^2 = 0
28 // w is the homogeneous scale factor.
29 // there are 17 classes of quadrics depending on the signs of curvature
30 // and degrees of degeneracy
31 //
32 template <class T>
33 class vgl_quadric_3d
34 {
35  public:
55  num_quadric_types // is here to enable iterating through this list
56  };
57 
58  private:
59  // DATA MEMBERS
60  bool det_zero_;
62  T a_; //!< coefficient of \a x^2
63  T b_; //!< coefficient of \a y^2
64  T c_; //!< coefficient of \a z^2
65  T d_; //!< coefficient of \a xy
66  T e_; //!< coefficient of \a xz
67  T f_; //!< coefficient of \a yz
68  T g_; //!< coefficient of \a xw
69  T h_; //!< coefficient of \a yw
70  T i_; //!< coefficient of \a zw
71  T j_; //!< coefficient of \a w^2
72 
73  public:
74  inline vgl_quadric_type type() const { return type_; }
75 
76  //: Returns the internal enum value corresponding to the string argument.
77  // Useful for comparison purposes, or for use in "case" statements.
78  static vgl_quadric_type type_by_name(std::string const& name);
79 
80  //: Converts the quadric type from enum (internal representation) to string.
81  static std::string type_by_number(vgl_quadric_type const& type) ;
82 
83  //: Returns the coefficient of \f$X^2\f$
84  inline T a() const { return a_; }
85 
86  //: Returns the coefficient of \f$Y^2\f$
87  inline T b() const { return b_; }
88 
89  //: Returns the coefficient of \f$Z^2\f$
90  inline T c() const { return c_; }
91 
92  //: Returns the coefficient of \f$XY\f$
93  inline T d() const { return d_; }
94 
95  //: Returns the coefficient of \f$XZ\f$
96  inline T e() const { return e_; }
97 
98  //: Returns the coefficient of \f$YZ\f$
99  inline T f() const { return f_; }
100 
101  //: Returns the coefficient of \f$XW\f$
102  inline T g() const { return g_; }
103 
104  //: Returns the coefficient of \f$YW\f$
105  inline T h() const { return h_; }
106 
107  //: Returns the coefficient of \f$ZW\f$
108  inline T i() const { return i_; }
109 
110  //: Returns the coefficient of \f$W^2\f$
111  inline T j() const { return j_; }
112 
113  // CONSTRUCTORS AND RELATED STUFF
114  // default constructor
116 
117  //: constructor using polynomial coefficients.
118  vgl_quadric_3d(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j);
119 
120  //: constructor from a linear array of polynomial coefficients, given as a C array.
121  vgl_quadric_3d(T const coeff[]);
122 
123  //: constructor from a matix of polynomial coefficients (see below)
124  vgl_quadric_3d(std::vector<std::vector<T> > const& Q);
125 
126  //: return a matrix of quadric coefficients of the form:
127  // _ _
128  // | a d/2 e/2 g/2 |
129  // | d/2 b f/2 h/2 |
130  // Q = | e/2 f/2 c i/2 |
131  // | g/2 h/2 i/2 j |
132  // - -
133  // Note that X^t Q X = 0 , where X^t =[x y z w] is the same as implicit equation 1) above.
134  //
135  std::vector<std::vector<T> > coef_matrix() const;
136 
137  //: constructor from a canonical 4x4 quadric coefficient matrix and a 4x4 homogeneous matrix, H
138  // representing the Euclidean transformation from the canonical frame to the global frame
139  // _ _
140  // |R t| where t is a 3x1 translation vector and R is a rotation matrix
141  // H = | | 0^t is a 1x3 zero vector.
142  // |0^t 1|
143  // - -
144  vgl_quadric_3d(std::vector<std::vector<T> > const& canonical_quadric, std::vector<std::vector<T> > const& H);
145 
146  //: constructor for central quadrics e.g. ellipsoid, ax^2+ by^2+ cz*2 + j = 0, where diag = [a,b,c,j]
147  // are the diagonal elements of the 4x4 quadric coefficient matrix and a 4x4 homogeneous matrix, and
148  // H represents the Euclidean transformation from the canonical frame to the global frame (see above)
149  vgl_quadric_3d(std::vector<T> const& diag, std::vector<std::vector<T> > const& H);
150 
151  //: set or reset the quadric using polynomial coefficients.
152  void set(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j);
153 
154  void set(std::vector<std::vector<T> > const& Q);
155 
156  //: comparison operator.
157  // Comparison is on the quadric, not the equation coefficients. Hence two
158  // quadrics are identical if their coefficient vectors are multiples of
159  // each other.
160  bool operator==(vgl_quadric_3d<T> const& c) const;
161 
162  // UTILITY FUNCTIONS
163 
164  //: Returns true if this quadric is degenerate
165  bool is_degenerate() const{return det_zero_;}
166 
167  //: Sampson distance d_sampson(p) = ||p^t Q p||^2/||grad(p*t Q p)||^2
168  // a first order approximation to Euclidean distance
169  T sampson_dist(vgl_homg_point_3d<T> const& pt) const;
170 
171  //: Returns true if the point pt belongs to the quadric surface.
172  // I.e., if it satisfies the quadric equation within algebraic distance, i.e. pt^t Q pt < tol;
173  bool on(vgl_homg_point_3d<T> const& pt, T tol = T(0)) const;
174 
175  //: if the upper 3x3 submatrix of Q is full rank then the center of the quadric can be defined
176  // otherwise the center is not defined for degenerate quadrics
177  bool center(vgl_point_3d<T>& center) const;
178 
179  //:: eigenvalues and eigenvectors of the upper 3x3 quadric matrix
180  void upper_3x3_eigensystem(std::vector<T>& eigenvalues, std::vector<std::vector<T> >& eigenvectors) const;
181 
182  //:: The quadric in its canonical frame if the center is defined, i.e. the upper 3x3 quadric matrix is full rank
183  // In this case the quadric coefficient matrix in the canonical frame is
184  // a 4x4 diagonal matrix, e.g. ax^2 + by^2 + cz^2 + j = 0. Note that the canonical frame is not unique as
185  // alignment of quadric axes with the orthogonal frame has numerous possible arrangements.
186  // H is a homogenous(4x4)transformation from canonical coordinate space back to the original space.
187  bool canonical_central_quadric(std::vector<T>& diag, std::vector<std::vector<T> >& H) const;
188 
189  //: The quadric coefficient matrix in the canonical frame, whether or not the quadric is central
190  // H is a homogenous(4x4)transformation from canonical coordinate space back to the original space.
191  std::vector<std::vector<T> > canonical_quadric(std::vector<std::vector<T> >& H) const;
192  private:
193  //--------------------------------------------------------------------------
194  //: set quadric type from polynomial coefficients and store in member type_
195  void compute_type();
196 
197 };
198 
199 // \relatesalso vgl_quadric_3d
200 template <class T>
201 std::ostream& operator<<(std::ostream& s, vgl_quadric_3d<T> const& c);
202 
203 //: Read a b c d e f g h i j from stream
204 // \relatesalso vgl_quadric_3d
205 template <class T>
206 std::istream& operator>>(std::istream& s, vgl_quadric_3d<T>& c);
207 
208 //: Computes the eigensystem for real symmetric matrices. Used to classify quadrics.
209 template <class T, size_t n>
210 void eigen(T m[n][n], T l[n], T vc[n][n]);
211 
212 //: Auxillary function used by eigen
213 template <class T, size_t n>
214 void twst(T m[n][n], T c, T s, int i, int j);
216 #define VGL_QUADRIC_3D_INSTANTIATE(T) extern "please include vgl/vgl_quadric_3d.hxx first"
217 
218 #endif // vgl_quadric_3d_h_
T b_
coefficient of y^2
T h() const
Returns the coefficient of .
point in projective 3D space
bool operator==(vgl_quadric_3d< T > const &c) const
comparison operator.
T h_
coefficient of yw
T b() const
Returns the coefficient of .
bool center(vgl_point_3d< T > &center) const
if the upper 3x3 submatrix of Q is full rank then the center of the quadric can be defined.
T e_
coefficient of xz
bool is_degenerate() const
Returns true if this quadric is degenerate.
vgl_quadric_type type() const
bool on(vgl_homg_point_3d< T > const &pt, T tol=T(0)) const
Returns true if the point pt belongs to the quadric surface.
T c_
coefficient of z^2
T c() const
Returns the coefficient of .
T j() const
Returns the coefficient of .
std::vector< std::vector< T > > coef_matrix() const
return a matrix of quadric coefficients of the form:.
void upper_3x3_eigensystem(std::vector< T > &eigenvalues, std::vector< std::vector< T > > &eigenvectors) const
: eigenvalues and eigenvectors of the upper 3x3 quadric matrix.
std::vector< std::vector< T > > canonical_quadric(std::vector< std::vector< T > > &H) const
The quadric coefficient matrix in the canonical frame, whether or not the quadric is central.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
T d_
coefficient of xy
Represents a homogeneous 3D point.
Definition: vgl_fwd.h:9
vgl_quadric_type type_
static vgl_quadric_type type_by_name(std::string const &name)
Returns the internal enum value corresponding to the string argument.
T e() const
Returns the coefficient of .
void set(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j)
set or reset the quadric using polynomial coefficients.
a point in 3D nonhomogeneous space
void twst(T m[n][n], T c, T s, int i, int j)
Auxillary function used by eigen.
void eigen(T m[n][n], T l[n], T vc[n][n])
Computes the eigensystem for real symmetric matrices. Used to classify quadrics.
T sampson_dist(vgl_homg_point_3d< T > const &pt) const
Sampson distance d_sampson(p) = ||p^t Q p||^2/||grad(p*t Q p)||^2.
T f() const
Returns the coefficient of .
T g_
coefficient of xw
T d() const
Returns the coefficient of .
T a_
coefficient of x^2
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
T f_
coefficient of yz
void compute_type()
set quadric type from polynomial coefficients and store in member type_.
#define l
T j_
coefficient of w^2
T a() const
Returns the coefficient of .
T g() const
Returns the coefficient of .
T i() const
Returns the coefficient of .
bool canonical_central_quadric(std::vector< T > &diag, std::vector< std::vector< T > > &H) const
: The quadric in its canonical frame if the center is defined, i.e. the upper 3x3 quadric matrix is f...
static std::string type_by_number(vgl_quadric_type const &type)
Converts the quadric type from enum (internal representation) to string.
T i_
coefficient of zw