1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////
20 // A straight line is coded as a point (3 Double_t) and //
21 // 3 direction cosines //
23 ///////////////////////////////////////////////////////////////////
25 #include <Riostream.h>
28 #include "AliStrLine.h"
34 //________________________________________________________
35 AliStrLine::AliStrLine() :
40 // Default constructor
41 for(Int_t i=0;i<3;i++) {
46 SetIdPoints(65535,65535);
49 //________________________________________________________
50 AliStrLine::AliStrLine(const Double_t *const point, const Double_t *const cd, Bool_t twopoints, UShort_t id1, UShort_t id2) :
55 // Standard constructor
56 // if twopoints is true: point and cd are the 3D coordinates of
57 // two points defininig the straight line
58 // if twopoint is false: point represents the 3D coordinates of a point
59 // belonging to the straight line and cd is the
61 for(Int_t i=0;i<3;i++)
65 InitTwoPoints(point,cd);
67 InitDirection(point,cd);
73 //________________________________________________________
74 AliStrLine::AliStrLine(const Double_t *const point, const Double_t *const sig2point, const Double_t *const cd, Bool_t twopoints, UShort_t id1, UShort_t id2) :
79 // Standard constructor
80 // if twopoints is true: point and cd are the 3D coordinates of
81 // two points defininig the straight line
82 // if twopoint is false: point represents the 3D coordinates of a point
83 // belonging to the straight line and cd is the
85 for(Int_t i=0;i<3;i++)
86 fSigma2P0[i] = sig2point[i];
89 InitTwoPoints(point,cd);
91 InitDirection(point,cd);
96 //________________________________________________________
97 AliStrLine::AliStrLine(const Double_t *const point, const Double_t *const sig2point, const Double_t *const wmat, const Double_t *const cd, Bool_t twopoints, UShort_t id1, UShort_t id2) :
102 // Standard constructor
103 // if twopoints is true: point and cd are the 3D coordinates of
104 // two points defininig the straight line
105 // if twopoint is false: point represents the 3D coordinates of a point
106 // belonging to the straight line and cd is the
107 // direction in space
109 fWMatrix = new Double_t [6];
110 for(Int_t i=0;i<3;i++){
111 fSigma2P0[i] = sig2point[i];
112 for(Int_t j=0;j<3;j++)if(j>=i)fWMatrix[k++]=wmat[3*i+j];
115 InitTwoPoints(point,cd);
117 InitDirection(point,cd);
119 SetIdPoints(id1,id2);
122 //________________________________________________________
123 AliStrLine::AliStrLine(const AliStrLine &source):
131 for(Int_t i=0;i<3;i++){
132 fP0[i]=source.fP0[i];
133 fSigma2P0[i]=source.fSigma2P0[i];
134 fCd[i]=source.fCd[i];
137 fWMatrix = new Double_t [6];
138 for(Int_t i=0;i<6;i++)fWMatrix[i]=source.fWMatrix[i];
140 for(Int_t i=0;i<2;i++) fIdPoint[i]=source.fIdPoint[i];
143 //________________________________________________________
144 AliStrLine& AliStrLine::operator=(const AliStrLine& source)
146 // Assignment operator
148 TObject::operator=(source);
149 for(Int_t i=0;i<3;i++){
150 fP0[i]=source.fP0[i];
151 fSigma2P0[i]=source.fSigma2P0[i];
152 fCd[i]=source.fCd[i];
158 fWMatrix = new Double_t [6];
159 for(Int_t i=0;i<6;i++)fWMatrix[i]=source.fWMatrix[i];
161 for(Int_t i=0;i<2;i++) fIdPoint[i]=source.fIdPoint[i];
166 //________________________________________________________
167 void AliStrLine::GetWMatrix(Double_t *wmat)const {
168 // Getter for weighting matrix, as a [9] dim. array
171 for(Int_t i=0;i<3;i++){
172 for(Int_t j=0;j<3;j++){
174 wmat[3*i+j]=fWMatrix[k++];
177 wmat[3*i+j]=wmat[3*j+i];
183 //________________________________________________________
184 void AliStrLine::SetWMatrix(const Double_t *wmat) {
185 // Setter for weighting matrix, strating from a [9] dim. array
186 if(fWMatrix)delete [] fWMatrix;
187 fWMatrix = new Double_t [6];
189 for(Int_t i=0;i<3;i++){
190 for(Int_t j=0;j<3;j++)if(j>=i)fWMatrix[k++]=wmat[3*i+j];
194 //________________________________________________________
195 void AliStrLine::InitDirection(const Double_t *const point, const Double_t *const cd)
197 // Initialization from a point and a direction
198 Double_t norm = cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2];
201 norm = TMath::Sqrt(1./norm);
202 for(Int_t i=0;i<3;++i) {
208 else AliFatal("Null direction cosines!!!");
211 //________________________________________________________
212 void AliStrLine::InitTwoPoints(const Double_t *const pA, const Double_t *const pB)
214 // Initialization from the coordinates of two
215 // points in the space
217 for(Int_t i=0;i<3;i++)cd[i] = pB[i]-pA[i];
218 InitDirection(pA,cd);
221 //________________________________________________________
222 AliStrLine::~AliStrLine() {
224 if(fWMatrix)delete [] fWMatrix;
227 //________________________________________________________
228 void AliStrLine::PrintStatus() const {
229 // Print current status
230 cout <<"=======================================================\n";
231 cout <<"Direction cosines: ";
232 for(Int_t i=0;i<3;i++)cout <<fCd[i]<<"; ";
234 cout <<"Known point: ";
235 for(Int_t i=0;i<3;i++)cout <<fP0[i]<<"; ";
237 cout <<"Error on known point: ";
238 for(Int_t i=0;i<3;i++)cout <<TMath::Sqrt(fSigma2P0[i])<<"; ";
240 cout <<"Current value for the parameter: "<<fTpar<<endl;
243 //________________________________________________________
244 Int_t AliStrLine::IsParallelTo(const AliStrLine *line) const {
245 // returns 1 if lines are parallel, 0 if not paralel
246 const Double_t prec=1e-14;
250 Double_t vecpx=fCd[1]*cd2[2]-fCd[2]*cd2[1];
251 Double_t mod=TMath::Abs(fCd[1]*cd2[2])+TMath::Abs(fCd[2]*cd2[1]);
252 if(TMath::Abs(vecpx) > prec*mod) return 0;
254 Double_t vecpy=-fCd[0]*cd2[2]+fCd[2]*cd2[0];
255 mod=TMath::Abs(fCd[0]*cd2[2])+TMath::Abs(fCd[2]*cd2[0]);
256 if(TMath::Abs(vecpy) > prec*mod) return 0;
258 Double_t vecpz=fCd[0]*cd2[1]-fCd[1]*cd2[0];
259 mod=TMath::Abs(fCd[0]*cd2[1])+TMath::Abs(fCd[1]*cd2[0]);
260 if(TMath::Abs(vecpz) > prec) return 0;
264 //________________________________________________________
265 Int_t AliStrLine::Crossrphi(const AliStrLine *line)
267 // Cross 2 lines in the X-Y plane
268 const Double_t prec=1e-14;
269 const Double_t big=1e20;
276 Double_t c=p2[0]-fP0[0];
279 Double_t f=p2[1]-fP0[1];
280 Double_t deno = a*e-b*d;
281 Double_t mod=TMath::Abs(a*e)+TMath::Abs(b*d);
283 if(TMath::Abs(deno) > prec*mod) {
284 fTpar = (c*e-b*f)/deno;
293 //________________________________________________________
294 Int_t AliStrLine::CrossPoints(AliStrLine *line, Double_t *point1, Double_t *point2){
295 // Looks for the crossing point estimated starting from the
297 const Double_t prec=1e-14;
307 k1+=(fP0[i]-p2[i])*fCd[i];
308 k2+=(fP0[i]-p2[i])*cd2[i];
318 Double_t deno = a11*a22-a21*a12;
319 Double_t mod = TMath::Abs(a11*a22)+TMath::Abs(a21*a12);
320 if(TMath::Abs(deno) < prec*mod) return -1;
321 fTpar = (a11*k2-a21*k1) / deno;
322 Double_t par2 = (k1*a22-k2*a12) / deno;
324 GetCurrentPoint(point1);
325 line->GetCurrentPoint(point2);
328 //________________________________________________________________
329 Int_t AliStrLine::Cross(AliStrLine *line, Double_t *point)
332 //Finds intersection between lines
335 Int_t retcod=CrossPoints(line,point1,point2);
337 for(Int_t i=0;i<3;i++)point[i]=(point1[i]+point2[i])/2.;
344 //___________________________________________________________
345 Double_t AliStrLine::GetDCA(const AliStrLine *line) const
347 //Returns the distance of closest approach between two lines
348 const Double_t prec=1e-14;
354 Int_t ispar=IsParallelTo(line);
356 Double_t dist1q=0,dist2=0,mod=0;
358 dist1q+=(fP0[i]-p2[i])*(fP0[i]-p2[i]);
359 dist2+=(fP0[i]-p2[i])*fCd[i];
362 if(TMath::Abs(mod) > prec){
364 return TMath::Sqrt(dist1q-dist2*dist2);
368 perp[0]=fCd[1]*cd2[2]-fCd[2]*cd2[1];
369 perp[1]=-fCd[0]*cd2[2]+fCd[2]*cd2[0];
370 perp[2]=fCd[0]*cd2[1]-fCd[1]*cd2[0];
371 Double_t mod=0,dist=0;
373 mod+=perp[i]*perp[i];
374 dist+=(fP0[i]-p2[i])*perp[i];
376 if(TMath::Abs(mod) > prec) {
377 return TMath::Abs(dist/TMath::Sqrt(mod));
381 //________________________________________________________
382 void AliStrLine::GetCurrentPoint(Double_t *point) const {
383 // Fills the array point with the current value on the line
384 for(Int_t i=0;i<3;i++)point[i]=fP0[i]+fCd[i]*fTpar;
387 //________________________________________________________
388 Double_t AliStrLine::GetDistFromPoint(const Double_t *point) const
390 // computes distance from point
391 AliStrLine tmpline(point, fCd, kFALSE);
392 return GetDCA(&tmpline);
395 //________________________________________________________
396 Bool_t AliStrLine::GetParamAtRadius(Double_t r,Double_t &t1,Double_t &t2) const
398 // Input: radial distance from the origin (x=0, x=0) in the bending plane
399 // Returns a boolean: kTRUE if the line crosses the cylinder of radius r
400 // and axis coincident with the z axis. It returns kFALSE otherwise
401 // Output: t1 and t2 in ascending order. The parameters of the line at
402 // the two intersections with the cylinder
403 Double_t p1= fCd[0]*fP0[0]+fCd[1]*fP0[1];
404 Double_t p2=fCd[0]*fCd[0]+fCd[1]*fCd[1];
405 Double_t delta=p1*p1-p2*(fP0[0]*fP0[0]+fP0[1]*fP0[1]-r*r);
411 delta=TMath::Sqrt(delta);
416 // use delta as a temporary buffer
421 if(TMath::AreEqualAbs(t1,t2,1.e-9))t1=t2;