Files
geant4/source/geometry/solids/usolids/include/UReduciblePolygon.hh
T
2016-06-10 11:51:14 +02:00

191 lines
4.4 KiB
C++

//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UReduciblePolygon
//
// Class description:
//
// Utility class used to specify, test, reduce, and/or otherwise
// manipulate a 2D polygon.
//
// For this class, a polygon consists of n > 2 points in 2D
// space (a,b). The polygon is always closed by connecting the
// last point to the first. A UReduciblePolygon is guaranteed
// to fulfill this definition in all instances.
//
// Illegal manipulations (such that a valid polygon would be
// produced) result in an error return if possible and
// otherwise a // UException.
//
// The Set of manipulations is limited currently to what
// is needed for UPolycone and UPolyhedra.
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UReduciblePolygon_hh
#define UReduciblePolygon_hh
#include "UTypes.hh"
class UReduciblePolygon
{
friend class UReduciblePolygonIterator;
public:
//
// Creator: via simple a/b arrays
//
UReduciblePolygon(const double a[], const double b[], int n);
//
// Creator: a special version for UPolygon and UPolycone
// that takes two a points at planes of b
// (where a==r and b==z for the GEANT3 classic PCON and PGON)
//
UReduciblePolygon(const double rmin[], const double rmax[],
const double z[], int n);
virtual ~UReduciblePolygon();
//
// Queries
//
inline int NumVertices() const
{
return numVertices;
}
inline double Amin() const
{
return aMin;
}
inline double Amax() const
{
return aMax;
}
inline double Bmin() const
{
return bMin;
}
inline double Bmax() const
{
return bMax;
}
void CopyVertices(double a[], double b[]) const;
//
// Manipulations
//
void ScaleA(double scale);
void ScaleB(double scale);
bool RemoveDuplicateVertices(double tolerance);
bool RemoveRedundantVertices(double tolerance);
void ReverseOrder();
void StartWithZMin();
//
// Tests
//
double Area();
bool CrossesItself(double tolerance);
bool BisectedBy(double a1, double b1,
double a2, double b2, double tolerance);
void Print(); // Debugging only
public: // without description
protected:
void Create(const double a[], const double b[], int n);
void CalculateMaxMin();
//
// Below are member values that are *always* kept up to date (please!)
//
double aMin, aMax, bMin, bMax;
int numVertices;
//
// A subclass which holds the vertices in a single-linked list
//
// Yeah, call me an old-fashioned c hacker, but I cannot make
// myself use the rogue tools for this trivial list.
//
struct ABVertex; // Secret recipe for allowing
friend struct ABVertex; // protected nested structures
struct ABVertex
{
ABVertex() : a(0.), b(0.), next(0) {}
double a, b;
ABVertex* next;
};
ABVertex* vertexHead;
private:
UReduciblePolygon(const UReduciblePolygon&);
UReduciblePolygon& operator=(const UReduciblePolygon&);
// Private copy constructor and assignment operator.
};
//
// A companion class for iterating over the vertices of our polygon.
// It is simple enough that all routines are declared inline here.
//
class UReduciblePolygonIterator
{
public:
UReduciblePolygonIterator(const UReduciblePolygon* theSubject)
{
subject = theSubject;
current = 0;
}
void Begin()
{
current = subject->vertexHead;
}
bool Next()
{
if (current) current = current->next;
return Valid();
}
bool Valid() const
{
return current != 0;
}
double GetA() const
{
return current->a;
}
double GetB() const
{
return current->b;
}
protected:
const UReduciblePolygon* subject; // Who are we iterating over
UReduciblePolygon::ABVertex* current; // Current vertex
};
#endif