Main MRPT website > C++ reference for MRPT 1.9.9
CCylinder.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 #include <mrpt/opengl/CCylinder.h>
12 #include <mrpt/math/geometry.h>
13 #include <mrpt/utils/CStream.h>
14 
15 #include "opengl_internals.h"
16 
17 using namespace mrpt;
18 using namespace mrpt::opengl;
19 using namespace mrpt::math;
20 using namespace mrpt::utils;
21 using namespace std;
22 
24 
25 /*---------------------------------------------------------------
26  render
27  ---------------------------------------------------------------*/
28 void CCylinder::render_dl() const
29 {
30 #if MRPT_HAS_OPENGL_GLUT
35  GLUquadricObj* obj = gluNewQuadric();
36 
37  // This is required to draw cylinders of negative height.
38  const float absHeight = std::abs(mHeight);
39  if (mHeight < 0)
40  {
41  glPushMatrix();
42  glTranslatef(0, 0, mHeight);
43  }
44 
45  gluCylinder(obj, mBaseRadius, mTopRadius, absHeight, mSlices, mStacks);
46 
47  if (mHeight < 0) glPopMatrix();
48 
49  if (mHasBottomBase) gluDisk(obj, 0, mBaseRadius, mSlices, 1);
50  if (mHasTopBase && mTopRadius > 0)
51  {
52  glPushMatrix();
53  glTranslatef(0, 0, mHeight);
54  gluDisk(obj, 0, mTopRadius, mSlices, 1);
55  glPopMatrix();
56  }
57  gluDeleteQuadric(obj);
59 
60 #endif
61 }
62 
63 /*---------------------------------------------------------------
64  Implements the writing to a CStream capability of
65  CSerializable objects
66  ---------------------------------------------------------------*/
67 void CCylinder::writeToStream(mrpt::utils::CStream& out, int* version) const
68 {
69  if (version)
70  *version = 0;
71  else
72  {
73  writeToStreamRender(out);
74  // version 0
75  out << mBaseRadius << mTopRadius << mHeight << mSlices << mStacks
76  << mHasBottomBase << mHasTopBase;
77  }
78 }
79 
80 /*---------------------------------------------------------------
81  Implements the reading from a CStream capability of
82  CSerializable objects
83  ---------------------------------------------------------------*/
85 {
86  switch (version)
87  {
88  case 0:
89  readFromStreamRender(in);
90  in >> mBaseRadius >> mTopRadius >> mHeight >> mSlices >> mStacks >>
91  mHasBottomBase >> mHasTopBase;
92  break;
93  default:
95  };
97 }
98 
99 bool solveEqn(double a, double b, double c, double& t)
100 { // Actually, the b from the quadratic equation is the DOUBLE of this. But
101  // this way, operations are simpler.
102  if (a < 0)
103  {
104  a = -a;
105  b = -b;
106  c = -c;
107  }
108  if (a >= mrpt::math::getEpsilon())
109  {
110  double delta = square(b) - a * c;
111  if (delta == 0)
112  return (t = -b / a) >= 0;
113  else if (delta >= 0)
114  {
115  delta = sqrt(delta);
116  if (-b - delta > 0)
117  {
118  t = (-b - delta) / a;
119  return true;
120  }
121  else if (-b + delta > 0)
122  {
123  t = (-b + delta) / a;
124  return true;
125  } // else return false; Both solutions are negative
126  } // else return false; Both solutions are complex
127  }
128  else if (abs(b) >= mrpt::math::getEpsilon())
129  {
130  t = -c / (b + b);
131  return t >= 0;
132  } // else return false; This actually isn't an equation
133  return false;
134 }
135 
136 bool CCylinder::traceRay(const mrpt::poses::CPose3D& o, double& dist) const
137 {
138  TLine3D lin;
139  createFromPoseX(o - this->m_pose, lin);
140  lin.unitarize(); // By adding this line, distance from any point of the
141  // line to its base is exactly equal to the "t".
142  if (abs(lin.director[2]) < getEpsilon())
143  {
144  if (!reachesHeight(lin.pBase.z)) return false;
145  float r;
146  return getRadius(static_cast<float>(lin.pBase.z), r)
147  ? solveEqn(
148  square(lin.director[0]) + square(lin.director[1]),
149  lin.director[0] * lin.pBase.x +
150  lin.director[1] * lin.pBase.y,
151  square(lin.pBase.x) + square(lin.pBase.y) - square(r),
152  dist)
153  : false;
154  }
155  bool fnd = false;
156  double nDist, tZ0;
157  if (mHasBottomBase && (tZ0 = -lin.pBase.z / lin.director[2]) > 0)
158  {
159  nDist = sqrt(
160  square(lin.pBase.x + tZ0 * lin.director[0]) +
161  square(lin.pBase.y + tZ0 * lin.director[1]));
162  if (nDist <= mBaseRadius)
163  {
164  fnd = true;
165  dist = tZ0;
166  }
167  }
168  if (mHasTopBase)
169  {
170  tZ0 = (mHeight - lin.pBase.z) / lin.director[2];
171  if (tZ0 > 0 && (!fnd || tZ0 < dist))
172  {
173  nDist = sqrt(
174  square(lin.pBase.x + tZ0 * lin.director[0]) +
175  square(lin.pBase.y + tZ0 * lin.director[1]));
176  if (nDist <= mTopRadius)
177  {
178  fnd = true;
179  dist = tZ0;
180  }
181  }
182  }
183  if (mBaseRadius == mTopRadius)
184  {
185  if (solveEqn(
186  square(lin.director[0]) + square(lin.director[1]),
187  lin.director[0] * lin.pBase.x + lin.director[1] * lin.pBase.y,
188  square(lin.pBase.x) + square(lin.pBase.y) - square(mBaseRadius),
189  nDist))
190  if ((!fnd || nDist < dist) &&
191  reachesHeight(lin.pBase.z + nDist * lin.director[2]))
192  {
193  dist = nDist;
194  fnd = true;
195  }
196  }
197  else
198  {
199  double slope = (mTopRadius - mBaseRadius) / mHeight;
200  if (solveEqn(
201  square(lin.director[0]) + square(lin.director[1]) -
202  square(lin.director[2] * slope),
203  lin.pBase.x * lin.director[0] + lin.pBase.y * lin.director[1] -
204  (mBaseRadius + slope * lin.pBase.z) * slope *
205  lin.director[2],
206  square(lin.pBase.x) + square(lin.pBase.y) -
207  square(mBaseRadius + slope * lin.pBase.z),
208  nDist))
209  if ((!fnd || nDist < dist) &&
210  reachesHeight(lin.pBase.z + nDist * lin.director[2]))
211  {
212  dist = nDist;
213  fnd = true;
214  }
215  }
216  return fnd;
217 }
218 
220  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
221 {
222  bb_min.x = -std::max(mBaseRadius, mTopRadius);
223  bb_min.y = bb_min.x;
224  bb_min.z = 0;
225 
226  bb_max.x = std::max(mBaseRadius, mTopRadius);
227  bb_max.y = bb_max.x;
228  bb_max.z = mHeight;
229 
230  // Convert to coordinates of my parent:
231  m_pose.composePoint(bb_min, bb_min);
232  m_pose.composePoint(bb_max, bb_max);
233 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble t
Definition: glext.h:3689
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: CCylinder.cpp:84
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
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
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
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
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
Definition: CCylinder.cpp:67
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
const GLubyte * c
Definition: glext.h:6313
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
A cylinder or cone whose base lies in the XY plane.
Definition: CCylinder.h:32
GLubyte GLubyte b
Definition: glext.h:6279
double x
X,Y,Z coordinates.
#define GL_BLEND
Definition: glew.h:432
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: CCylinder.cpp:219
void unitarize()
Unitarize director vector.
double director[3]
Director vector.
GLAPI void GLAPIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
#define GL_SRC_ALPHA
Definition: glew.h:286
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Ray tracing.
Definition: CCylinder.cpp:136
bool solveEqn(double a, double b, double c, double &t)
Definition: CCylinder.cpp:99
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
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
GLAPI void GLAPIENTRY glPushMatrix(void)
Lightweight 3D point.
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
Definition: geometry.cpp:30
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
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