Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JCylinder3D.hh
Go to the documentation of this file.
1 #ifndef __JCYLINDER3D__
2 #define __JCYLINDER3D__
3 
4 #include <istream>
5 #include <ostream>
6 #include <limits>
7 #include <utility>
8 #include <cmath>
9 
10 #include "JIO/JSerialisable.hh"
11 #include "JLang/JManip.hh"
12 #include "JMath/JConstants.hh"
13 #include "JGeometry2D/JCircle2D.hh"
14 #include "JGeometry3D/JVector3D.hh"
15 #include "JGeometry3D/JAxis3D.hh"
16 
17 
18 /**
19  * \author mdejong
20  */
21 
22 namespace JGEOMETRY3D {}
23 namespace JPP { using namespace JGEOMETRY3D; }
24 
25 namespace JGEOMETRY3D {
26 
27  using JIO::JReader;
28  using JIO::JWriter;
31 
32 
33  /**
34  * Cylinder object.
35  *
36  * The cylinder consists of a 2D circle in the (x,y) plane and a range in z
37  * (i.e.\ axis of cylinder is parallel to the z-axis).
38  */
39  class JCylinder3D :
40  public JCircle2D
41  {
42  public:
43  /**
44  * Default constructor.
45  */
47  JCircle2D(),
48  zmin(0.0),
49  zmax(0.0)
50  {}
51 
52 
53  /**
54  * Constructor.
55  *
56  * \param circle 2D circle in (x,y)
57  * \param zmin minimal z
58  * \param zmax maximal z
59  */
60  JCylinder3D(const JCircle2D& circle,
61  const double zmin,
62  const double zmax) :
63  JCircle2D(circle)
64  {
65  this->zmin = zmin;
66  this->zmax = zmax;
67  }
68 
69 
70  /**
71  * Constructor.
72  *
73  * Determines smallest enclosing cylinder for any number of points.
74  *
75  * \param __begin begin of data
76  * \param __end end of data
77  * \param precision precision
78  */
79  template<class T>
80  JCylinder3D(T __begin,
81  T __end,
82  const double precision = std::numeric_limits<double>::epsilon()) :
83  JCircle2D(__begin, __end, precision),
84  zmin(0.0),
85  zmax(0.0)
86  {
87  if (__begin != __end) {
88 
89  zmin = std::numeric_limits<double>::max();
90  zmax = std::numeric_limits<double>::lowest();
91 
92  for (T i = __begin; i != __end; ++i) {
93  if (i->getZ() < zmin) zmin = i->getZ();
94  if (i->getZ() > zmax) zmax = i->getZ();
95  }
96  }
97  }
98 
99 
100  /**
101  * Get minimal z position.
102  *
103  * \return minimal z position
104  */
105  double getZmin() const
106  {
107  return zmin;
108  }
109 
110 
111  /**
112  * Get maximal z position.
113  *
114  * \return maximal z position
115  */
116  double getZmax() const
117  {
118  return zmax;
119  }
120 
121 
122  /**
123  * Set minimal z position.
124  *
125  * \param zmin minimal z position
126  */
127  void setZmin(const double zmin)
128  {
129  this->zmin = zmin;
130  }
131 
132 
133  /**
134  * Set maximal z position.
135  *
136  * \param zmax maximal z position
137  */
138  void setZmax(const double zmax)
139  {
140  this->zmax = zmax;
141  }
142 
143 
144  /**
145  * Add position.
146  *
147  * \param pos position
148  * \return this cylinder
149  */
150  JCylinder3D& add(const JVector3D& pos)
151  {
152  static_cast<JPosition2D&>(*this).add(JPosition2D(pos.getX(), pos.getY()));
153 
154  zmin += pos.getZ();
155  zmax += pos.getZ();
156 
157  return *this;
158  }
159 
160 
161  /**
162  * Add (safety) margin.
163  *
164  * \param D margin
165  * \return this cylinder
166  */
167  void addMargin(const double D)
168  {
169  __r += D;
170  zmin -= D;
171  zmax += D;
172  }
173 
174 
175  /**
176  * Get volume.
177  *
178  * \return volume
179  */
180  inline double getVolume() const
181  {
182  return (getZmax ()- getZmin()) * JMATH::PI * getRadius() * getRadius();
183  }
184 
185 
186  /**
187  * Get centre.
188  *
189  * \return centre
190  */
192  {
193  return JPosition3D(getPosition(), (getZmax() - getZmin())/2.0);
194  }
195 
196 
197  /**
198  * Check whether given point is inside cylinder.
199  *
200  * \param pos position
201  * \return true if inside; else false
202  */
203  inline bool is_inside(const JVector3D& pos) const
204  {
205  return (pos.getZ() >= getZmin() &&
206  pos.getZ() <= getZmax() &&
207  JCircle2D::is_inside(JVector2D(pos.getX(), pos.getY())));
208  }
209 
210 
211  /**
212  * Get distance between cylinder wall and given position.
213  *
214  * \param pos position
215  * \return distance
216  */
217  inline double getDistance(const JVector3D& pos) const
218  {
219  JVector2D D(pos);
220 
221  D.sub(*this);
222 
223  double R = D.getLength();
224 
225  if (R > this->getRadius()) {
226 
227  R -= this->getRadius();
228 
229  double dz = 0.0;
230 
231  if (pos.getZ() > this->getZmax())
232  dz = pos.getZ() - this->getZmax();
233  else if (pos.getZ() < this->getZmin())
234  dz = this->getZmin() - pos.getZ();
235  else
236  return R;
237 
238  return sqrt(R*R + dz*dz);
239 
240  } else {
241 
242  if (pos.getZ() > this->getZmax())
243  return pos.getZ() - this->getZmax();
244  else if (pos.getZ() < this->getZmin())
245  return this->getZmin() - pos.getZ();
246  else
247  return 0.0;
248  }
249  }
250 
251 
252  /**
253  * Get square of distance between cylinder wall and given position.
254  *
255  * \param pos position
256  * \return square of distance
257  */
258  inline double getDistanceSquared(const JVector3D& pos) const
259  {
260  const double d = getDistance(pos);
261 
262  return d*d;
263  }
264 
265 
266  /**
267  * Get intersection points of axis with cylinder.
268  *
269  * \param axis axis
270  * \return up and down stream positions along axis
271  */
273  {
274  double path[] = { 0.0, 0.0 };
275 
276  if (fabs(axis.getDZ()) != 0.0) {
277 
278  // intersection with bottom or top surface
279 
280  const double Z[] = {
281  axis.getDZ() > 0 ? this->getZmin() : this->getZmax(),
282  axis.getDZ() > 0 ? this->getZmax() : this->getZmin()
283  };
284 
285  for (int i = 0; i != 2; ++i) {
286 
287  const double u = (Z[i] - axis.getZ()) / axis.getDZ();
288  const double x = axis.getX() + u * axis.getDX() - this->getX();
289  const double y = axis.getY() + u * axis.getDY() - this->getY();
290 
291  if (x*x + y*y <= this->getRadius() * this->getRadius()) {
292  path[i] = u;
293  }
294  }
295  }
296 
297  if (fabs(axis.getDZ()) != 1.0) {
298 
299  // intersection with cylinder wall
300 
301  const double x = axis.getX() - this->getX();
302  const double y = axis.getY() - this->getY();
303  const double dx = axis.getDX();
304  const double dy = axis.getDY();
305  const double R = this->getRadius();
306 
307  const double a = (dx * dx + dy * dy);
308  const double b = 2*(dx * x + dy * y);
309  const double c = (x * x + y * y) - R * R;
310 
311  const double q = b*b - 4*a*c;
312 
313  if (q >= 0) {
314 
315  const double u[] = {
316  (-b - sqrt(q)) / (2*a),
317  (-b + sqrt(q)) / (2*a)
318  };
319 
320  for (int i = 0; i != 2; ++i) {
321 
322  const double z = axis.getZ() + u[i] * axis.getDZ();
323 
324  if (z >= this->getZmin() && z <= this->getZmax()) {
325  path[i] = u[i];
326  }
327  }
328  }
329  }
330 
331  return std::make_pair(path[0], path[1]);
332  }
333 
334 
335  /**
336  * Read cylinder from input stream.
337  *
338  * \param in input stream
339  * \param cylinder cylinder
340  * \return input stream
341  */
342  friend inline std::istream& operator>>(std::istream& in, JCylinder3D& cylinder)
343  {
344  in >> static_cast<JCircle2D&>(cylinder);
345  in >> cylinder.zmin >> cylinder.zmax;
346 
347  return in;
348  }
349 
350 
351  /**
352  * Write cylinder to output stream.
353  *
354  * \param out output stream
355  * \param cylinder cylinder
356  * \return output stream
357  */
358  friend inline std::ostream& operator<<(std::ostream& out, const JCylinder3D& cylinder)
359  {
360  const JFormat format(out, getFormat<JCylinder3D>(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
361 
362  out << static_cast<const JCircle2D&>(cylinder);
363  out << ' ';
364  out << format << cylinder.zmin;
365  out << ' ';
366  out << format << cylinder.zmax;
367 
368  return out;
369  }
370 
371 
372  /**
373  * Read cylinder from input.
374  *
375  * \param in reader
376  * \param cylinder cylinder
377  * \return reader
378  */
379  friend inline JReader& operator>>(JReader& in, JCylinder3D& cylinder)
380  {
381  in >> static_cast<JCircle2D&>(cylinder);
382  in >> cylinder.zmin >> cylinder.zmax;
383 
384  return in;
385  }
386 
387 
388  /**
389  * Write cylinder to output.
390  *
391  * \param out writer
392  * \param cylinder cylinder
393  * \return writer
394  */
395  friend inline JWriter& operator<<(JWriter& out, const JCylinder3D& cylinder)
396  {
397  out << static_cast<const JCircle2D&>(cylinder);
398  out << cylinder.zmin << cylinder.zmax;
399 
400  return out;
401  }
402 
403 
404  protected:
405  double zmin;
406  double zmax;
407  };
408 }
409 
410 #endif
const JPosition2D & getPosition() const
Get position.
Definition: JPosition2D.hh:97
Data structure for vector in two dimensions.
Definition: JVector2D.hh:32
JCylinder3D(T __begin, T __end, const double precision=std::numeric_limits< double >::epsilon())
Constructor.
Definition: JCylinder3D.hh:80
Interface for binary output.
do echo Generating $dir eval D
Definition: JDrawLED.sh:50
double getRadius() const
Get radius.
Definition: JCircle2D.hh:126
JVector2D()
Default constructor.
Definition: JVector2D.hh:39
JPosition2D()
Default constructor.
Definition: JPosition2D.hh:43
Data structure for circle in two dimensions.
Definition: JCircle2D.hh:30
void setZmin(const double zmin)
Set minimal z position.
Definition: JCylinder3D.hh:127
friend JWriter & operator<<(JWriter &out, const JCylinder3D &cylinder)
Write cylinder to output.
Definition: JCylinder3D.hh:395
double getZmin() const
Get minimal z position.
Definition: JCylinder3D.hh:105
double getDistanceSquared(const JVector3D &pos) const
Get square of distance between cylinder wall and given position.
Definition: JCylinder3D.hh:258
JCylinder3D & add(const JVector3D &pos)
Add position.
Definition: JCylinder3D.hh:150
friend JReader & operator>>(JReader &in, JCylinder3D &cylinder)
Read cylinder from input.
Definition: JCylinder3D.hh:379
double getY() const
Get y position.
Definition: JVector2D.hh:74
friend std::istream & operator>>(std::istream &in, JCylinder3D &cylinder)
Read cylinder from input stream.
Definition: JCylinder3D.hh:342
Auxiliary class to temporarily define format specifications.
Definition: JManip.hh:631
JVector2D & sub(const JVector2D &vector)
Subtract vector.
Definition: JVector2D.hh:115
do cat driver txt<< EOFevent ev_configure{RC_EVT%< ev_configure.txt > RC_DWRT path
Axis object.
Definition: JAxis3D.hh:38
bool is_inside(const JVector2D &pos, const double precision=std::numeric_limits< double >::min()) const
Check whether given point is inside circle.
Definition: JCircle2D.hh:252
JPosition3D getCenter() const
Get centre.
Definition: JCylinder3D.hh:191
friend std::ostream & operator<<(std::ostream &out, const JCylinder3D &cylinder)
Write cylinder to output stream.
Definition: JCylinder3D.hh:358
Cylinder object.
Definition: JCylinder3D.hh:39
Data structure for vector in three dimensions.
Definition: JVector3D.hh:34
Mathematical constants.
double getDY() const
Get y direction.
Definition: JVersor3D.hh:106
double getDX() const
Get x direction.
Definition: JVersor3D.hh:95
double getX() const
Get x position.
Definition: JVector2D.hh:63
do set_variable OUTPUT_DIRECTORY $WORKDIR T
static const double PI
Mathematical constants.
void addMargin(const double D)
Add (safety) margin.
Definition: JCylinder3D.hh:167
double getY() const
Get y position.
Definition: JVector3D.hh:104
Interface for binary input.
then usage $script[distance] fi case set_variable R
Definition: JDrawLED.sh:40
I/O manipulators.
double getVolume() const
Get volume.
Definition: JCylinder3D.hh:180
double getZmax() const
Get maximal z position.
Definition: JCylinder3D.hh:116
then JMuonMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
Definition: JMuonPath.sh:45
JCylinder3D()
Default constructor.
Definition: JCylinder3D.hh:46
then JCalibrateToT a
Definition: JTuneHV.sh:103
double getX() const
Get x position.
Definition: JVector3D.hh:94
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
Definition: JCylinder3D.hh:203
void setZmax(const double zmax)
Set maximal z position.
Definition: JCylinder3D.hh:138
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
double u[N+1]
Definition: JPolint.hh:739
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
Definition: JCanberra.sh:36
std::pair< double, double > getIntersection(const JAxis3D &axis) const
Get intersection points of axis with cylinder.
Definition: JCylinder3D.hh:272
JCylinder3D(const JCircle2D &circle, const double zmin, const double zmax)
Constructor.
Definition: JCylinder3D.hh:60
double getDistance(const JVector3D &pos) const
Get distance between cylinder wall and given position.
Definition: JCylinder3D.hh:217
double getLength() const
Get length.
Definition: JVector2D.hh:199
Data structure for format specifications.
Definition: JManip.hh:521
double getZ() const
Get z position.
Definition: JVector3D.hh:115
double getDZ() const
Get z direction.
Definition: JVersor3D.hh:117