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-2018, 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>
14 
15 #include "opengl_internals.h"
16 
17 using namespace mrpt;
18 using namespace mrpt::opengl;
19 using namespace mrpt::math;
20 
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 
65 {
66  writeToStreamRender(out);
67  // version 0
68  out << mBaseRadius << mTopRadius << mHeight << mSlices << mStacks
69  << mHasBottomBase << mHasTopBase;
70 }
73 {
74  switch (version)
75  {
76  case 0:
77  readFromStreamRender(in);
78  in >> mBaseRadius >> mTopRadius >> mHeight >> mSlices >> mStacks >>
79  mHasBottomBase >> mHasTopBase;
80  break;
81  default:
83  };
85 }
86 
87 bool solveEqn(double a, double b, double c, double& t)
88 { // Actually, the b from the quadratic equation is the DOUBLE of this. But
89  // this way, operations are simpler.
90  if (a < 0)
91  {
92  a = -a;
93  b = -b;
94  c = -c;
95  }
96  if (a >= mrpt::math::getEpsilon())
97  {
98  double delta = square(b) - a * c;
99  if (delta == 0)
100  return (t = -b / a) >= 0;
101  else if (delta >= 0)
102  {
103  delta = sqrt(delta);
104  if (-b - delta > 0)
105  {
106  t = (-b - delta) / a;
107  return true;
108  }
109  else if (-b + delta > 0)
110  {
111  t = (-b + delta) / a;
112  return true;
113  } // else return false; Both solutions are negative
114  } // else return false; Both solutions are complex
115  }
116  else if (abs(b) >= mrpt::math::getEpsilon())
117  {
118  t = -c / (b + b);
119  return t >= 0;
120  } // else return false; This actually isn't an equation
121  return false;
122 }
123 
124 bool CCylinder::traceRay(const mrpt::poses::CPose3D& o, double& dist) const
125 {
126  TLine3D lin;
127  mrpt::math::createFromPoseX((o - this->m_pose).asTPose(), lin);
128  lin.unitarize(); // By adding this line, distance from any point of the
129  // line to its base is exactly equal to the "t".
130  if (abs(lin.director[2]) < getEpsilon())
131  {
132  if (!reachesHeight(lin.pBase.z)) return false;
133  float r;
134  return getRadius(static_cast<float>(lin.pBase.z), r)
135  ? solveEqn(
136  square(lin.director[0]) + square(lin.director[1]),
137  lin.director[0] * lin.pBase.x +
138  lin.director[1] * lin.pBase.y,
139  square(lin.pBase.x) + square(lin.pBase.y) - square(r),
140  dist)
141  : false;
142  }
143  bool fnd = false;
144  double nDist, tZ0;
145  if (mHasBottomBase && (tZ0 = -lin.pBase.z / lin.director[2]) > 0)
146  {
147  nDist = sqrt(
148  square(lin.pBase.x + tZ0 * lin.director[0]) +
149  square(lin.pBase.y + tZ0 * lin.director[1]));
150  if (nDist <= mBaseRadius)
151  {
152  fnd = true;
153  dist = tZ0;
154  }
155  }
156  if (mHasTopBase)
157  {
158  tZ0 = (mHeight - lin.pBase.z) / lin.director[2];
159  if (tZ0 > 0 && (!fnd || tZ0 < dist))
160  {
161  nDist = sqrt(
162  square(lin.pBase.x + tZ0 * lin.director[0]) +
163  square(lin.pBase.y + tZ0 * lin.director[1]));
164  if (nDist <= mTopRadius)
165  {
166  fnd = true;
167  dist = tZ0;
168  }
169  }
170  }
171  if (mBaseRadius == mTopRadius)
172  {
173  if (solveEqn(
174  square(lin.director[0]) + square(lin.director[1]),
175  lin.director[0] * lin.pBase.x + lin.director[1] * lin.pBase.y,
176  square(lin.pBase.x) + square(lin.pBase.y) - square(mBaseRadius),
177  nDist))
178  if ((!fnd || nDist < dist) &&
179  reachesHeight(lin.pBase.z + nDist * lin.director[2]))
180  {
181  dist = nDist;
182  fnd = true;
183  }
184  }
185  else
186  {
187  double slope = (mTopRadius - mBaseRadius) / mHeight;
188  if (solveEqn(
189  square(lin.director[0]) + square(lin.director[1]) -
190  square(lin.director[2] * slope),
191  lin.pBase.x * lin.director[0] + lin.pBase.y * lin.director[1] -
192  (mBaseRadius + slope * lin.pBase.z) * slope *
193  lin.director[2],
194  square(lin.pBase.x) + square(lin.pBase.y) -
195  square(mBaseRadius + slope * lin.pBase.z),
196  nDist))
197  if ((!fnd || nDist < dist) &&
198  reachesHeight(lin.pBase.z + nDist * lin.director[2]))
199  {
200  dist = nDist;
201  fnd = true;
202  }
203  }
204  return fnd;
205 }
206 
208  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
209 {
210  bb_min.x = -std::max(mBaseRadius, mTopRadius);
211  bb_min.y = bb_min.x;
212  bb_min.z = 0;
213 
214  bb_max.x = std::max(mBaseRadius, mTopRadius);
215  bb_max.y = bb_max.x;
216  bb_max.z = mHeight;
217 
218  // Convert to coordinates of my parent:
219  m_pose.composePoint(bb_min, bb_min);
220  m_pose.composePoint(bb_max, bb_max);
221 }
GLdouble GLdouble t
Definition: glext.h:3689
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
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
Definition: CCylinder.cpp:71
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
unsigned char uint8_t
Definition: rptypes.h:41
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:90
T square(const T x)
Inline function for the square of a number.
This base provides a set of functions for maths stuff.
const GLubyte * c
Definition: glext.h:6313
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
Definition: CCylinder.cpp:64
A cylinder or cone whose base lies in the XY plane.
Definition: CCylinder.h:30
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:207
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.
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:52
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
void createFromPoseX(const mrpt::math::TPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the X axis in a given pose.
Definition: geometry.cpp:940
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Ray tracing.
Definition: CCylinder.cpp:124
bool solveEqn(double a, double b, double c, double &t)
Definition: CCylinder.cpp:87
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
Definition: geometry.cpp:27
void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
Definition: gl_utils.cpp:143
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.
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
Definition: CCylinder.cpp:63
3D line, represented by a base point and a director vector.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020