View Javadoc

1   package org.lcsim.detector.solids;
2   
3   import static java.lang.Math.PI;
4   import static java.lang.Math.cos;
5   
6   import hep.physics.vec.Hep3Vector;
7   import java.text.DecimalFormat;
8   import java.text.NumberFormat;
9   
10  /**
11   * This class encapsulates the behavior of a right
12   * regular polyhedron whose principal axis is aligned
13   * with the z axis and whose parallel ends are made of
14   * regular polygons. The polygons have a flat base at
15   * the bottom. The polyhedron is allowed to be hollow
16   * by specifying an inner radius for an inner polyhedron
17   * coaxial along z. For now it must have the same number
18   * of sides with the same orientation.
19   *
20   * @author Norman A. Graf
21   *
22   * @version $Id: RightRegularPolyhedron.java,v 1.4 2010/04/22 21:18:39 ngraf Exp $
23   */
24  public class RightRegularPolyhedron extends AbstractSolid
25  {
26      //input
27  
28      private int _nsides;
29      private double _rmin;
30      private double _rmax;
31      private double _zmin;
32      private double _zmax;
33      //derived quantities
34      private RegularPolygon _innerPolygon = null;
35      private RegularPolygon _outerPolygon = null;
36      private boolean _isHollow;
37  
38      /**
39       * Fully qualified constructor for a hollow right regular polyhedron.
40       *
41       * @param name   the name of this solid
42       * @param nsides the number of sides of the regular polygon forming the ends.
43       * @param rmin   the radius of the inner polygon's inscribed circle
44       * @param rmax   the radius of the outer polygon's circumscribed circle
45       * @param zmin   the minimum z extent
46       * @param zmax   the maximum z extent
47       */
48      public RightRegularPolyhedron(String name, int nsides, double rmin, double rmax, double zmin, double zmax)
49      {
50          super(name);
51          if (nsides < 3)
52              throw new RuntimeException("Cannot make a polyhedron with less than three sides!");
53          _nsides = nsides;
54          if (rmin >= rmax)
55              throw new RuntimeException("Inner radius must be inside outer radius!");
56          _rmin = rmin;
57          _rmax = rmax;
58          if (zmin >= zmax)
59              throw new RuntimeException("Minimum z must be less than maximum z!");
60          _zmin = zmin;
61          _zmax = zmax;
62  
63          // need to calculate the circumscribed circle radius for the inner polygon
64          double dPhi = 2. * PI / ((double) _nsides);
65          double r = _rmin / cos(dPhi / 2.);
66          _innerPolygon = new RegularPolygon(_nsides, r);
67          _outerPolygon = new RegularPolygon(_nsides, _rmax);
68          _isHollow = true;
69      }
70  
71      /**
72       * Fully qualified constructor for a solid right regular polyhedron.
73       *
74       * @param name   the name of this solid
75       * @param nsides the number of sides of the regular polygon forming the ends.
76       * @param radius the radius of the outer polygon's circumscribed circle
77       * @param zmin   the minimum z extent
78       * @param zmax   the maximum z extent
79       */
80      public RightRegularPolyhedron(String name, int nsides, double radius, double zmin, double zmax)
81      {
82          super(name);
83          if (nsides < 3)
84              throw new RuntimeException("Cannot make a polyhedron with less than three sides!");
85          _nsides = nsides;
86          _rmax = radius;
87          if (zmin >= zmax)
88              throw new RuntimeException("Minimum z must be less than maximum z!");
89          _zmin = zmin;
90          _zmax = zmax;
91          _outerPolygon = new RegularPolygon(_nsides, _rmax);
92          _isHollow = false;
93      }
94  
95      public double getCubicVolume()
96      {
97          return volume();
98      }
99  
100     /**
101      * Determines whether a point lies within or outside of this solid.
102      * 
103      * @param pos the point to check
104      * @return an enumeration of INSIDE or OUTSIDE ( SURFACE is reported as INSIDE)
105      */
106     public Inside inside(Hep3Vector pos)
107     {
108         //fail fast
109         double z = pos.z();
110         if (z < _zmin || z > _zmax)
111         {
112             return Inside.OUTSIDE;
113         }
114 
115         double x = pos.x();
116         double y = pos.y();
117         double r2 = x * x + y * y;
118         if (r2 > _rmax * _rmax)
119             return Inside.OUTSIDE;
120         if (r2 < _rmin * _rmin)
121             return Inside.OUTSIDE;
122 
123         //need to be inside the outer polygon...
124         Inside outer = _outerPolygon.inside(pos);
125         if (outer.compareTo(Inside.OUTSIDE) == 0)
126             return Inside.OUTSIDE;
127 
128         // and not inside the inner polygon
129         if (_isHollow)
130         {
131             Inside inner = _innerPolygon.inside(pos);
132             if (inner.compareTo(Inside.INSIDE) == 0)
133                 return Inside.OUTSIDE;
134         }
135         return Inside.INSIDE;
136     }
137 
138     /**
139      * Returns the area of the polygonal face
140      * @return the area of polygon forming the face of this solid
141      */
142     public double polygonalArea()
143     {
144         double area = _outerPolygon.area();
145         if (_isHollow)
146             area -= _innerPolygon.area();
147         return area;
148     }
149 
150     /**
151      * Is this a hollow polygon?
152      * @return true if this polygon is hollow
153      */
154     public boolean isHollow()
155     {
156         return _isHollow;
157     }
158 
159     /**
160      * Returns the volume of this solid
161      * @return the volume of this solid
162      */
163     public double volume()
164     {
165         return polygonalArea() * (_zmax - _zmin);
166     }
167 
168     @Override
169     public String toString()
170     {
171         NumberFormat formatter = new DecimalFormat("#0.00");
172 
173         StringBuffer sb = new StringBuffer("RightRegularAnnularPolyhedron\n");
174         sb.append(" with " + _nsides + " sides from r= " + _rmin + " to " + _rmax + ": \n");
175         sb.append(_outerPolygon.toString() + "\n");
176         if (_isHollow)
177             sb.append(_innerPolygon.toString() + "\n");
178         sb.append("volume= " + volume() + "\n");
179         return sb.toString();
180     }
181 
182     /**
183      *
184      * @return the number of equal sides of the polygonal faces
185      */
186     public int getNumberOfSides()
187     {
188         return _nsides;
189     }
190 
191     /**
192      *
193      * @return the minimum z extent of this solid
194      */
195     public double getZMin()
196     {
197         return _zmin;
198     }
199 
200     /**
201      *
202      * @return the maximal z extent of this solid
203      */
204     public double getZMax()
205     {
206         return _zmax;
207     }
208 
209     /**
210      * The radius of the inscribe polygon if hollow.
211      * Returns zero if the polygon is not hollow
212      * @return the radius of the inscribed circle
213      */
214     public double getRMin()
215     {
216         return _rmin;
217     }
218 
219     /**
220      *
221      * @return the radius of the circumscribed circle
222      */
223     public double getRMax()
224     {
225         return _rmax;
226     }
227 
228     /**
229      * The polygon representing the 2D end faces of the
230      * inner boundary of this solid. Note that z=0.
231      * @return  null if the solid is not hollow.
232      */
233     public RegularPolygon getInnerPolygon()
234     {
235         return _innerPolygon;
236     }
237 
238     /**
239      * The polygon representing the 2D end faces. Note that z=0.
240      * @return The polygon representing the end faces
241      *
242      */
243     public RegularPolygon getOuterPolygon()
244     {
245         return _outerPolygon;
246     }
247 
248     private double t(Hep3Vector a, Hep3Vector b, Hep3Vector c)
249     {
250         double t = (a.y() - b.y()) * (c.x() - b.x()) - (a.x() - b.x()) * (c.y() - b.y());
251         return t;
252     }
253 }