Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UVector2.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UVector2
12 //
13 // 19.09.12 Marek Gayer
14 // Created from original implementation in CLHEP
15 // --------------------------------------------------------------------
16 
17 #include <cmath>
18 #include <iostream>
19 #include "UVector2.hh"
20 
21 double UVector2::tolerance = UVector2::ZMpvToleranceTicks * 2.22045e-16;
22 
23 double UVector2::setTolerance(double tol)
24 {
25  // Set the tolerance for UVector2s to be considered near one another
26  double oldTolerance(tolerance);
27  tolerance = tol;
28  return oldTolerance;
29 }
30 
31 double UVector2::operator()(int i) const
32 {
33  if (i == 0)
34  {
35  return x;
36  }
37  else if (i == 1)
38  {
39  return y;
40  }
41  else
42  {
43  // ZMthrowA(ZMxpvIndexRange("UVector2::operator(): bad index"));
44  return 0.0;
45  }
46 }
47 
48 double& UVector2::operator()(int i)
49 {
50  static double dummy;
51 
52  switch (i)
53  {
54  case X:
55  return x;
56  case Y:
57  return y;
58  default:
59  // ZMthrowA (ZMxpvIndexRange("UVector2::operator() : bad index"));
60  return dummy;
61  }
62 }
63 
64 void UVector2::rotate(double angler)
65 {
66  double s = std::sin(angler);
67  double c = std::cos(angler);
68  double xx = x;
69  x = c * xx - s * y;
70  y = s * xx + c * y;
71 }
72 
73 UVector2 operator/ (const UVector2& p, double a)
74 {
75  if (a == 0)
76  {
77  // ZMthrowA(ZMxpvInfiniteVector( "Division of UVector2 by zero"));
78  }
79  return UVector2(p.x / a, p.y / a);
80 }
81 
82 std::ostream& operator << (std::ostream& os, const UVector2& q)
83 {
84  os << "(" << q.x << ", " << q.y << ")";
85  return os;
86 }
87 
88 //void ZMinput2doubles ( std::istream & is, const char * type,
89 // double & x, double & y );
90 
91 /*
92 std::istream & operator>>(std::istream & is, UVector2 & p) {
93  double x, y;
94  ZMinput2doubles ( is, "UVector2", x, y );
95  p.set(x, y);
96  return is;
97 } // operator>>()
98 */
99 
100 UVector2::operator UVector3() const
101 {
102  return UVector3(x, y, 0.0);
103 }
104 
105 int UVector2::compare(const UVector2& v) const
106 {
107  if (y > v.y)
108  {
109  return 1;
110  }
111  else if (y < v.y)
112  {
113  return -1;
114  }
115  else if (x > v.x)
116  {
117  return 1;
118  }
119  else if (x < v.x)
120  {
121  return -1;
122  }
123  else
124  {
125  return 0;
126  }
127 } /* Compare */
128 
129 
130 bool UVector2::operator > (const UVector2& v) const
131 {
132  return (compare(v) > 0);
133 }
134 bool UVector2::operator < (const UVector2& v) const
135 {
136  return (compare(v) < 0);
137 }
138 bool UVector2::operator>= (const UVector2& v) const
139 {
140  return (compare(v) >= 0);
141 }
142 bool UVector2::operator<= (const UVector2& v) const
143 {
144  return (compare(v) <= 0);
145 }
146 
147 bool UVector2::isNear(const UVector2& p, double epsilon) const
148 {
149  double limit = dot(p) * epsilon * epsilon;
150  return ((*this - p).mag2() <= limit);
151 } /* isNear() */
152 
153 double UVector2::howNear(const UVector2& p) const
154 {
155  double d = (*this - p).mag2();
156  double pdp = dot(p);
157  if ((pdp > 0) && (d < pdp))
158  {
159  return std::sqrt(d / pdp);
160  }
161  else if ((pdp == 0) && (d == 0))
162  {
163  return 0;
164  }
165  else
166  {
167  return 1;
168  }
169 } /* howNear */
170 
171 double UVector2::howParallel(const UVector2& v) const
172 {
173  // | V1 x V2 | / | V1 dot V2 |
174  // Of course, the "cross product" is fictitious but the math is valid
175  double v1v2 = std::fabs(dot(v));
176  if (v1v2 == 0)
177  {
178  // Zero is parallel to no other vector except for zero.
179  return ((mag2() == 0) && (v.mag2() == 0)) ? 0 : 1;
180  }
181  double abscross = std::fabs(x * v.y - y - v.x);
182  if (abscross >= v1v2)
183  {
184  return 1;
185  }
186  else
187  {
188  return abscross / v1v2;
189  }
190 } /* howParallel() */
191 
193  double epsilon) const
194 {
195  // | V1 x V2 | <= epsilon * | V1 dot V2 |
196  // Of course, the "cross product" is fictitious but the math is valid
197  double v1v2 = std::fabs(dot(v));
198  if (v1v2 == 0)
199  {
200  // Zero is parallel to no other vector except for zero.
201  return ((mag2() == 0) && (v.mag2() == 0));
202  }
203  double abscross = std::fabs(x * v.y - y - v.x);
204  return (abscross <= epsilon * v1v2);
205 } /* isParallel() */
206 
207 double UVector2::howOrthogonal(const UVector2& v) const
208 {
209  // | V1 dot V2 | / | V1 x V2 |
210  // Of course, the "cross product" is fictitious but the math is valid
211  double v1v2 = std::fabs(dot(v));
212  if (v1v2 == 0)
213  {
214  return 0; // Even if one or both are 0, they are considered orthogonal
215  }
216  double abscross = std::fabs(x * v.y - y - v.x);
217  if (v1v2 >= abscross)
218  {
219  return 1;
220  }
221  else
222  {
223  return v1v2 / abscross;
224  }
225 } /* howOrthogonal() */
226 
228  double epsilon) const
229 {
230  // | V1 dot V2 | <= epsilon * | V1 x V2 |
231  // Of course, the "cross product" is fictitious but the math is valid
232  double v1v2 = std::fabs(dot(v));
233  double abscross = std::fabs(x * v.y - y - v.x);
234  return (v1v2 <= epsilon * abscross);
235 } /* isOrthogonal() */
236 
static double setTolerance(double tol)
Definition: UVector2.cc:23
const XML_Char * s
const char * p
Definition: xmltok.h:285
void rotate(double)
Definition: UVector2.cc:64
bool isParallel(const UVector2 &p, double epsilon=tolerance) const
Definition: UVector2.cc:192
bool isOrthogonal(const UVector2 &p, double epsilon=tolerance) const
Definition: UVector2.cc:227
int compare(const UVector2 &v) const
Definition: UVector2.cc:105
double howParallel(const UVector2 &p) const
Definition: UVector2.cc:171
double howOrthogonal(const UVector2 &p) const
Definition: UVector2.cc:207
bool operator<(const UVector2 &v) const
Definition: UVector2.cc:134
bool isNear(const UVector2 &p, double epsilon=tolerance) const
Definition: UVector2.cc:147
double x
Definition: UVector2.hh:195
bool operator>=(const UVector2 &v) const
Definition: UVector2.cc:138
double howNear(const UVector2 &p) const
Definition: UVector2.cc:153
double mag2() const
Definition: UVector2.hh:305
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
BasicVector3D< float > operator/(const BasicVector3D< float > &v, double a)
bool operator>(const UVector2 &v) const
Definition: UVector2.cc:130
double operator()(int i) const
Definition: UVector2.cc:31
bool operator<=(const UVector2 &v) const
Definition: UVector2.cc:142
double dot(const UVector2 &p) const
Definition: UVector2.hh:300
double y
Definition: UVector2.hh:196