Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SpaceVector.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// ---------------------------------------------------------------------------
3//
4// This file is a part of the CLHEP - a Class Library for High Energy Physics.
5//
6// SpaceVector
7//
8// This is the implementation of those methods of the Hep3Vector class which
9// originated from the ZOOM SpaceVector class. Several groups of these methods
10// have been separated off into the following code units:
11//
12// SpaceVectorR.cc All methods involving rotation
13// SpaceVectorD.cc All methods involving angle decomposition
14// SpaceVectorP.cc Intrinsic properties and methods involving second vector
15//
16
17#ifdef GNUPRAGMA
18#pragma implementation
19#endif
20
23
24#include <cmath>
25
26namespace CLHEP {
27
28//-*****************************
29// - 1 -
30// set (multiple components)
31// in various coordinate systems
32//
33//-*****************************
34
36 double r1,
37 double theta1,
38 double phi1) {
39// if ( r1 < 0 ) {
40// std::cerr << "Hep3Vector::setSpherical() - "
41// << "Spherical coordinates set with negative R" << std::endl;
42// // No special return needed if warning is ignored.
43// }
44// if ( (theta1 < 0) || (theta1 > CLHEP::pi) ) {
45// std::cerr << "Hep3Vector::setSpherical() - "
46// << "Spherical coordinates set with theta not in [0, PI]" << std::endl;
47// // No special return needed if warning is ignored.
48// }
49 dz = r1 * std::cos(theta1);
50 double rho1 ( r1*std::sin(theta1));
51 dy = rho1 * std::sin (phi1);
52 dx = rho1 * std::cos (phi1);
53 return;
54} /* setSpherical (r, theta1, phi1) */
55
57 double rho1,
58 double phi1,
59 double z1) {
60// if ( rho1 < 0 ) {
61// std::cerr << "Hep3Vector::setCylindrical() - "
62// << "Cylindrical coordinates supplied with negative Rho" << std::endl;
63// // No special return needed if warning is ignored.
64// }
65 dz = z1;
66 dy = rho1 * std::sin (phi1);
67 dx = rho1 * std::cos (phi1);
68 return;
69} /* setCylindrical (r, phi, z) */
70
72 double rho1,
73 double phi1,
74 double theta1) {
75 if (rho1 == 0) {
76 std::cerr << "Hep3Vector::setRhoPhiTheta() - "
77 << "Attempt set vector components rho, phi, theta with zero rho -- "
78 << "zero vector is returned, ignoring theta and phi" << std::endl;
79 dx = 0; dy = 0; dz = 0;
80 return;
81 }
82// if ( (theta1 == 0) || (theta1 == CLHEP::pi) ) {
83// std::cerr << "Hep3Vector::setRhoPhiTheta() - "
84// << "Attempt set cylindrical vector vector with finite rho and "
85// << "theta along the Z axis: infinite Z would be computed" << std::endl;
86// }
87// if ( (theta1 < 0) || (theta1 > CLHEP::pi) ) {
88// std::cerr << "Hep3Vector::setRhoPhiTheta() - "
89// << "Rho, phi, theta set with theta not in [0, PI]" << std::endl;
90// // No special return needed if warning is ignored.
91// }
92 dz = rho1 / std::tan (theta1);
93 dy = rho1 * std::sin (phi1);
94 dx = rho1 * std::cos (phi1);
95 return;
96} /* setCyl (rho, phi, theta) */
97
99 double rho1,
100 double phi1,
101 double eta1 ) {
102 if (rho1 == 0) {
103 std::cerr << "Hep3Vector::setRhoPhiEta() - "
104 << "Attempt set vector components rho, phi, eta with zero rho -- "
105 << "zero vector is returned, ignoring eta and phi" << std::endl;
106 dx = 0; dy = 0; dz = 0;
107 return;
108 }
109 double theta1 (2 * std::atan ( std::exp (-eta1) ));
110 dz = rho1 / std::tan (theta1);
111 dy = rho1 * std::sin (phi1);
112 dx = rho1 * std::cos (phi1);
113 return;
114} /* setCyl (rho, phi, eta) */
115
116//************
117// - 3 -
118// Comparisons
119//
120//************
121
122int Hep3Vector::compare (const Hep3Vector & v) const {
123 if ( dz > v.dz ) {
124 return 1;
125 } else if ( dz < v.dz ) {
126 return -1;
127 } else if ( dy > v.dy ) {
128 return 1;
129 } else if ( dy < v.dy ) {
130 return -1;
131 } else if ( dx > v.dx ) {
132 return 1;
133 } else if ( dx < v.dx ) {
134 return -1;
135 } else {
136 return 0;
137 }
138} /* Compare */
139
140
141bool Hep3Vector::operator > (const Hep3Vector & v) const {
142 return (compare(v) > 0);
143}
144bool Hep3Vector::operator < (const Hep3Vector & v) const {
145 return (compare(v) < 0);
146}
147bool Hep3Vector::operator>= (const Hep3Vector & v) const {
148 return (compare(v) >= 0);
149}
150bool Hep3Vector::operator<= (const Hep3Vector & v) const {
151 return (compare(v) <= 0);
152}
153
154
155//-********
156// Nearness
157//-********
158
159// These methods all assume you can safely take mag2() of each vector.
160// Absolutely safe but slower and much uglier alternatives were
161// provided as build-time options in ZOOM SpaceVectors.
162// Also, much smaller codes were provided tht assume you can square
163// mag2() of each vector; but those return bad answers without warning
164// when components exceed 10**90.
165//
166// IsNear, HowNear, and DeltaR are found in ThreeVector.cc
167
168double Hep3Vector::howParallel (const Hep3Vector & v) const {
169 // | V1 x V2 | / | V1 dot V2 |
170 double v1v2 = std::fabs(dot(v));
171 if ( v1v2 == 0 ) {
172 // Zero is parallel to no other vector except for zero.
173 return ( (mag2() == 0) && (v.mag2() == 0) ) ? 0 : 1;
174 }
175 Hep3Vector v1Xv2 ( cross(v) );
176 double abscross = v1Xv2.mag();
177 if ( abscross >= v1v2 ) {
178 return 1;
179 } else {
180 return abscross/v1v2;
181 }
182} /* howParallel() */
183
185 double epsilon) const {
186 // | V1 x V2 | **2 <= epsilon **2 | V1 dot V2 | **2
187 // V1 is *this, V2 is v
188
189 static const double TOOBIG = std::pow(2.0,507);
190 static const double SCALE = std::pow(2.0,-507);
191 double v1v2 = std::fabs(dot(v));
192 if ( v1v2 == 0 ) {
193 return ( (mag2() == 0) && (v.mag2() == 0) );
194 }
195 if ( v1v2 >= TOOBIG ) {
196 Hep3Vector sv1 ( *this * SCALE );
197 Hep3Vector sv2 ( v * SCALE );
198 Hep3Vector sv1Xsv2 = sv1.cross(sv2);
199 double x2 = sv1Xsv2.mag2();
200 double limit = v1v2*SCALE*SCALE;
201 limit = epsilon*epsilon*limit*limit;
202 return ( x2 <= limit );
203 }
204
205 // At this point we know v1v2 can be squared.
206
207 Hep3Vector v1Xv2 ( cross(v) );
208 if ( (std::fabs (v1Xv2.dx) > TOOBIG) ||
209 (std::fabs (v1Xv2.dy) > TOOBIG) ||
210 (std::fabs (v1Xv2.dz) > TOOBIG) ) {
211 return false;
212 }
213
214 return ( (v1Xv2.mag2()) <= ((epsilon * v1v2) * (epsilon * v1v2)) );
215
216} /* isParallel() */
217
218
219double Hep3Vector::howOrthogonal (const Hep3Vector & v) const {
220 // | V1 dot V2 | / | V1 x V2 |
221
222 double v1v2 = std::fabs(dot(v));
223 //-| Safe because both v1 and v2 can be squared
224 if ( v1v2 == 0 ) {
225 return 0; // Even if one or both are 0, they are considered orthogonal
226 }
227 Hep3Vector v1Xv2 ( cross(v) );
228 double abscross = v1Xv2.mag();
229 if ( v1v2 >= abscross ) {
230 return 1;
231 } else {
232 return v1v2/abscross;
233 }
234
235} /* howOrthogonal() */
236
238 double epsilon) const {
239// | V1 x V2 | **2 <= epsilon **2 | V1 dot V2 | **2
240// V1 is *this, V2 is v
241
242 static const double TOOBIG = std::pow(2.0,507);
243 static const double SCALE = std::pow(2.0,-507);
244 double v1v2 = std::fabs(dot(v));
245 //-| Safe because both v1 and v2 can be squared
246 if ( v1v2 >= TOOBIG ) {
247 Hep3Vector sv1 ( *this * SCALE );
248 Hep3Vector sv2 ( v * SCALE );
249 Hep3Vector sv1Xsv2 = sv1.cross(sv2);
250 double x2 = sv1Xsv2.mag2();
251 double limit = epsilon*epsilon*x2;
252 double y2 = v1v2*SCALE*SCALE;
253 return ( y2*y2 <= limit );
254 }
255
256 // At this point we know v1v2 can be squared.
257
258 Hep3Vector eps_v1Xv2 ( cross(epsilon*v) );
259 if ( (std::fabs (eps_v1Xv2.dx) > TOOBIG) ||
260 (std::fabs (eps_v1Xv2.dy) > TOOBIG) ||
261 (std::fabs (eps_v1Xv2.dz) > TOOBIG) ) {
262 return true;
263 }
264
265 // At this point we know all the math we need can be done.
266
267 return ( v1v2*v1v2 <= eps_v1Xv2.mag2() );
268
269} /* isOrthogonal() */
270
271double Hep3Vector::setTolerance (double tol) {
272// Set the tolerance for Hep3Vectors to be considered near one another
273 double oldTolerance (tolerance);
274 tolerance = tol;
275 return oldTolerance;
276}
277
278//-***********************
279// Helper Methods:
280// negativeInfinity()
281//-***********************
282
284 // A byte-order-independent way to return -Infinity
285 struct Dib {
286 union {
287 double d;
288 unsigned char i[8];
289 } u;
290 };
291 Dib negOne;
292 Dib posTwo;
293 negOne.u.d = -1.0;
294 posTwo.u.d = 2.0;
295 Dib value;
296 int k;
297 for (k=0; k<8; k++) {
298 value.u.i[k] = negOne.u.i[k] | posTwo.u.i[k];
299 }
300 return value.u.d;
301}
302
303} // namespace CLHEP
void setRhoPhiEta(double rho, double phi, double eta)
Definition: SpaceVector.cc:98
bool operator>=(const Hep3Vector &v) const
Definition: SpaceVector.cc:147
static DLL_API double tolerance
Definition: ThreeVector.h:399
double mag2() const
void setSpherical(double r, double theta, double phi)
Definition: SpaceVector.cc:35
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
bool operator>(const Hep3Vector &v) const
Definition: SpaceVector.cc:141
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:237
double negativeInfinity() const
Definition: SpaceVector.cc:283
static double setTolerance(double tol)
Definition: SpaceVector.cc:271
double mag() const
bool operator<=(const Hep3Vector &v) const
Definition: SpaceVector.cc:150
void setCylindrical(double r, double phi, double z)
Definition: SpaceVector.cc:56
int compare(const Hep3Vector &v) const
Definition: SpaceVector.cc:122
double howParallel(const Hep3Vector &v) const
Definition: SpaceVector.cc:168
double howOrthogonal(const Hep3Vector &v) const
Definition: SpaceVector.cc:219
void setRhoPhiTheta(double rho, double phi, double theta)
Definition: SpaceVector.cc:71
bool operator<(const Hep3Vector &v) const
Definition: SpaceVector.cc:144
bool isParallel(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:184
Definition: DoubConv.h:17