#include <G4Ellipse.hh>
Inheritance diagram for G4Ellipse:
Public Member Functions | |
G4Ellipse () | |
virtual | ~G4Ellipse () |
G4Ellipse (const G4Ellipse &right) | |
G4Ellipse & | operator= (const G4Ellipse &right) |
G4Curve * | Project (const G4Transform3D &tr=G4Transform3D::Identity) |
G4bool | Tangent (G4CurvePoint &cp, G4Vector3D &v) |
G4double | GetPMax () const |
G4Point3D | GetPoint (G4double param) const |
G4double | GetPPoint (const G4Point3D &p) const |
G4double | GetSemiAxis1 () const |
G4double | GetSemiAxis2 () const |
void | Init (const G4Axis2Placement3D &position0, G4double semiAxis10, G4double semiAxis20) |
G4int | IntersectRay2D (const G4Ray &ray) |
Protected Member Functions | |
void | InitBounded () |
Definition at line 46 of file G4Ellipse.hh.
G4Ellipse::G4Ellipse | ( | ) |
G4Ellipse::~G4Ellipse | ( | ) | [virtual] |
G4Ellipse::G4Ellipse | ( | const G4Ellipse & | right | ) |
Definition at line 51 of file G4Ellipse.cc.
References G4Curve::bBox, G4Curve::bounded, G4Curve::end, G4Curve::pEnd, G4Conic::position, G4Curve::pRange, G4Conic::pShift, G4Curve::pStart, G4Curve::sameSense, and G4Curve::start.
00052 : G4Conic(), semiAxis1(right.semiAxis1), semiAxis2(right.semiAxis2), 00053 ratioAxis2Axis1(right.ratioAxis2Axis1), toUnitCircle(right.toUnitCircle), 00054 forTangent(right.forTangent) 00055 { 00056 pShift = right.pShift; 00057 position = right.position; 00058 bBox = right.bBox; 00059 start = right.start; 00060 end = right.end; 00061 pStart = right.pStart; 00062 pEnd = right.pEnd; 00063 pRange = right.pRange; 00064 bounded = right.bounded; 00065 sameSense = right.sameSense; 00066 }
G4double G4Ellipse::GetPMax | ( | ) | const [inline, virtual] |
Implements G4Curve.
Definition at line 77 of file G4Ellipse.icc.
References G4Axis2Placement3D::GetLocation(), G4Conic::GetPShift(), G4Axis2Placement3D::GetPX(), G4Axis2Placement3D::GetPY(), and G4Conic::position.
Referenced by InitBounded().
00078 { 00079 param-= GetPShift(); 00080 return G4Point3D( position.GetLocation() 00081 + semiAxis1*std::cos(param)*position.GetPX() 00082 + semiAxis2*std::sin(param)*position.GetPY() ); 00083 }
Implements G4Curve.
Definition at line 86 of file G4Ellipse.icc.
References G4Conic::GetPShift(), G4Axis2Placement3D::GetToPlacementCoordinates(), and G4Conic::position.
00087 { 00088 G4Point3D ptLocal= position.GetToPlacementCoordinates()*pt; 00089 G4double angle= std::atan2(ptLocal.y(), ptLocal.x()*ratioAxis2Axis1); 00090 G4double r= (angle<0)? angle+CLHEP::twopi: angle; 00091 return r+GetPShift(); 00092 }
G4double G4Ellipse::GetSemiAxis1 | ( | ) | const [inline] |
G4double G4Ellipse::GetSemiAxis2 | ( | ) | const [inline] |
void G4Ellipse::Init | ( | const G4Axis2Placement3D & | position0, | |
G4double | semiAxis10, | |||
G4double | semiAxis20 | |||
) | [inline] |
Definition at line 38 of file G4Ellipse.icc.
References G4Axis2Placement3D::GetToPlacementCoordinates(), G4Conic::position, and G4Curve::SetBounds().
Referenced by Project(), and G4CircularCurve::Project().
00040 { 00041 position= position0; 00042 semiAxis1= semiAxis10; 00043 semiAxis2= semiAxis20; 00044 00045 ratioAxis2Axis1= semiAxis2/semiAxis1; 00046 00047 SetBounds(0, 0); 00048 00049 // needed only for 2D ellipses 00050 toUnitCircle = G4Scale3D(1/semiAxis1, 1/semiAxis2, 0) 00051 * position.GetToPlacementCoordinates(); 00052 00053 forTangent= -semiAxis1*semiAxis1/(semiAxis2*semiAxis2); 00054 }
void G4Ellipse::InitBounded | ( | ) | [protected, virtual] |
Implements G4Curve.
Definition at line 155 of file G4Ellipse.cc.
References G4Curve::bBox, G4BoundingBox3D::Extend(), G4Curve::GetEnd(), GetPoint(), G4Axis2Placement3D::GetPX(), G4Axis2Placement3D::GetPY(), G4Curve::GetStart(), G4BoundingBox3D::Init(), G4Curve::IsPOn(), G4INCL::Math::pi, and G4Conic::position.
00156 { 00157 // original implementation 00158 // const G4Point3D& center = position.GetLocation(); 00159 // G4double maxEntent = std::max(semiAxis1, semiAxis2); 00160 // G4Vector3D halfExtent(maxEntent, maxEntent, maxEntent); 00161 // bBox.Init(center+halfExtent, center-halfExtent); 00162 00163 // the bbox must include the start and endpoints as well as the 00164 // extreme points if they lie on the curve 00165 bBox.Init(GetStart(), GetEnd()); 00166 00167 // the parameter values 00168 // belonging to the points with an extreme x, y and z coordinate 00169 for (G4int i=0; i<3; i++) 00170 { 00171 G4double u= std::atan2(position.GetPY()(i)*semiAxis2, 00172 position.GetPX()(i)*semiAxis1); 00173 if (IsPOn(u)) 00174 bBox.Extend(GetPoint(u)); 00175 00176 if (IsPOn(u+pi)) 00177 bBox.Extend(GetPoint(u+pi)); 00178 } 00179 }
Implements G4Curve.
Definition at line 141 of file G4Ellipse.icc.
References G4Ray::GetDir(), G4Ray::GetStart(), and G4Curve::kCarTolerance.
00142 { 00143 // transform s.t. the ellipse becomes the unit circle 00144 // with the center at the origin 00145 00146 // 2D operations would be faster 00147 G4Point3D st= toUnitCircle*ray.GetStart(); 00148 G4Vector3D d= toUnitCircle*ray.GetDir(); 00149 00150 // solve (st+i*t)^2 = 1 for i (the distance) 00151 G4double sd= st*d; 00152 G4double dd= d.mag2(); // never 0 00153 G4double ss= st.mag2(); 00154 00155 G4double discr= sd*sd-dd*(ss-1); 00156 G4int nbinter = 0; 00157 G4double i; 00158 00159 if (discr > 0) 00160 { 00161 // 2 intersections 00162 G4double sqrtdiscr= std::sqrt(discr); 00163 00164 // if i is positive, we have an intersection 00165 i= -sd-sqrtdiscr; 00166 if (i > kCarTolerance) 00167 nbinter++; 00168 00169 i= -sd+sqrtdiscr; 00170 if (i > kCarTolerance) 00171 nbinter++; 00172 } 00173 00174 // if the ray is tangent on the circle 00175 if (discr == 0) 00176 nbinter = 1; 00177 00178 return nbinter; 00179 }
Definition at line 68 of file G4Ellipse.cc.
References G4Curve::bBox, G4Curve::bounded, G4Curve::end, forTangent, G4Curve::pEnd, G4Conic::position, G4Curve::pRange, G4Conic::pShift, G4Curve::pStart, ratioAxis2Axis1, G4Curve::sameSense, semiAxis1, semiAxis2, G4Curve::start, and toUnitCircle.
00069 { 00070 if (&right == this) return *this; 00071 00072 semiAxis1 = right.semiAxis1; 00073 semiAxis2 = right.semiAxis2; 00074 ratioAxis2Axis1 = right.ratioAxis2Axis1; 00075 toUnitCircle = right.toUnitCircle; 00076 forTangent = right.forTangent; 00077 pShift = right.pShift; 00078 position = right.position; 00079 bBox = right.bBox; 00080 start = right.start; 00081 end = right.end; 00082 pStart = right.pStart; 00083 pEnd = right.pEnd; 00084 pRange = right.pRange; 00085 bounded = right.bounded; 00086 sameSense = right.sameSense; 00087 00088 return *this; 00089 }
G4Curve * G4Ellipse::Project | ( | const G4Transform3D & | tr = G4Transform3D::Identity |
) | [virtual] |
Implements G4Curve.
Definition at line 91 of file G4Ellipse.cc.
References FLT_MAX, G4GeometryTolerance::GetInstance(), G4Axis2Placement3D::GetLocation(), G4Curve::GetPEnd(), G4Curve::GetPStart(), G4Axis2Placement3D::GetPX(), G4Axis2Placement3D::GetPY(), G4Axis2Placement3D::GetPZ(), G4Curve::GetSameSense(), Init(), G4Axis2Placement3D::Init(), G4Curve::IsBounded(), G4INCL::Math::pi, G4Conic::position, G4Curve::SetBounds(), G4Conic::SetPShift(), and G4Curve::SetSameSense().
Referenced by G4CircularCurve::Project().
00092 { 00093 G4Point3D newLocation = tr*position.GetLocation(); 00094 newLocation.setZ(0); 00095 G4double axisZ = ( tr*position.GetPZ() ).unit().z(); 00096 00097 if (std::abs(axisZ)<G4GeometryTolerance::GetInstance()->GetAngularTolerance()) 00098 { return 0; } 00099 00100 G4Vector3D newAxis(0, 0, axisZ>0? +1: -1); 00101 00102 // get the parameter of an endpoint of an axis 00103 // (this is a point the distance of which from the center is extreme) 00104 G4Vector3D xPrime= tr*position.GetPX(); 00105 xPrime.setZ(0); 00106 G4Vector3D yPrime= tr*position.GetPY(); 00107 yPrime.setZ(0); 00108 00109 G4Vector3D a = G4Vector3D( semiAxis1*xPrime ); 00110 G4Vector3D b = G4Vector3D( semiAxis2*yPrime ); 00111 00112 G4double u; 00113 G4double abmag = a.mag2()-b.mag2(); 00114 G4double prod = 2*a*b; 00115 00116 if ((abmag > FLT_MAX) && (prod < -FLT_MAX)) 00117 u = -pi/8; 00118 else if ((abmag < -FLT_MAX) && (prod > FLT_MAX)) 00119 u = 3*pi/8; 00120 else if ((abmag < -FLT_MAX) && (prod < -FLT_MAX)) 00121 u = -3*pi/8; 00122 else if ((std::abs(abmag) < perMillion) && (std::abs(prod) < perMillion)) 00123 u = 0.; 00124 else 00125 u = std::atan2(prod,abmag) / 2; 00126 00127 // get the coordinate axis directions and the semiaxis lengths 00128 G4Vector3D sAxis1 = G4Vector3D( a*std::cos(u)+b*std::sin(u) ); 00129 G4Vector3D sAxis2 = G4Vector3D( a*std::cos(u+pi/2)+b*std::sin(u+pi/2) ); 00130 G4double newSemiAxis1 = sAxis1.mag(); 00131 G4double newSemiAxis2 = sAxis2.mag(); 00132 G4Vector3D newRefDirection = sAxis1; 00133 00134 // create the new ellipse 00135 G4Axis2Placement3D newPosition; 00136 newPosition.Init(newRefDirection, newAxis, newLocation); 00137 G4Ellipse* r= new G4Ellipse; 00138 r->Init(newPosition, newSemiAxis1, newSemiAxis2); 00139 00140 // introduce the shift in the parametrization 00141 // maybe the Sign must be changed? 00142 r->SetPShift(u); 00143 00144 // set the bounds when necessary 00145 if (IsBounded()) 00146 r->SetBounds(GetPStart(), GetPEnd()); 00147 00148 // L. Broglia 00149 // copy sense of the curve 00150 r->SetSameSense(GetSameSense()); 00151 00152 return r; 00153 }
G4bool G4Ellipse::Tangent | ( | G4CurvePoint & | cp, | |
G4Vector3D & | v | |||
) | [virtual] |
Implements G4Curve.
Definition at line 182 of file G4Ellipse.cc.
References G4CurvePoint::GetPoint(), G4Conic::GetPosition(), G4Axis2Placement3D::GetPX(), G4Axis2Placement3D::GetPY(), G4Curve::GetSameSense(), and G4Axis2Placement3D::GetToPlacementCoordinates().
00183 { 00184 // The tangent is computed from the 3D point representation 00185 // for all conics. An alternaive implementation (based on 00186 // the parametric point) might be worthwhile adding 00187 // for efficiency. 00188 00189 const G4Axis2Placement3D& pos = *(GetPosition()); 00190 G4Point3D p= pos.GetToPlacementCoordinates() * cp.GetPoint(); 00191 00192 v=forTangent*p.y()*pos.GetPX() + p.x()*pos.GetPY(); 00193 if(GetSameSense()) 00194 v = -v; 00195 00196 return true; 00197 }