vector.cc
1 #include "vector.hh"
2 #include "Constants.h"
3 #include <cmath>
4 #include "TVector3.h"
5 #include "TRotation.h"
6 
7 #if defined(ANITA_UTIL_EXISTS) and defined(VECTORIZE)
8 #include "vectormath_trig.h"
9 #endif
10 
11 using std::cout;
12 
13 Vector::Vector(double x_inp,double y_inp,double z_inp) {
14  x = x_inp;
15  y = y_inp;
16  z = z_inp;
17  angles_need_updating = true;
18 } //Constructor Vector(double,double,double)
19 Vector::Vector(double* xarray) {
20  x=xarray[0];
21  y=xarray[1];
22  z=xarray[2];
23  angles_need_updating = true;
24 }
25 Vector::Vector(double theta_inp, double phi_inp) {
26 
27  if (theta_inp < 0.0 || theta_inp > PI) {
28 
29  cout<<"Error! Attempt to construct Vector from invalid theta!\n";
30 
31  x = 0.;
32  y = 0.;
33  z = 1.;
34  UpdateThetaPhi();
35  } //check to see if theta is valid
36 
37  x = sin(theta_inp) * cos(phi_inp);
38  y = sin(theta_inp) * sin(phi_inp);
39  z = cos(theta_inp);
40 
41  theta = theta_inp;
42  phi = phi_inp;
43  angles_need_updating = false;
44 } //Constructor Vector(theta,phi)
45 
46 Vector::Vector() {
47  x = 0.;
48  y = 0.;
49  z = 1.;
50  theta = 0;
51  phi = 0;
52  angles_need_updating = false;
53 } //Vector default constructor
54 
55 Vector Vector::Cross(const Vector &vec) const {
56  return Vector(y * vec.z - z * vec.y,
57  -x * vec.z + z * vec.x,
58  x * vec.y - y * vec.x);
59 } //Vector::Cross
60 
61 double Vector::Dot(const Vector &vec) const
62 {return x * vec.x +y * vec.y + z * vec.z ;}
63 //Takes the dot product this x vec.
64 
65 double Vector::Mag() const {
66  return sqrt(x*x + y*y + z*z);
67 } //Vector::Mag
68 
69 double Vector::Angle(const Vector &vec) const {
70  return acos(((*this)*vec) / (this->Mag() * vec.Mag()));
71 } //Vector::Angle
72 
73 Vector Vector::ChangeCoord(const Vector &new_x_axis,const Vector &new_y_axis) const {
74 
75 
76  TVector3 temp;
77  temp.SetX(this->GetX());
78  temp.SetY(this->GetY());
79  temp.SetZ(this->GetZ());
80 
81  TVector3 tnew_x_axis;
82  tnew_x_axis.SetX(new_x_axis.GetX());
83  tnew_x_axis.SetY(new_x_axis.GetY());
84  tnew_x_axis.SetZ(new_x_axis.GetZ());
85 
86  TVector3 tnew_y_axis;
87  tnew_y_axis.SetX(new_y_axis.GetX());
88  tnew_y_axis.SetY(new_y_axis.GetY());
89  tnew_y_axis.SetZ(new_y_axis.GetZ());
90 
91  //cout << "before trotation.\n";
92  TRotation r;
93  r.SetXAxis(tnew_x_axis);
94  r.SetYAxis(tnew_y_axis);
95  r.SetZAxis(tnew_x_axis.Cross(tnew_y_axis));
96  //cout << "tnew_x_axis is ";
97  //tnew_x_axis.Print();
98  //cout << "tnew_y_axis is ";
99  //tnew_y_axis.Print();
100  //cout << "tnew_z_axis is ";
101  //(tnew_x_axis.Cross(tnew_y_axis)).Print();
102 
103  // cout << "after trotation.\n";
104 
105  //r.SetToIdentity();
106  //r.RotateAxes(newX,newY,newZ);
107  //r.Invert();
108 
109  temp.Transform(r);
110 
111  Vector new_vector;
112  new_vector.SetX(temp.X());
113  new_vector.SetY(temp.Y());
114  new_vector.SetZ(temp.Z());
115 
116 
117 
118  //Vector new_vector = this->RotateY(new_z_axis.theta);
119  //new_vector = new_vector.RotateZ(new_z_axis.phi);
120 
121  return new_vector;
122 } //Vector::ChangeCoord
123 
124 Vector Vector::ChangeCoord(const Vector &new_z_axis) const {
125 
126  Vector new_vector = this->RotateY(new_z_axis.Theta());
127  new_vector = new_vector.RotateZ(new_z_axis.Phi());
128 
129  return new_vector;
130 
131 }
132 
133 Vector Vector::Unit() const {
134  return (*this) / this->Mag();
135 } //Vector::Unit
136 
137 void Vector::Print() const {
138  cout << x << " " << y << " " << z << "\n";
139 }
140 double Vector::Theta() const {
141  if (angles_need_updating) UpdateThetaPhi();
142  return theta;
143 } //Vector::Theta
144 
145 double Vector::Phi() const {
146  if (angles_need_updating) UpdateThetaPhi();
147  return phi;
148 } //Vector::Phi
149 
150 Vector Vector::RotateX(double angle) const {
151  double new_x = x;
152  double new_y = cos(angle)*y - sin(angle)*z;
153  double new_z = sin(angle)*y + cos(angle)*z;
154  Vector rotated_vector(new_x,new_y,new_z);
155  return rotated_vector;
156 } //RotateX
157 
158 Vector Vector::RotateY(double angle) const {
159  double new_x = cos(angle)*x + sin(angle)*z;
160  double new_y = y;
161  double new_z = -sin(angle)*x + cos(angle)*z;
162  Vector rotated_vector(new_x,new_y,new_z);
163  return rotated_vector;
164 } //RotateY
165 
166 Vector Vector::RotateZ(double angle) const {
167  // double new_x = cos(angle)*x - sin(angle)*y;
168  // double new_y = sin(angle)*x + cos(angle)*y;
169  // double new_z = z;
170  double cosangle = cos(angle);
171  double sinangle = sin(angle);
172  Vector rotated_vector(cosangle*x - sinangle*y,sinangle*x + cosangle*y,z);
173  return rotated_vector;
174 } //RotateZ
175 
176 Vector Vector::Rotate(const double angle,const Vector& axis) const {
177  //Code blatently stolen from Root's TRotation::Rotate method
178  //Example: If you rotate the vector (0,0,1) by 90 degrees around the vector (0,1,0), the result is (1,0,0).
179  double length = axis.Mag();
180 
181  double s = sin(angle);
182  double c = cos(angle);
183  double dx = axis.x / length;
184  double dy = axis.y / length;
185  double dz = axis.z / length;
186 
187  double newx = (c+(1-c)*dx*dx) * x + ((1-c)*dx*dy-s*dz) * y + ((1-c)*dx*dz+s*dy) * z;
188  double newy = ((1-c)*dy*dx+s*dz) * x + (c+(1-c)*dy*dy) * y + ((1-c)*dy*dz-s*dx) * z;
189  double newz = ((1-c)*dz*dx-s*dy) * x + ((1-c)*dz*dy+s*dx) * y + (c+(1-c)*dz*dz) * z;
190 
191  return Vector(newx,newy,newz);
192 } //Vector::Rotate
193 
194 void Vector::UpdateThetaPhi() const {
195  //This is a private method that will calculate values of theta and phi from x,y,z coordinates,
196  //and store the results in the class variables.
197  //double transverse = hypot(x,y);
198  double transverse = sqrt(x*x+y*y);
199 
200 #if defined(ANITA_UTIL_EXISTS) and defined(VECTORIZE)
201 
202  Vec2d Y(transverse,y);
203  Vec2d X(z,x);
204  Vec2d answer = atan2(Y,X);
205  theta = answer[0];
206  phi = answer[1];
207 #else
208  // atan2 outputs in the range -pi to pi
209  theta = atan2(transverse,z);
210  phi=atan2(y,x);
211 #endif
212 
213  if (phi<0)
214  phi+=2*PI;
215  // phi is now from 0 to 2*pi wrt +x
216  angles_need_updating = false;
217 
218 } //UpdateThetaPhi
219 Vector Vector::Zero() {
220  //Zero the vector
221 
222  x=0;
223  y=0;
224  z=0;
225  return Vector(x,y,z);
226 } // Zero
227 
228 
229 
230 
231 
232 
233 
234 ostream& operator <<(ostream& outs, const Vector& vec) {
235  cout<<vec.x<<","<<vec.y<<","<<vec.z;
236  return outs;
237 } //Vector overloaded operator <<
238 
239 
240 Vector Vector::Orthogonal() const
241 {
242  //this is based on ROOT's implementation which might be based on Geant4's?
243 
244  Double_t xx = fabs(x);
245  Double_t yy = fabs(y);
246  Double_t zz = fabs(z);
247  if (xx < yy) {
248  return xx < zz ? Vector(0,z,-y) : Vector(y,-x,0);
249  } else {
250  return yy < zz ? Vector(-z,0,x) : Vector(y,-x,0);
251  }
252 }
Inelasticity distributions: stores parametrizations and picks inelasticities.
Definition: Primaries.h:38
This class represents a three-vector. Operators are overloaded to provide for the familiar operations...
Definition: vector.hh:27