-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Cartesian2D.h
262 lines (193 loc) · 6.47 KB
/
Cartesian2D.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// @(#)root/mathcore:$Id: b12794c790afad19142e34a401af6c233aba446b $
// Authors: W. Brown, M. Fischler, L. Moneta 2005
/**********************************************************************
* *
* Copyright (c) 2005 , LCG ROOT MathLib Team *
* & FNAL LCG ROOT Mathlib Team *
* *
* *
**********************************************************************/
// Header file for class Cartesian2D
//
// Created by: Lorenzo Moneta at Mon 16 Apr 2007
//
#ifndef ROOT_Math_GenVector_Cartesian2D
#define ROOT_Math_GenVector_Cartesian2D 1
#include "Math/GenVector/Polar2Dfwd.h"
#include "Math/Math.h"
namespace ROOT {
namespace Math {
//__________________________________________________________________________________________
/**
Class describing a 2D cartesian coordinate system
(x, y coordinates)
@ingroup GenVector
@sa Overview of the @ref GenVector "physics vector library"
*/
template <class T = double>
class Cartesian2D {
public :
typedef T Scalar;
static constexpr unsigned int Dimension = 2U;
/**
Default constructor with x=y=0
*/
Cartesian2D() : fX(0.0), fY(0.0) { }
/**
Constructor from x,y coordinates
*/
Cartesian2D(Scalar xx, Scalar yy) : fX(xx), fY(yy) { }
/**
Construct from any Vector or coordinate system implementing
X() and Y()
*/
template <class CoordSystem>
explicit constexpr Cartesian2D(const CoordSystem & v)
: fX(v.X()), fY(v.Y()) { }
// for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
// re-implement them ( there is no no need to have them with g++4)
/**
copy constructor
*/
Cartesian2D(const Cartesian2D & v) :
fX(v.X()), fY(v.Y()) { }
/**
assignment operator
*/
Cartesian2D & operator= (const Cartesian2D & v) {
fX = v.X();
fY = v.Y();
return *this;
}
/**
Set internal data based on 2 Scalar numbers
*/
void SetCoordinates(Scalar xx, Scalar yy) { fX=xx; fY=yy; }
/**
get internal data into 2 Scalar numbers
*/
void GetCoordinates(Scalar& xx, Scalar& yy ) const {xx=fX; yy=fY; }
Scalar X() const { return fX;}
Scalar Y() const { return fY;}
Scalar Mag2() const { return fX*fX + fY*fY; }
Scalar R() const { using std::sqrt; return sqrt(Mag2()); }
Scalar Phi() const { using std::atan2; return (fX == Scalar(0) && fY == Scalar(0)) ? Scalar(0) : atan2(fY, fX); }
/**
set the x coordinate value keeping y constant
*/
void SetX(Scalar a) { fX = a; }
/**
set the y coordinate value keeping x constant
*/
void SetY(Scalar a) { fY = a; }
/**
set all values using cartesian coordinates
*/
void SetXY(Scalar xx, Scalar yy ) {
fX=xx;
fY=yy;
}
/**
scale the vector by a scalar quantity a
*/
void Scale(Scalar a) { fX *= a; fY *= a; }
/**
negate the vector
*/
void Negate() { fX = -fX; fY = -fY; }
/**
rotate by an angle
*/
void Rotate(Scalar angle) {
using std::sin;
const Scalar s = sin(angle);
using std::cos;
const Scalar c = cos(angle);
SetCoordinates(c * fX - s * fY, s * fX + c * fY);
}
/**
Assignment from any class implementing x(),y()
(can assign from any coordinate system)
*/
template <class CoordSystem>
Cartesian2D & operator = (const CoordSystem & v) {
fX = v.x();
fY = v.y();
return *this;
}
/**
Exact equality
*/
bool operator == (const Cartesian2D & rhs) const {
return fX == rhs.fX && fY == rhs.fY;
}
bool operator != (const Cartesian2D & rhs) const {return !(operator==(rhs));}
// ============= Compatibility section ==================
// The following make this coordinate system look enough like a CLHEP
// vector that an assignment member template can work with either
Scalar x() const { return X();}
Scalar y() const { return Y();}
// ============= Overloads for improved speed ==================
template <class T2>
explicit constexpr Cartesian2D( const Polar2D<T2> & v )
{
const Scalar r = v.R(); // re-using this instead of calling v.X() and v.Y()
// is the speed improvement
using std::cos;
fX = r * cos(v.Phi());
using std::sin;
fY = r * sin(v.Phi());
}
// Technical note: This works even though only Polar2Dfwd.h is
// included (and in fact, including Polar2D.h would cause circularity
// problems). It works because any program **using** this ctor must itself
// be including Polar2D.h.
template <class T2>
Cartesian2D & operator = (const Polar2D<T2> & v)
{
const Scalar r = v.R();
using std::cos;
fX = r * cos(v.Phi());
using std::sin;
fY = r * sin(v.Phi());
return *this;
}
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
// ====== Set member functions for coordinates in other systems =======
void SetR(Scalar r);
void SetPhi(Scalar phi);
#endif
private:
/**
(Contiguous) data containing the coordinates values x and y
*/
T fX;
T fY;
};
} // end namespace Math
} // end namespace ROOT
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
// need to put here setter methods to resolve nasty cyclical dependencies
// I need to include other coordinate systems only when Cartesian is already defined
// since they depend on it
#include "Math/GenVector/GenVector_exception.h"
#include "Math/GenVector/Polar2D.h"
// ====== Set member functions for coordinates in other systems =======
namespace ROOT {
namespace Math {
template <class T>
void Cartesian2D<T>::SetR(Scalar r) {
GenVector_exception e("Cartesian2D::SetR() is not supposed to be called");
throw e;
Polar2D<Scalar> v(*this); v.SetR(r); *this = Cartesian2D<Scalar>(v);
}
template <class T>
void Cartesian2D<T>::SetPhi(Scalar phi) {
GenVector_exception e("Cartesian2D::SetPhi() is not supposed to be called");
throw e;
Polar2D<Scalar> v(*this); v.SetPhi(phi); *this = Cartesian2D<Scalar>(v);
}
} // end namespace Math
} // end namespace ROOT
#endif
#endif /* ROOT_Math_GenVector_Cartesian2D */