Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Ellipse.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id$
28 //
29 // ----------------------------------------------------------------------
30 // GEANT 4 class source file
31 //
32 // G4Ellipse.cc
33 //
34 // ----------------------------------------------------------------------
35 
36 #include "G4Ellipse.hh"
37 
38 #include "G4PhysicalConstants.hh"
39 #include "G4SystemOfUnits.hh"
40 #include "G4GeometryTolerance.hh"
41 
43  : semiAxis1(0.), semiAxis2(0.), ratioAxis2Axis1(0.), forTangent(.0)
44 {
45 }
46 
48 {
49 }
50 
52  : G4Conic(), semiAxis1(right.semiAxis1), semiAxis2(right.semiAxis2),
53  ratioAxis2Axis1(right.ratioAxis2Axis1), toUnitCircle(right.toUnitCircle),
54  forTangent(right.forTangent)
55 {
56  pShift = right.pShift;
57  position = right.position;
58  bBox = right.bBox;
59  start = right.start;
60  end = right.end;
61  pStart = right.pStart;
62  pEnd = right.pEnd;
63  pRange = right.pRange;
64  bounded = right.bounded;
65  sameSense = right.sameSense;
66 }
67 
69 {
70  if (&right == this) return *this;
71 
72  semiAxis1 = right.semiAxis1;
73  semiAxis2 = right.semiAxis2;
74  ratioAxis2Axis1 = right.ratioAxis2Axis1;
75  toUnitCircle = right.toUnitCircle;
76  forTangent = right.forTangent;
77  pShift = right.pShift;
78  position = right.position;
79  bBox = right.bBox;
80  start = right.start;
81  end = right.end;
82  pStart = right.pStart;
83  pEnd = right.pEnd;
84  pRange = right.pRange;
85  bounded = right.bounded;
86  sameSense = right.sameSense;
87 
88  return *this;
89 }
90 
92 {
93  G4Point3D newLocation = tr*position.GetLocation();
94  newLocation.setZ(0);
95  G4double axisZ = ( tr*position.GetPZ() ).unit().z();
96 
97  if (std::abs(axisZ)<G4GeometryTolerance::GetInstance()->GetAngularTolerance())
98  { return 0; }
99 
100  G4Vector3D newAxis(0, 0, axisZ>0? +1: -1);
101 
102  // get the parameter of an endpoint of an axis
103  // (this is a point the distance of which from the center is extreme)
104  G4Vector3D xPrime= tr*position.GetPX();
105  xPrime.setZ(0);
106  G4Vector3D yPrime= tr*position.GetPY();
107  yPrime.setZ(0);
108 
109  G4Vector3D a = G4Vector3D( semiAxis1*xPrime );
110  G4Vector3D b = G4Vector3D( semiAxis2*yPrime );
111 
112  G4double u;
113  G4double abmag = a.mag2()-b.mag2();
114  G4double prod = 2*a*b;
115 
116  if ((abmag > FLT_MAX) && (prod < -FLT_MAX))
117  u = -pi/8;
118  else if ((abmag < -FLT_MAX) && (prod > FLT_MAX))
119  u = 3*pi/8;
120  else if ((abmag < -FLT_MAX) && (prod < -FLT_MAX))
121  u = -3*pi/8;
122  else if ((std::abs(abmag) < perMillion) && (std::abs(prod) < perMillion))
123  u = 0.;
124  else
125  u = std::atan2(prod,abmag) / 2;
126 
127  // get the coordinate axis directions and the semiaxis lengths
128  G4Vector3D sAxis1 = G4Vector3D( a*std::cos(u)+b*std::sin(u) );
129  G4Vector3D sAxis2 = G4Vector3D( a*std::cos(u+pi/2)+b*std::sin(u+pi/2) );
130  G4double newSemiAxis1 = sAxis1.mag();
131  G4double newSemiAxis2 = sAxis2.mag();
132  G4Vector3D newRefDirection = sAxis1;
133 
134  // create the new ellipse
135  G4Axis2Placement3D newPosition;
136  newPosition.Init(newRefDirection, newAxis, newLocation);
137  G4Ellipse* r= new G4Ellipse;
138  r->Init(newPosition, newSemiAxis1, newSemiAxis2);
139 
140  // introduce the shift in the parametrization
141  // maybe the Sign must be changed?
142  r->SetPShift(u);
143 
144  // set the bounds when necessary
145  if (IsBounded())
146  r->SetBounds(GetPStart(), GetPEnd());
147 
148  // L. Broglia
149  // copy sense of the curve
151 
152  return r;
153 }
154 
156 {
157  // original implementation
158  // const G4Point3D& center = position.GetLocation();
159  // G4double maxEntent = std::max(semiAxis1, semiAxis2);
160  // G4Vector3D halfExtent(maxEntent, maxEntent, maxEntent);
161  // bBox.Init(center+halfExtent, center-halfExtent);
162 
163  // the bbox must include the start and endpoints as well as the
164  // extreme points if they lie on the curve
165  bBox.Init(GetStart(), GetEnd());
166 
167  // the parameter values
168  // belonging to the points with an extreme x, y and z coordinate
169  for (G4int i=0; i<3; i++)
170  {
171  G4double u= std::atan2(position.GetPY()(i)*semiAxis2,
172  position.GetPX()(i)*semiAxis1);
173  if (IsPOn(u))
174  bBox.Extend(GetPoint(u));
175 
176  if (IsPOn(u+pi))
177  bBox.Extend(GetPoint(u+pi));
178  }
179 }
180 
181 
183 {
184  // The tangent is computed from the 3D point representation
185  // for all conics. An alternaive implementation (based on
186  // the parametric point) might be worthwhile adding
187  // for efficiency.
188 
189  const G4Axis2Placement3D& pos = *(GetPosition());
191 
192  v=forTangent*p.y()*pos.GetPX() + p.x()*pos.GetPY();
193  if(GetSameSense())
194  v = -v;
195 
196  return true;
197 }
198