Main MRPT website > C++ reference for MRPT 1.9.9
CEllipsoid.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "opengl-precomp.h" // Precompiled header
11 
12 #include <mrpt/opengl/CEllipsoid.h>
13 #include <mrpt/math/CMatrix.h>
14 #include <mrpt/math/geometry.h>
16 #include <mrpt/utils/CStream.h>
17 
18 #include "opengl_internals.h"
19 
20 using namespace mrpt;
21 using namespace mrpt::opengl;
22 using namespace mrpt::utils;
23 using namespace mrpt::math;
24 using namespace std;
25 
27 
28 /*---------------------------------------------------------------
29  render
30  ---------------------------------------------------------------*/
31 void CEllipsoid::render_dl() const
32 {
33 #if MRPT_HAS_OPENGL_GLUT
35 
36  const size_t dim = m_cov.getColCount();
37 
38  if (m_eigVal(0, 0) != 0.0 && m_eigVal(1, 1) != 0.0 &&
39  (dim == 2 || m_eigVal(2, 2) != 0.0) && m_quantiles != 0.0)
40  {
45  glLineWidth(m_lineWidth);
47 
48  if (dim == 2)
49  {
50  glDisable(GL_LIGHTING); // Disable lights when drawing lines
51 
52  // ---------------------
53  // 2D ellipse
54  // ---------------------
55 
56  /* Equivalent MATLAB code:
57  *
58  * q=1;
59  * [vec val]=eig(C);
60  * M=(q*val*vec)';
61  * R=M*[x;y];
62  * xx=R(1,:);yy=R(2,:);
63  * plot(xx,yy), axis equal;
64  */
65 
66  double ang;
67  unsigned int i;
68 
69  // Compute the new vectors for the ellipsoid:
70  CMatrixDouble M;
71  M.noalias() = double(m_quantiles) * m_eigVal * m_eigVec.adjoint();
72 
74 
75  // Compute the points of the 2D ellipse:
76  for (i = 0, ang = 0; i < m_2D_segments;
77  i++, ang += (M_2PI / m_2D_segments))
78  {
79  double ccos = cos(ang);
80  double ssin = sin(ang);
81 
82  const float x =
83  ccos * M.get_unsafe(0, 0) + ssin * M.get_unsafe(1, 0);
84  const float y =
85  ccos * M.get_unsafe(0, 1) + ssin * M.get_unsafe(1, 1);
86 
87  glVertex2f(x, y);
88  } // end for points on ellipse
89 
90  glEnd();
91 
92  // 2D: Save bounding box:
93  const double max_radius =
94  m_quantiles * std::max(m_eigVal(0, 0), m_eigVal(1, 1));
95  m_bb_min = mrpt::math::TPoint3D(-max_radius, -max_radius, 0);
96  m_bb_max = mrpt::math::TPoint3D(max_radius, max_radius, 0);
97  // Convert to coordinates of my parent:
98  m_pose.composePoint(m_bb_min, m_bb_min);
99  m_pose.composePoint(m_bb_max, m_bb_max);
100 
102  }
103  else
104  {
105  // ---------------------
106  // 3D ellipsoid
107  // ---------------------
108  GLfloat mat[16];
109 
110  // A homogeneous transformation matrix, in this order:
111  //
112  // 0 4 8 12
113  // 1 5 9 13
114  // 2 6 10 14
115  // 3 7 11 15
116  //
117  mat[3] = mat[7] = mat[11] = 0;
118  mat[15] = 1;
119  mat[12] = mat[13] = mat[14] = 0;
120 
121  mat[0] = m_eigVec(0, 0);
122  mat[1] = m_eigVec(1, 0);
123  mat[2] = m_eigVec(2, 0); // New X-axis
124  mat[4] = m_eigVec(0, 1);
125  mat[5] = m_eigVec(1, 1);
126  mat[6] = m_eigVec(2, 1); // New X-axis
127  mat[8] = m_eigVec(0, 2);
128  mat[9] = m_eigVec(1, 2);
129  mat[10] = m_eigVec(2, 2); // New X-axis
130 
131  GLUquadricObj* obj = gluNewQuadric();
133 
134  if (!m_drawSolid3D)
135  glDisable(GL_LIGHTING); // Disable lights when drawing lines
136 
137  gluQuadricDrawStyle(obj, m_drawSolid3D ? GLU_FILL : GLU_LINE);
138 
139  glPushMatrix();
140  glMultMatrixf(mat);
141  glScalef(
142  m_eigVal(0, 0) * m_quantiles, m_eigVal(1, 1) * m_quantiles,
143  m_eigVal(2, 2) * m_quantiles);
144 
145  gluSphere(obj, 1, m_3D_segments, m_3D_segments);
147 
148  glPopMatrix();
149 
150  gluDeleteQuadric(obj);
152 
153  // 3D: Save bounding box:
154  const double max_radius =
155  m_quantiles *
156  std::max(
157  m_eigVal(0, 0), std::max(m_eigVal(1, 1), m_eigVal(2, 2)));
158  m_bb_min = mrpt::math::TPoint3D(-max_radius, -max_radius, 0);
159  m_bb_max = mrpt::math::TPoint3D(max_radius, max_radius, 0);
160  // Convert to coordinates of my parent:
161  m_pose.composePoint(m_bb_min, m_bb_min);
162  m_pose.composePoint(m_bb_max, m_bb_max);
163  }
164 
166 
168  }
170  cout << "Covariance matrix leading to error is:" << endl
171  << m_cov << endl;);
172 #endif
173 }
174 
175 /*---------------------------------------------------------------
176  Implements the writing to a CStream capability of
177  CSerializable objects
178  ---------------------------------------------------------------*/
179 void CEllipsoid::writeToStream(mrpt::utils::CStream& out, int* version) const
180 {
181  if (version)
182  *version = 1;
183  else
184  {
185  writeToStreamRender(out);
186  out << m_cov << m_drawSolid3D << m_quantiles << (uint32_t)m_2D_segments
187  << (uint32_t)m_3D_segments << m_lineWidth;
188  }
189 }
190 
191 /*---------------------------------------------------------------
192  Implements the reading from a CStream capability of
193  CSerializable objects
194  ---------------------------------------------------------------*/
196 {
197  switch (version)
198  {
199  case 0:
200  case 1:
201  {
202  uint32_t i;
203  readFromStreamRender(in);
204  if (version == 0)
205  {
206  CMatrix c;
207  in >> c;
208  m_cov = c.cast<double>();
209  }
210  else
211  {
212  in >> m_cov;
213  }
214 
215  in >> m_drawSolid3D >> m_quantiles;
216  in >> i;
217  m_2D_segments = i;
218  in >> i;
219  m_3D_segments = i;
220  in >> m_lineWidth;
221 
222  // Update cov. matrix cache:
223  m_prevComputedCov = m_cov;
224  setCovMatrix(m_cov);
225  }
226  break;
227  default:
229  };
231 }
232 
233 bool quickSolveEqn(double a, double b_2, double c, double& t)
234 {
235  double delta = square(b_2) - a * c;
236  if (delta == 0)
237  return (t = -b_2 / a) >= 0;
238  else if (delta > 0)
239  {
240  delta = sqrt(delta);
241  if ((t = (-b_2 - delta) / a) >= 0)
242  return true;
243  else
244  return (t = (-b_2 + delta) / a) >= 0;
245  }
246  else
247  return false;
248 }
249 
250 bool CEllipsoid::traceRay(const mrpt::poses::CPose3D& o, double& dist) const
251 {
252  if (m_cov.getRowCount() != 3) return false;
253  TLine3D lin, lin2;
254  createFromPoseX(o - this->m_pose, lin);
255  lin.unitarize(); // By adding this line, distance from any point of the
256  // line to its base is exactly equal to the "t".
257  for (size_t i = 0; i < 3; i++)
258  {
259  lin2.pBase[i] = 0;
260  lin2.director[i] = 0;
261  for (size_t j = 0; j < 3; j++)
262  {
263  double vji = m_eigVec(j, i);
264  lin2.pBase[i] += vji * lin.pBase[j];
265  lin2.director[i] += vji * lin.director[j];
266  }
267  }
268  double a = 0, b_2 = 0, c = -square(m_quantiles);
269  for (size_t i = 0; i < 3; i++)
270  {
271  double ev = m_eigVal(i, i);
272  a += square(lin2.director[i] / ev);
273  b_2 += lin2.director[i] * lin2.pBase[i] / square(ev);
274  c += square(lin2.pBase[i] / ev);
275  }
276  return quickSolveEqn(a, b_2, c, dist);
277 }
278 
280  const mrpt::math::CMatrixDouble& m, int resizeToSize)
281 {
282  MRPT_START
283 
284  ASSERT_(m.getColCount() == m.getRowCount());
285  ASSERT_(
286  size(m, 1) == 2 || size(m, 1) == 3 ||
287  (resizeToSize > 0 && (resizeToSize == 2 || resizeToSize == 3)));
288 
289  m_cov = m;
290  if (resizeToSize > 0 && resizeToSize < (int)size(m, 1))
291  m_cov.setSize(resizeToSize, resizeToSize);
292 
293  if (m_cov == m_prevComputedCov) return; // Done.
294 
296 
297  // Handle the special case of an ellipsoid of volume = 0
298  const double d = m_cov.det();
299  if (d == 0 || d != d) // Note: "d!=d" is a great test for invalid numbers,
300  // don't remove!
301  {
302  // All zeros:
303  m_prevComputedCov = m_cov;
304  m_eigVec.zeros(3, 3);
305  m_eigVal.zeros(3, 3);
306  }
307  else
308  {
309  // Not null matrix: compute the eigen-vectors & values:
310  m_prevComputedCov = m_cov;
311  if (m_cov.eigenVectors(m_eigVec, m_eigVal))
312  {
313  m_eigVal = m_eigVal.array().sqrt().matrix();
314  // Do the scale at render to avoid recomputing the m_eigVal for
315  // different m_quantiles
316  }
317  else
318  {
319  m_eigVec.zeros(3, 3);
320  m_eigVal.zeros(3, 3);
321  }
322  }
323 
324  MRPT_END
325 }
326 
328  const mrpt::math::CMatrixFloat& m, int resizeToSize)
329 {
331  setCovMatrix(CMatrixDouble(m), resizeToSize);
332 }
333 
334 /** Evaluates the bounding box of this object (including possible children) in
335  * the coordinate frame of the object parent. */
337  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
338 {
339  bb_min = m_bb_min;
340  bb_max = m_bb_max;
341 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble t
Definition: glext.h:3689
void setCovMatrix(const mrpt::math::CMatrixDouble &m, int resizeToSize=-1)
Set the 2x2 or 3x3 covariance matrix that will determine the aspect of the ellipsoid (if resizeToSize...
Definition: CEllipsoid.cpp:279
GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m)
#define MRPT_END_WITH_CLEAN_UP(stuff)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
bool quickSolveEqn(double a, double b_2, double c, double &t)
Definition: CEllipsoid.cpp:233
GLAPI void GLAPIENTRY glPopMatrix(void)
TPoint3D pBase
Base point.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
STL namespace.
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glew.h:287
#define GL_LIGHTING
Definition: glew.h:385
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
float GLfloat
Definition: glew.h:217
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
#define M_2PI
Definition: mrpt_macros.h:437
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
void createFromPoseX(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the X axis in a given pose.
Definition: geometry.cpp:943
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define MRPT_END
const GLubyte * c
Definition: glext.h:6313
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
Definition: CEllipsoid.cpp:195
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define GL_BLEND
Definition: glew.h:432
#define GL_LINE_LOOP
Definition: glew.h:274
void unitarize()
Unitarize director vector.
double director[3]
Director vector.
#define MRPT_START
#define GL_SRC_ALPHA
Definition: glew.h:286
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Ray tracing.
Definition: CEllipsoid.cpp:250
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
GLAPI void GLAPIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
This file implements matrix/vector text and binary serialization.
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:140
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
#define ASSERT_(f)
GLAPI void GLAPIENTRY glEnd(void)
GLenum GLint GLint y
Definition: glext.h:3538
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
Definition: CEllipsoid.cpp:179
GLsizeiptr size
Definition: glext.h:3923
A 2D ellipse or 3D ellipsoid, depending on the size of the m_cov matrix (2x2 or 3x3).
Definition: CEllipsoid.h:47
GLenum GLint x
Definition: glext.h:3538
GLAPI void GLAPIENTRY glPushMatrix(void)
Lightweight 3D point.
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:25
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const override
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
Definition: CEllipsoid.cpp:336
3D line, represented by a base point and a director vector.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019