G4ClippablePolygon Class Reference

#include <G4ClippablePolygon.hh>


Public Member Functions

 G4ClippablePolygon ()
virtual ~G4ClippablePolygon ()
virtual void AddVertexInOrder (const G4ThreeVector vertex)
virtual void ClearAllVertices ()
void SetNormal (const G4ThreeVector &newNormal)
const G4ThreeVector GetNormal () const
virtual G4bool Clip (const G4VoxelLimits &voxelLimit)
virtual G4bool PartialClip (const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void ClipAlongOneAxis (const G4VoxelLimits &voxelLimit, const EAxis axis)
virtual G4bool GetExtent (const EAxis axis, G4double &min, G4double &max) const
virtual const G4ThreeVectorGetMinPoint (const EAxis axis) const
virtual const G4ThreeVectorGetMaxPoint (const EAxis axis) const
G4int GetNumVertices () const
G4bool Empty () const
virtual G4bool InFrontOf (const G4ClippablePolygon &other, EAxis axis) const
virtual G4bool BehindOf (const G4ClippablePolygon &other, EAxis axis) const
virtual G4bool GetPlanerExtent (const G4ThreeVector &pointOnPlane, const G4ThreeVector &planeNormal, G4double &min, G4double &max) const

Protected Member Functions

void ClipToSimpleLimits (G4ThreeVectorList &pPolygon, G4ThreeVectorList &outputPolygon, const G4VoxelLimits &pVoxelLimit)

Protected Attributes

G4ThreeVectorList vertices
G4ThreeVector normal
G4double kCarTolerance


Detailed Description

Definition at line 55 of file G4ClippablePolygon.hh.


Constructor & Destructor Documentation

G4ClippablePolygon::G4ClippablePolygon (  ) 

Definition at line 48 of file G4ClippablePolygon.cc.

References G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetSurfaceTolerance(), and kCarTolerance.

00049   : normal(0.,0.,0.)
00050 {
00051   kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
00052 }

G4ClippablePolygon::~G4ClippablePolygon (  )  [virtual]

Definition at line 58 of file G4ClippablePolygon.cc.

00059 {
00060 }


Member Function Documentation

void G4ClippablePolygon::AddVertexInOrder ( const G4ThreeVector  vertex  )  [virtual]

Definition at line 66 of file G4ClippablePolygon.cc.

References vertices.

Referenced by G4Hype::AddPolyToExtent(), G4PolyPhiFace::CalculateExtent(), G4PolyhedraSide::CalculateExtent(), G4PolyconeSide::CalculateExtent(), G4Hype::CalculateExtent(), G4EllipticalTube::CalculateExtent(), and G4EllipticalCone::CalculateExtent().

00067 {
00068   vertices.push_back( vertex );
00069 }

G4bool G4ClippablePolygon::BehindOf ( const G4ClippablePolygon other,
EAxis  axis 
) const [virtual]

Definition at line 296 of file G4ClippablePolygon.cc.

References Empty(), GetMaxPoint(), GetNormal(), GetPlanerExtent(), kCarTolerance, normal, and vertices.

Referenced by G4SolidExtentList::AddSurface().

00298 {
00299   //
00300   // If things are empty, do something semi-sensible
00301   //
00302   G4int noLeft = vertices.size();
00303   if (noLeft==0) return false;
00304   
00305   if (other.Empty()) return true;
00306 
00307   //
00308   // Get minimum of other polygon
00309   //
00310   const G4ThreeVector *maxPointOther = other.GetMaxPoint( axis );
00311   const G4double maxOther = maxPointOther->operator()(axis);
00312   
00313   //
00314   // Get minimum of this polygon
00315   //
00316   const G4ThreeVector *maxPoint = GetMaxPoint( axis );
00317   const G4double max = maxPoint->operator()(axis);
00318   
00319   //
00320   // Easy decision
00321   //
00322   if (max > maxOther+kCarTolerance) return true;    // Clear winner
00323   
00324   if (maxOther > max+kCarTolerance) return false;    // Clear loser
00325   
00326   //
00327   // We have a tie (this will not be all that rare since our
00328   // polygons are connected)
00329   //
00330   // Check to see if there is a vertex in the other polygon
00331   // that is in front of this one (or vice versa)
00332   //
00333   G4bool answer;
00334   G4ThreeVector normalOther = other.GetNormal();
00335   
00336   if (std::fabs(normalOther(axis)) > std::fabs(normal(axis)))
00337   {
00338     G4double minP, maxP;
00339     GetPlanerExtent( *maxPointOther, normalOther, minP, maxP );
00340     
00341     answer = (normalOther(axis) > 0) ? (maxP > +kCarTolerance)
00342                                      : (minP < -kCarTolerance);
00343   }
00344   else
00345   {
00346     G4double minP, maxP;
00347     other.GetPlanerExtent( *maxPoint, normal, minP, maxP );
00348     
00349     answer = (normal(axis) > 0) ? (minP < -kCarTolerance)
00350                                 : (maxP > +kCarTolerance);
00351   }
00352   return answer;
00353 }

void G4ClippablePolygon::ClearAllVertices (  )  [virtual]

Definition at line 75 of file G4ClippablePolygon.cc.

References vertices.

Referenced by G4PolyconeSide::CalculateExtent(), G4EllipticalTube::CalculateExtent(), and G4EllipticalCone::CalculateExtent().

00076 {
00077   vertices.clear();
00078 }

G4bool G4ClippablePolygon::Clip ( const G4VoxelLimits voxelLimit  )  [virtual]

Definition at line 84 of file G4ClippablePolygon.cc.

References ClipAlongOneAxis(), G4VoxelLimits::IsLimited(), kXAxis, kYAxis, kZAxis, and vertices.

00085 {
00086   if (voxelLimit.IsLimited()) {
00087     ClipAlongOneAxis( voxelLimit, kXAxis );
00088     ClipAlongOneAxis( voxelLimit, kYAxis );
00089     ClipAlongOneAxis( voxelLimit, kZAxis );
00090   }
00091   
00092   return (vertices.size() > 0);
00093 }

void G4ClippablePolygon::ClipAlongOneAxis ( const G4VoxelLimits voxelLimit,
const EAxis  axis 
) [virtual]

Definition at line 401 of file G4ClippablePolygon.cc.

References G4VoxelLimits::AddLimit(), ClipToSimpleLimits(), G4VoxelLimits::GetMaxExtent(), G4VoxelLimits::GetMinExtent(), G4VoxelLimits::IsLimited(), and vertices.

Referenced by Clip(), and PartialClip().

00403 {    
00404   if (!voxelLimit.IsLimited(axis)) return;
00405   
00406   G4ThreeVectorList tempPolygon;
00407 
00408   //
00409   // Build a "simple" voxelLimit that includes only the min extent
00410   // and apply this to our vertices, producing result in tempPolygon
00411   //
00412   G4VoxelLimits simpleLimit1;
00413   simpleLimit1.AddLimit( axis, voxelLimit.GetMinExtent(axis), kInfinity );
00414   ClipToSimpleLimits( vertices, tempPolygon, simpleLimit1 );
00415 
00416   //
00417   // If nothing is left from the above clip, we might as well return now
00418   // (but with an empty vertices)
00419   //
00420   if (tempPolygon.size() == 0)
00421   {
00422     vertices.clear();
00423     return;
00424   }
00425 
00426   //
00427   // Now do the same, but using a "simple" limit that includes only the max
00428   // extent. Apply this to out tempPolygon, producing result in vertices.
00429   //
00430   G4VoxelLimits simpleLimit2;
00431   simpleLimit2.AddLimit( axis, -kInfinity, voxelLimit.GetMaxExtent(axis) );
00432   ClipToSimpleLimits( tempPolygon, vertices, simpleLimit2 );
00433 
00434   //
00435   // If nothing is left, return now
00436   //
00437   if (vertices.size() == 0) return;
00438 }

void G4ClippablePolygon::ClipToSimpleLimits ( G4ThreeVectorList &  pPolygon,
G4ThreeVectorList &  outputPolygon,
const G4VoxelLimits pVoxelLimit 
) [protected]

Definition at line 445 of file G4ClippablePolygon.cc.

References G4VoxelLimits::ClipToLimits(), and G4VoxelLimits::Inside().

Referenced by ClipAlongOneAxis().

00448 {
00449   G4int i;
00450   G4int noVertices=pPolygon.size();
00451   G4ThreeVector vEnd,vStart;
00452 
00453   outputPolygon.clear();
00454     
00455   for (i=0;i<noVertices;i++)
00456   {
00457     vStart=pPolygon[i];
00458     if (i==noVertices-1)
00459     {
00460       vEnd=pPolygon[0];
00461     }
00462     else
00463     {
00464       vEnd=pPolygon[i+1];
00465     }
00466 
00467     if (pVoxelLimit.Inside(vStart))
00468     {
00469       if (pVoxelLimit.Inside(vEnd))
00470       {
00471         // vStart and vEnd inside -> output end point
00472         //
00473         outputPolygon.push_back(vEnd);
00474       }
00475       else
00476       {
00477         // vStart inside, vEnd outside -> output crossing point
00478         //
00479         pVoxelLimit.ClipToLimits(vStart,vEnd);
00480         outputPolygon.push_back(vEnd);
00481       }
00482     }
00483     else
00484     {
00485       if (pVoxelLimit.Inside(vEnd))
00486       {
00487         // vStart outside, vEnd inside -> output inside section
00488         //
00489         pVoxelLimit.ClipToLimits(vStart,vEnd);
00490         outputPolygon.push_back(vStart);
00491         outputPolygon.push_back(vEnd);
00492       }
00493       else    // Both point outside -> no output
00494       {
00495       }
00496     }
00497   }
00498 }

G4bool G4ClippablePolygon::Empty (  )  const [inline]

Definition at line 56 of file G4ClippablePolygon.icc.

References vertices.

Referenced by BehindOf(), G4SolidExtentList::GetExtent(), and InFrontOf().

00057 {
00058    return vertices.size()==0;
00059 }

G4bool G4ClippablePolygon::GetExtent ( const EAxis  axis,
G4double min,
G4double max 
) const [virtual]

Definition at line 117 of file G4ClippablePolygon.cc.

References vertices.

Referenced by G4SolidExtentList::AddSurface(), and G4SolidExtentList::GetExtent().

00120 {
00121   //
00122   // Okay, how many entries do we have?
00123   //
00124   G4int noLeft = vertices.size();
00125   
00126   //
00127   // Return false if nothing is left
00128   //
00129   if (noLeft == 0) return false;
00130   
00131   //
00132   // Initialize min and max to our first vertex
00133   //
00134   min = max = vertices[0].operator()( axis );
00135   
00136   //
00137   // Compare to the rest
00138   //
00139   G4int i;
00140   for( i=1; i<noLeft; i++ )
00141   {
00142     G4double component = vertices[i].operator()( axis );
00143     if (component < min )
00144       min = component;
00145     else if (component > max )
00146       max = component;
00147   }
00148   
00149   return true;
00150 }

const G4ThreeVector * G4ClippablePolygon::GetMaxPoint ( const EAxis  axis  )  const [virtual]

Definition at line 190 of file G4ClippablePolygon.cc.

References FatalException, G4Exception(), and vertices.

Referenced by BehindOf().

00191 {
00192   G4int noLeft = vertices.size();
00193   if (noLeft==0)
00194     G4Exception("G4ClippablePolygon::GetMaxPoint()",
00195                 "GeomSolids0002", FatalException, "Empty polygon.");
00196   
00197   const G4ThreeVector *answer = &(vertices[0]);
00198   G4double max = answer->operator()(axis);
00199 
00200   G4int i;
00201   for( i=1; i<noLeft; i++ )
00202   {
00203     G4double component = vertices[i].operator()( axis );
00204     if (component > max)
00205     {
00206       answer = &(vertices[i]);
00207       max = component;
00208     }
00209   }
00210   
00211   return answer;
00212 }

const G4ThreeVector * G4ClippablePolygon::GetMinPoint ( const EAxis  axis  )  const [virtual]

Definition at line 159 of file G4ClippablePolygon.cc.

References FatalException, G4Exception(), and vertices.

Referenced by InFrontOf().

00160 {
00161   G4int noLeft = vertices.size();
00162   if (noLeft==0)
00163     G4Exception("G4ClippablePolygon::GetMinPoint()",
00164                 "GeomSolids0002", FatalException, "Empty polygon.");
00165   
00166   const G4ThreeVector *answer = &(vertices[0]);
00167   G4double min = answer->operator()(axis);
00168 
00169   G4int i;
00170   for( i=1; i<noLeft; i++ )
00171   {
00172     G4double component = vertices[i].operator()( axis );
00173     if (component < min)
00174     {
00175       answer = &(vertices[i]);
00176       min = component;
00177     }
00178   }
00179   
00180   return answer;
00181 }

const G4ThreeVector G4ClippablePolygon::GetNormal (  )  const [inline]

Definition at line 44 of file G4ClippablePolygon.icc.

References normal.

Referenced by BehindOf(), G4SolidExtentList::GetExtent(), and InFrontOf().

00045 {
00046    return normal;
00047 }

G4int G4ClippablePolygon::GetNumVertices (  )  const [inline]

Definition at line 50 of file G4ClippablePolygon.icc.

References vertices.

00051 {
00052    return vertices.size();
00053 }

G4bool G4ClippablePolygon::GetPlanerExtent ( const G4ThreeVector pointOnPlane,
const G4ThreeVector planeNormal,
G4double min,
G4double max 
) const [virtual]

Definition at line 361 of file G4ClippablePolygon.cc.

References vertices.

Referenced by BehindOf(), and InFrontOf().

00365 {
00366   //
00367   // Okay, how many entries do we have?
00368   //
00369   G4int noLeft = vertices.size();
00370   
00371   //
00372   // Return false if nothing is left
00373   //
00374   if (noLeft == 0) return false;
00375   
00376   //
00377   // Initialize min and max to our first vertex
00378   //
00379   min = max = planeNormal.dot(vertices[0]-pointOnPlane);
00380   
00381   //
00382   // Compare to the rest
00383   //
00384   G4int i;
00385   for( i=1; i<noLeft; i++ )
00386   {
00387     G4double component = planeNormal.dot(vertices[i] - pointOnPlane);
00388     if (component < min )
00389       min = component;
00390     else if (component > max )
00391       max = component;
00392   }
00393   
00394   return true;
00395 }

G4bool G4ClippablePolygon::InFrontOf ( const G4ClippablePolygon other,
EAxis  axis 
) const [virtual]

Definition at line 231 of file G4ClippablePolygon.cc.

References Empty(), GetMinPoint(), GetNormal(), GetPlanerExtent(), kCarTolerance, normal, and vertices.

Referenced by G4SolidExtentList::AddSurface().

00233 {
00234   //
00235   // If things are empty, do something semi-sensible
00236   //
00237   G4int noLeft = vertices.size();
00238   if (noLeft==0) return false;
00239   
00240   if (other.Empty()) return true;
00241 
00242   //
00243   // Get minimum of other polygon
00244   //
00245   const G4ThreeVector *minPointOther = other.GetMinPoint( axis );
00246   const G4double minOther = minPointOther->operator()(axis);
00247   
00248   //
00249   // Get minimum of this polygon
00250   //
00251   const G4ThreeVector *minPoint = GetMinPoint( axis );
00252   const G4double min = minPoint->operator()(axis);
00253   
00254   //
00255   // Easy decision
00256   //
00257   if (min < minOther-kCarTolerance) return true;    // Clear winner
00258   
00259   if (minOther < min-kCarTolerance) return false;    // Clear loser
00260   
00261   //
00262   // We have a tie (this will not be all that rare since our
00263   // polygons are connected)
00264   //
00265   // Check to see if there is a vertex in the other polygon
00266   // that is behind this one (or vice versa)
00267   //
00268   G4bool answer;
00269   G4ThreeVector normalOther = other.GetNormal();
00270   
00271   if (std::fabs(normalOther(axis)) > std::fabs(normal(axis)))
00272   {
00273     G4double minP, maxP;
00274     GetPlanerExtent( *minPointOther, normalOther, minP, maxP );
00275     
00276     answer = (normalOther(axis) > 0) ? (minP < -kCarTolerance)
00277                                      : (maxP > +kCarTolerance);
00278   }
00279   else
00280   {
00281     G4double minP, maxP;
00282     other.GetPlanerExtent( *minPoint, normal, minP, maxP );
00283     
00284     answer = (normal(axis) > 0) ? (maxP > +kCarTolerance)
00285                                 : (minP < -kCarTolerance);
00286   }
00287   return answer;
00288 }

G4bool G4ClippablePolygon::PartialClip ( const G4VoxelLimits voxelLimit,
const EAxis  IgnoreMe 
) [virtual]

Definition at line 101 of file G4ClippablePolygon.cc.

References ClipAlongOneAxis(), G4VoxelLimits::IsLimited(), kXAxis, kYAxis, kZAxis, and vertices.

Referenced by G4Hype::AddPolyToExtent(), G4PolyPhiFace::CalculateExtent(), G4PolyhedraSide::CalculateExtent(), G4PolyconeSide::CalculateExtent(), G4Hype::CalculateExtent(), G4EllipticalTube::CalculateExtent(), and G4EllipticalCone::CalculateExtent().

00103 {
00104   if (voxelLimit.IsLimited()) {
00105     if (IgnoreMe != kXAxis) ClipAlongOneAxis( voxelLimit, kXAxis );
00106     if (IgnoreMe != kYAxis) ClipAlongOneAxis( voxelLimit, kYAxis );
00107     if (IgnoreMe != kZAxis) ClipAlongOneAxis( voxelLimit, kZAxis );
00108   }
00109   
00110   return (vertices.size() > 0);
00111 }

void G4ClippablePolygon::SetNormal ( const G4ThreeVector newNormal  )  [inline]

Definition at line 38 of file G4ClippablePolygon.icc.

References normal.

Referenced by G4Hype::AddPolyToExtent(), G4PolyPhiFace::CalculateExtent(), G4PolyhedraSide::CalculateExtent(), G4PolyconeSide::CalculateExtent(), G4Hype::CalculateExtent(), G4EllipticalTube::CalculateExtent(), and G4EllipticalCone::CalculateExtent().

00039 {
00040    normal = newNormal;
00041 }


Field Documentation

G4double G4ClippablePolygon::kCarTolerance [protected]

Definition at line 123 of file G4ClippablePolygon.hh.

Referenced by BehindOf(), G4ClippablePolygon(), and InFrontOf().

G4ThreeVector G4ClippablePolygon::normal [protected]

Definition at line 122 of file G4ClippablePolygon.hh.

Referenced by BehindOf(), GetNormal(), InFrontOf(), and SetNormal().

G4ThreeVectorList G4ClippablePolygon::vertices [protected]

Definition at line 121 of file G4ClippablePolygon.hh.

Referenced by AddVertexInOrder(), BehindOf(), ClearAllVertices(), Clip(), ClipAlongOneAxis(), Empty(), GetExtent(), GetMaxPoint(), GetMinPoint(), GetNumVertices(), GetPlanerExtent(), InFrontOf(), and PartialClip().


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:51:39 2013 for Geant4 by  doxygen 1.4.7