Jpp  18.0.0-rc.4
the software that should make you happy
 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  * Type definition of intersection.
45  */
47 
48 
49  /**
50  * Default constructor.
51  */
53  JCircle2D(),
54  zmin(0.0),
55  zmax(0.0)
56  {}
57 
58 
59  /**
60  * Constructor.
61  *
62  * \param circle 2D circle in (x,y)
63  * \param zmin minimal z
64  * \param zmax maximal z
65  */
66  JCylinder3D(const JCircle2D& circle,
67  const double zmin,
68  const double zmax) :
69  JCircle2D(circle)
70  {
71  this->zmin = zmin;
72  this->zmax = zmax;
73  }
74 
75 
76  /**
77  * Constructor.
78  *
79  * Determines smallest enclosing cylinder for any number of points.
80  *
81  * \param __begin begin of data
82  * \param __end end of data
83  * \param precision precision
84  */
85  template<class T>
86  JCylinder3D(T __begin,
87  T __end,
88  const double precision = std::numeric_limits<double>::epsilon()) :
89  JCircle2D(__begin, __end, precision),
90  zmin(0.0),
91  zmax(0.0)
92  {
93  if (__begin != __end) {
94 
95  zmin = std::numeric_limits<double>::max();
96  zmax = std::numeric_limits<double>::lowest();
97 
98  for (T i = __begin; i != __end; ++i) {
99  if (i->getZ() < zmin) zmin = i->getZ();
100  if (i->getZ() > zmax) zmax = i->getZ();
101  }
102  }
103  }
104 
105 
106  /**
107  * Get minimal z position.
108  *
109  * \return minimal z position
110  */
111  double getZmin() const
112  {
113  return zmin;
114  }
115 
116 
117  /**
118  * Get maximal z position.
119  *
120  * \return maximal z position
121  */
122  double getZmax() const
123  {
124  return zmax;
125  }
126 
127 
128  /**
129  * Set minimal z position.
130  *
131  * \param zmin minimal z position
132  */
133  void setZmin(const double zmin)
134  {
135  this->zmin = zmin;
136  }
137 
138 
139  /**
140  * Set maximal z position.
141  *
142  * \param zmax maximal z position
143  */
144  void setZmax(const double zmax)
145  {
146  this->zmax = zmax;
147  }
148 
149 
150  /**
151  * Add position.
152  *
153  * \param pos position
154  * \return this cylinder
155  */
156  JCylinder3D& add(const JVector3D& pos)
157  {
158  static_cast<JPosition2D&>(*this).add(JPosition2D(pos.getX(), pos.getY()));
159 
160  zmin += pos.getZ();
161  zmax += pos.getZ();
162 
163  return *this;
164  }
165 
166 
167  /**
168  * Add (safety) margin.
169  *
170  * \param D margin
171  */
172  void addMargin(const double D)
173  {
174  __r += D;
175  zmin -= D;
176  zmax += D;
177  }
178 
179 
180  /**
181  * Get volume.
182  *
183  * \return volume
184  */
185  inline double getVolume() const
186  {
187  return (getZmax() - getZmin()) * JMATH::PI * getRadius() * getRadius();
188  }
189 
190 
191  /**
192  * Get centre.
193  *
194  * \return centre
195  */
197  {
198  return JPosition3D(getPosition(), (getZmax() - getZmin())/2.0);
199  }
200 
201 
202  /**
203  * Check whether given point is inside cylinder.
204  *
205  * \param pos position
206  * \return true if inside; else false
207  */
208  inline bool is_inside(const JVector3D& pos) const
209  {
210  return (pos.getZ() >= getZmin() &&
211  pos.getZ() <= getZmax() &&
212  JCircle2D::is_inside(JVector2D(pos.getX(), pos.getY())));
213  }
214 
215 
216  /**
217  * Get distance between cylinder wall and given position.
218  *
219  * \param pos position
220  * \return distance
221  */
222  inline double getDistance(const JVector3D& pos) const
223  {
224  JVector2D D(pos);
225 
226  D.sub(*this);
227 
228  double R = D.getLength();
229 
230  if (R > this->getRadius()) {
231 
232  R -= this->getRadius();
233 
234  double dz = 0.0;
235 
236  if (pos.getZ() > this->getZmax())
237  dz = pos.getZ() - this->getZmax();
238  else if (pos.getZ() < this->getZmin())
239  dz = this->getZmin() - pos.getZ();
240  else
241  return R;
242 
243  return sqrt(R*R + dz*dz);
244 
245  } else {
246 
247  if (pos.getZ() > this->getZmax())
248  return pos.getZ() - this->getZmax();
249  else if (pos.getZ() < this->getZmin())
250  return this->getZmin() - pos.getZ();
251  else
252  return 0.0;
253  }
254  }
255 
256 
257  /**
258  * Get square of distance between cylinder wall and given position.
259  *
260  * \param pos position
261  * \return square of distance
262  */
263  inline double getDistanceSquared(const JVector3D& pos) const
264  {
265  const double d = getDistance(pos);
266 
267  return d*d;
268  }
269 
270 
271  /**
272  * Get intersection points of axis with cylinder.
273  *
274  * \param axis axis
275  * \return up and down stream positions along axis
276  */
277  inline intersection_type getIntersection(const JAxis3D& axis) const
278  {
279  double path[] = { 0.0, 0.0 };
280 
281  if (fabs(axis.getDZ()) != 0.0) {
282 
283  // intersection with bottom or top surface
284 
285  const double Z[] = {
286  axis.getDZ() > 0 ? this->getZmin() : this->getZmax(),
287  axis.getDZ() > 0 ? this->getZmax() : this->getZmin()
288  };
289 
290  for (int i = 0; i != 2; ++i) {
291 
292  const double u = (Z[i] - axis.getZ()) / axis.getDZ();
293  const double x = axis.getX() + u * axis.getDX() - this->getX();
294  const double y = axis.getY() + u * axis.getDY() - this->getY();
295 
296  if (x*x + y*y <= this->getRadius() * this->getRadius()) {
297  path[i] = u;
298  }
299  }
300  }
301 
302  if (fabs(axis.getDZ()) != 1.0) {
303 
304  // intersection with cylinder wall
305 
306  const double x = axis.getX() - this->getX();
307  const double y = axis.getY() - this->getY();
308  const double dx = axis.getDX();
309  const double dy = axis.getDY();
310  const double R = this->getRadius();
311 
312  const double a = (dx * dx + dy * dy);
313  const double b = 2*(dx * x + dy * y);
314  const double c = (x * x + y * y) - R * R;
315 
316  const double q = b*b - 4*a*c;
317 
318  if (q >= 0) {
319 
320  const double u[] = {
321  (-b - sqrt(q)) / (2*a),
322  (-b + sqrt(q)) / (2*a)
323  };
324 
325  for (int i = 0; i != 2; ++i) {
326 
327  const double z = axis.getZ() + u[i] * axis.getDZ();
328 
329  if (z >= this->getZmin() && z <= this->getZmax()) {
330  path[i] = u[i];
331  }
332  }
333  }
334  }
335 
336  return std::make_pair(path[0], path[1]);
337  }
338 
339 
340  /**
341  * Read cylinder from input stream.
342  *
343  * \param in input stream
344  * \param cylinder cylinder
345  * \return input stream
346  */
347  friend inline std::istream& operator>>(std::istream& in, JCylinder3D& cylinder)
348  {
349  in >> static_cast<JCircle2D&>(cylinder);
350  in >> cylinder.zmin >> cylinder.zmax;
351 
352  return in;
353  }
354 
355 
356  /**
357  * Write cylinder to output stream.
358  *
359  * \param out output stream
360  * \param cylinder cylinder
361  * \return output stream
362  */
363  friend inline std::ostream& operator<<(std::ostream& out, const JCylinder3D& cylinder)
364  {
365  const JFormat format(out, getFormat<JCylinder3D>(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
366 
367  out << static_cast<const JCircle2D&>(cylinder);
368  out << ' ';
369  out << format << cylinder.zmin;
370  out << ' ';
371  out << format << cylinder.zmax;
372 
373  return out;
374  }
375 
376 
377  /**
378  * Read cylinder from input.
379  *
380  * \param in reader
381  * \param cylinder cylinder
382  * \return reader
383  */
384  friend inline JReader& operator>>(JReader& in, JCylinder3D& cylinder)
385  {
386  in >> static_cast<JCircle2D&>(cylinder);
387  in >> cylinder.zmin >> cylinder.zmax;
388 
389  return in;
390  }
391 
392 
393  /**
394  * Write cylinder to output.
395  *
396  * \param out writer
397  * \param cylinder cylinder
398  * \return writer
399  */
400  friend inline JWriter& operator<<(JWriter& out, const JCylinder3D& cylinder)
401  {
402  out << static_cast<const JCircle2D&>(cylinder);
403  out << cylinder.zmin << cylinder.zmax;
404 
405  return out;
406  }
407 
408 
409  protected:
410  double zmin;
411  double zmax;
412  };
413 }
414 
415 #endif
const JPosition2D & getPosition() const
Get position.
Definition: JPosition2D.hh:98
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:86
Interface for binary output.
double getRadius() const
Get radius.
Definition: JCircle2D.hh:144
JVector2D()
Default constructor.
Definition: JVector2D.hh:39
JPosition2D()
Default constructor.
Definition: JPosition2D.hh:44
Data structure for circle in two dimensions.
Definition: JCircle2D.hh:33
void setZmin(const double zmin)
Set minimal z position.
Definition: JCylinder3D.hh:133
friend JWriter & operator<<(JWriter &out, const JCylinder3D &cylinder)
Write cylinder to output.
Definition: JCylinder3D.hh:400
double getZmin() const
Get minimal z position.
Definition: JCylinder3D.hh:111
double getDistanceSquared(const JVector3D &pos) const
Get square of distance between cylinder wall and given position.
Definition: JCylinder3D.hh:263
JCylinder3D & add(const JVector3D &pos)
Add position.
Definition: JCylinder3D.hh:156
intersection_type getIntersection(const JAxis3D &axis) const
Get intersection points of axis with cylinder.
Definition: JCylinder3D.hh:277
friend JReader & operator>>(JReader &in, JCylinder3D &cylinder)
Read cylinder from input.
Definition: JCylinder3D.hh:384
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:347
Auxiliary class to temporarily define format specifications.
Definition: JManip.hh:632
JVector2D & sub(const JVector2D &vector)
Subtract vector.
Definition: JVector2D.hh:115
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:270
JPosition3D getCenter() const
Get centre.
Definition: JCylinder3D.hh:196
friend std::ostream & operator<<(std::ostream &out, const JCylinder3D &cylinder)
Write cylinder to output stream.
Definition: JCylinder3D.hh:363
Cylinder object.
Definition: JCylinder3D.hh:39
Data structure for vector in three dimensions.
Definition: JVector3D.hh:34
Mathematical constants.
then JCalibrateToT a
Definition: JTuneHV.sh:116
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:172
double getY() const
Get y position.
Definition: JVector3D.hh:104
Interface for binary input.
$WORKDIR driver txt done cat $WORKDIR driver txt<< EOFprocess ${DATAFILTER}$FILTER_HOST csh-c '(setenv ROOTSYS $ROOTSYS &&source $JPP_DIR/setenv.csh $JPP_DIR &&(JDataFilter-H\$SERVER\$-M\$LOGGER\$-d $DEBUG-u ${DATAFILTER}-P $PORT</dev/null > &/dev/null &))';process ${DATAWRITER}$WRITER_HOST csh-c '(setenv ROOTSYS $ROOTSYS &&source $JPP_DIR/setenv.csh $JPP_DIR &&(JDataWriter-H\$SERVER\$-M\$LOGGER\$-d $DEBUG-u ${DATAWRITER}</dev/null > &/dev/null &))';print enterevent ev_init{RC_CMD}event ev_reset{RC_CMD}event ev_init{RC_CMD}event ev_configure{RC_DFLTR%<$WORKDIR/ev_configure_datafilter.txt > RC_DQSIM<$WORKDIR/ev_configure_dqsimulator.txt > RC_DWRT path
I/O manipulators.
double getVolume() const
Get volume.
Definition: JCylinder3D.hh:185
$WORKDIR ev_configure_dqsimulator txt echo process $DQ_SIMULATOR $i $SOURCE_HOST[$index] csh c(setenv ROOTSYS $ROOTSYS &&source $JPP_DIR/setenv.csh $JPP_DIR &&($DQ_SIMULATOR\-u\$NAME\$\-H\$SERVER\$\-M\$LOGGER\$\-d $DEBUG</dev/null > &/dev/null &))'
double getZmax() const
Get maximal z position.
Definition: JCylinder3D.hh:122
then JCookie sh JDataQuality D $DETECTOR_ID R
Definition: JDataQuality.sh:41
then JMuonMCEvt f $INPUT_FILE o $INTERMEDIATE_FILE d
Definition: JMuonPath.sh:47
JCylinder3D()
Default constructor.
Definition: JCylinder3D.hh:52
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:208
void setZmax(const double zmax)
Set maximal z position.
Definition: JCylinder3D.hh:144
do set_variable MODULE getModule a $WORKDIR detector_a datx L $STRING JEditDetector a $WORKDIR detector_a datx M $MODULE setz o $WORKDIR detector_a datx JEditDetector a $WORKDIR detector_b datx M $MODULE setz o $WORKDIR detector_b datx done echo Output stored at $WORKDIR detector_a datx and $WORKDIR tripod_a txt JDrawDetector2D a $WORKDIR detector_a datx a $WORKDIR detector_b datx L BL o detector $FORMAT $BATCH JDrawDetector2D T $WORKDIR tripod_a txt T $WORKDIR tripod_b txt L BL o tripod $FORMAT $BATCH JCompareDetector a $WORKDIR detector_a datx b $WORKDIR detector_b datx o $WORKDIR abc root &dev null for KEY in X Y Z
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
double u[N+1]
Definition: JPolint.hh:776
std::pair< double, double > intersection_type
Type definition of intersection.
Definition: JCylinder3D.hh:46
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 JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
JCylinder3D(const JCircle2D &circle, const double zmin, const double zmax)
Constructor.
Definition: JCylinder3D.hh:66
double getDistance(const JVector3D &pos) const
Get distance between cylinder wall and given position.
Definition: JCylinder3D.hh:222
double getLength() const
Get length.
Definition: JVector2D.hh:199
Data structure for format specifications.
Definition: JManip.hh:522
do echo Generating $dir eval D
Definition: JDrawLED.sh:53
double getZ() const
Get z position.
Definition: JVector3D.hh:115
double getDZ() const
Get z direction.
Definition: JVersor3D.hh:117
const double epsilon
Definition: JQuadrature.cc:21