Jpp test-rotations-old
the software that should make you happy
Loading...
Searching...
No Matches
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"
16
17
18/**
19 * \author mdejong
20 */
21
22namespace JGEOMETRY3D {}
23namespace JPP { using namespace JGEOMETRY3D; }
24
25namespace 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 */
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 */
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::minmax(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
I/O manipulators.
JFormat_t & getFormat()
Get format for given type.
Definition JManip.hh:682
Mathematical constants.
Data structure for circle in two dimensions.
Definition JCircle2D.hh:35
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
double getRadius() const
Get radius.
Definition JCircle2D.hh:144
const JPosition2D & getPosition() const
Get position.
JPosition2D()
Default constructor.
Data structure for vector in two dimensions.
Definition JVector2D.hh:34
double getY() const
Get y position.
Definition JVector2D.hh:74
double getX() const
Get x position.
Definition JVector2D.hh:63
JVector2D()
Default constructor.
Definition JVector2D.hh:39
JVector2D & sub(const JVector2D &vector)
Subtract vector.
Definition JVector2D.hh:115
double getLength() const
Get length.
Definition JVector2D.hh:199
Axis object.
Definition JAxis3D.hh:41
JCylinder3D(const JCircle2D &circle, const double zmin, const double zmax)
Constructor.
JCylinder3D(T __begin, T __end, const double precision=std::numeric_limits< double >::epsilon())
Constructor.
double getDistanceSquared(const JVector3D &pos) const
Get square of distance between cylinder wall and given position.
std::pair< double, double > intersection_type
Type definition of intersection.
friend std::istream & operator>>(std::istream &in, JCylinder3D &cylinder)
Read cylinder from input stream.
double getZmin() const
Get minimal z position.
double getVolume() const
Get volume.
bool is_inside(const JVector3D &pos) const
Check whether given point is inside cylinder.
friend std::ostream & operator<<(std::ostream &out, const JCylinder3D &cylinder)
Write cylinder to output stream.
intersection_type getIntersection(const JAxis3D &axis) const
Get intersection points of axis with cylinder.
friend JReader & operator>>(JReader &in, JCylinder3D &cylinder)
Read cylinder from input.
void setZmax(const double zmax)
Set maximal z position.
void setZmin(const double zmin)
Set minimal z position.
void addMargin(const double D)
Add (safety) margin.
friend JWriter & operator<<(JWriter &out, const JCylinder3D &cylinder)
Write cylinder to output.
JCylinder3D()
Default constructor.
double getDistance(const JVector3D &pos) const
Get distance between cylinder wall and given position.
JPosition3D getCenter() const
Get centre.
double getZmax() const
Get maximal z position.
JCylinder3D & add(const JVector3D &pos)
Add position.
Data structure for position in three dimensions.
Data structure for vector in three dimensions.
Definition JVector3D.hh:36
double getY() const
Get y position.
Definition JVector3D.hh:104
double getZ() const
Get z position.
Definition JVector3D.hh:115
double getX() const
Get x position.
Definition JVector3D.hh:94
double getDY() const
Get y direction.
Definition JVersor3D.hh:106
double getDX() const
Get x direction.
Definition JVersor3D.hh:95
double getDZ() const
Get z direction.
Definition JVersor3D.hh:117
Interface for binary input.
Interface for binary output.
Auxiliary classes and methods for 3D geometrical objects and operations.
Definition JAngle3D.hh:19
static const double PI
Mathematical constants.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Data structure for format specifications.
Definition JManip.hh:524
Auxiliary class to temporarily define format specifications.
Definition JManip.hh:636