CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
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#include "CLHEP/Vector/defs.h"
18#include "CLHEP/Vector/ThreeVector.h"
19#include "CLHEP/Vector/ZMxpv.h"
20#include "CLHEP/Units/PhysicalConstants.h"
21
22#include <cmath>
23
24namespace CLHEP {
25
26//-*****************************
27// - 1 -
28// set (multiple components)
29// in various coordinate systems
30//
31//-*****************************
32
34 double r1,
35 double theta1,
36 double phi1) {
37 if ( r1 < 0 ) {
38 ZMthrowC (ZMxpvNegativeR(
39 "Spherical coordinates set with negative R"));
40 // No special return needed if warning is ignored.
41 }
42 if ( (theta1 < 0) || (theta1 > CLHEP::pi) ) {
43 ZMthrowC (ZMxpvUnusualTheta(
44 "Spherical coordinates set with theta not in [0, PI]"));
45 // No special return needed if warning is ignored.
46 }
47 double rho1 ( r1*std::sin(theta1));
48 setZ(r1 * std::cos(theta1));
49 setY(rho1 * std::sin (phi1));
50 setX(rho1 * std::cos (phi1));
51 return;
52} /* setSpherical (r, theta1, phi) */
53
55 double rho1,
56 double phi1,
57 double z1) {
58 if ( rho1 < 0 ) {
59 ZMthrowC (ZMxpvNegativeR(
60 "Cylindrical coordinates supplied with negative Rho"));
61 // No special return needed if warning is ignored.
62 }
63 setZ(z1);
64 setY(rho1 * std::sin (phi1));
65 setX(rho1 * std::cos (phi1));
66 return;
67} /* setCylindrical (r, phi, z) */
68
70 double rho1,
71 double phi1,
72 double theta1) {
73 if (rho1 == 0) {
74 ZMthrowC (ZMxpvZeroVector(
75 "Attempt set vector components rho, phi, theta with zero rho -- "
76 "zero vector is returned, ignoring theta and phi"));
77 set(0.0, 0.0, 0.0);
78 return;
79 }
80 if ( (theta1 == 0) || (theta1 == CLHEP::pi) ) {
81 ZMthrowA (ZMxpvInfiniteVector(
82 "Attempt set cylindrical vector vector with finite rho and "
83 "theta along the Z axis: infinite Z would be computed"));
84 }
85 if ( (theta1 < 0) || (theta1 > CLHEP::pi) ) {
86 ZMthrowC (ZMxpvUnusualTheta(
87 "Rho, phi, theta set with theta not in [0, PI]"));
88 // No special return needed if warning is ignored.
89 }
90 setZ(rho1 / std::tan (theta1));
91 setY(rho1 * std::sin (phi1));
92 setX(rho1 * std::cos (phi1));
93 return;
94} /* setCyl (rho, phi, theta) */
95
97 double rho1,
98 double phi1,
99 double eta1 ) {
100 if (rho1 == 0) {
101 ZMthrowC (ZMxpvZeroVector(
102 "Attempt set vector components rho, phi, eta with zero rho -- "
103 "zero vector is returned, ignoring eta and phi"));
104 set(0.0, 0.0, 0.0);
105 return;
106 }
107 double theta1 (2 * std::atan ( std::exp (-eta1) ));
108 setZ(rho1 / std::tan (theta1));
109 setY(rho1 * std::sin (phi1));
110 setX(rho1 * std::cos (phi1));
111 return;
112} /* setCyl (rho, phi, eta) */
113
114
115//************
116// - 3 -
117// Comparisons
118//
119//************
120
121int Hep3Vector::compare (const Hep3Vector & v) const {
122 if ( z() > v.z() ) {
123 return 1;
124 } else if ( z() < v.z() ) {
125 return -1;
126 } else if ( y() > v.y() ) {
127 return 1;
128 } else if ( y() < v.y() ) {
129 return -1;
130 } else if ( x() > v.x() ) {
131 return 1;
132 } else if ( x() < v.x() ) {
133 return -1;
134 } else {
135 return 0;
136 }
137} /* Compare */
138
139
140bool Hep3Vector::operator > (const Hep3Vector & v) const {
141 return (compare(v) > 0);
142}
143bool Hep3Vector::operator < (const Hep3Vector & v) const {
144 return (compare(v) < 0);
145}
146bool Hep3Vector::operator>= (const Hep3Vector & v) const {
147 return (compare(v) >= 0);
148}
149bool Hep3Vector::operator<= (const Hep3Vector & v) const {
150 return (compare(v) <= 0);
151}
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.x()) > TOOBIG) ||
209 (std::fabs (v1Xv2.y()) > TOOBIG) ||
210 (std::fabs (v1Xv2.z()) > 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.x()) > TOOBIG) ||
260 (std::fabs (eps_v1Xv2.y()) > TOOBIG) ||
261 (std::fabs (eps_v1Xv2.z()) > 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//-***********************
280// Helper Methods:
281// negativeInfinity()
282//-***********************
283
285 // A byte-order-independent way to return -Infinity
286 struct Dib {
287 union {
288 double d;
289 unsigned char i[8];
290 } u;
291 };
292 Dib negOne;
293 Dib posTwo;
294 negOne.u.d = -1.0;
295 posTwo.u.d = 2.0;
296 Dib value;
297 int k;
298 for (k=0; k<8; k++) {
299 value.u.i[k] = negOne.u.i[k] | posTwo.u.i[k];
300 }
301 return value.u.d;
302}
303
304} // namespace CLHEP
305
306
#define ZMthrowC(A)
Definition: ZMxpv.h:133
#define ZMthrowA(A)
Definition: ZMxpv.h:128
double z() const
void setRhoPhiEta(double rho, double phi, double eta)
Definition: SpaceVector.cc:96
bool operator>=(const Hep3Vector &v) const
Definition: SpaceVector.cc:146
static double tolerance
Definition: ThreeVector.h:394
double x() const
void setY(double)
double mag2() const
double y() const
void setSpherical(double r, double theta, double phi)
Definition: SpaceVector.cc:33
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
void setZ(double)
bool operator>(const Hep3Vector &v) const
Definition: SpaceVector.cc:140
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:237
double negativeInfinity() const
Definition: SpaceVector.cc:284
static double setTolerance(double tol)
Definition: SpaceVector.cc:271
double mag() const
bool operator<=(const Hep3Vector &v) const
Definition: SpaceVector.cc:149
void setCylindrical(double r, double phi, double z)
Definition: SpaceVector.cc:54
void set(double x, double y, double z)
int compare(const Hep3Vector &v) const
Definition: SpaceVector.cc:121
double howParallel(const Hep3Vector &v) const
Definition: SpaceVector.cc:168
double howOrthogonal(const Hep3Vector &v) const
Definition: SpaceVector.cc:219
void setX(double)
void setRhoPhiTheta(double rho, double phi, double theta)
Definition: SpaceVector.cc:69
bool operator<(const Hep3Vector &v) const
Definition: SpaceVector.cc:143
bool isParallel(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:184