89 constructorParams.start_angle = start_angle;
90 constructorParams.opening_angle = opening_angle;
91 constructorParams.sides = sides;
92 constructorParams.num_z_planes = num_z_planes;
93 constructorParams.z_start = z_start;
94 constructorParams.z_values = 0;
95 constructorParams.RMIN = 0;
96 constructorParams.RMAX = 0;
98 if( num_z_planes > 0 )
100 constructorParams.z_values =
new G4double[num_z_planes];
101 constructorParams.RMIN =
new G4double[num_z_planes];
102 constructorParams.RMAX =
new G4double[num_z_planes];
103 for(
G4int idx = 0; idx < num_z_planes; ++idx )
105 constructorParams.z_values[idx] = z_values[idx];
106 constructorParams.RMIN[idx] = RMIN[idx];
107 constructorParams.RMAX[idx] = RMAX[idx];
117 if( z_values[0] != z_start )
119 std::ostringstream message;
120 message <<
"Construction Error. z_values[0] must be equal to z_start!"
122 <<
" Wrong solid parameters: "
123 <<
" z_values[0]= " << z_values[0] <<
" is not equal to "
124 <<
" z_start= " << z_start <<
".";
125 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
127 if( num_z_planes <= 0 ) { constructorParams.z_values =
new G4double[1]; }
128 constructorParams.z_values[0]= z_start;
132 InitializePolyhedra();
138 constructorParams.start_angle = 0.;
139 constructorParams.opening_angle = 0.;
140 constructorParams.sides = 0;
141 constructorParams.num_z_planes = 0;
142 constructorParams.z_start = 0.;
143 constructorParams.z_values = 0;
144 constructorParams.RMIN = 0;
145 constructorParams.RMAX = 0;
150 if( constructorParams.num_z_planes > 0 )
152 delete [] constructorParams.z_values;
153 delete [] constructorParams.RMIN;
154 delete [] constructorParams.RMAX;
161 constructorParams.start_angle = rhs.constructorParams.start_angle;
162 constructorParams.opening_angle = rhs.constructorParams.opening_angle;
163 constructorParams.sides = rhs.constructorParams.sides;
164 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes;
165 constructorParams.z_start = rhs.constructorParams.z_start;
166 constructorParams.z_values = 0;
167 constructorParams.RMIN = 0;
168 constructorParams.RMAX = 0;
169 G4int num_z_planes = constructorParams.num_z_planes;
170 if( num_z_planes > 0 )
172 constructorParams.z_values =
new G4double[num_z_planes];
173 constructorParams.RMIN =
new G4double[num_z_planes];
174 constructorParams.RMAX =
new G4double[num_z_planes];
175 for(
G4int idx = 0; idx < num_z_planes; ++idx )
177 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx];
178 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx];
179 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx];
183 InitializePolyhedra();
191 if (
this == &rhs) {
return *
this; }
199 constructorParams.start_angle = rhs.constructorParams.start_angle;
200 constructorParams.opening_angle = rhs.constructorParams.opening_angle;
201 constructorParams.sides = rhs.constructorParams.sides;
202 constructorParams.num_z_planes = rhs.constructorParams.num_z_planes;
203 constructorParams.z_start = rhs.constructorParams.z_start;
204 G4int num_z_planes = constructorParams.num_z_planes;
205 if( num_z_planes > 0 )
207 delete [] constructorParams.z_values;
208 delete [] constructorParams.RMIN;
209 delete [] constructorParams.RMAX;
210 constructorParams.z_values =
new G4double[num_z_planes];
211 constructorParams.RMIN =
new G4double[num_z_planes];
212 constructorParams.RMAX =
new G4double[num_z_planes];
213 for(
G4int idx = 0; idx < num_z_planes; ++idx )
215 constructorParams.z_values[idx] = rhs.constructorParams.z_values[idx];
216 constructorParams.RMIN[idx] = rhs.constructorParams.RMIN[idx];
217 constructorParams.RMAX[idx] = rhs.constructorParams.RMAX[idx];
221 InitializePolyhedra();
226void G4BREPSolidPolyhedra::InitializePolyhedra()
228 G4double start_angle = constructorParams.start_angle;
229 G4double opening_angle = constructorParams.opening_angle;
230 G4int sides = constructorParams.sides;
231 G4int num_z_planes = constructorParams.num_z_planes;
232 G4double z_start = constructorParams.z_start;
233 G4double* z_values = constructorParams.z_values;
234 G4double* RMIN = constructorParams.RMIN;
235 G4double* RMAX = constructorParams.RMAX;
236 G4int sections = num_z_planes - 1;
238 if( opening_angle >= 2*pi-perMillion )
257 G4double PartAngle = (opening_angle)/sides;
267 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
269 "The solid must have at least 3 sides!" );
274 if( num_z_planes < 2 )
276 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
278 "The solid must have at least 2 z-sections!" );
284 if( z_values[0] == z_values[1]
285 || z_values[sections-1] == z_values[sections] )
287 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
289 "The solid must have the first 2 and the last 2 z-values different!" );
295 if( z_values[0] < z_values[1] )
309 for(
G4int idx = 0; idx < sections; idx++ )
311 if( ( z_values[idx] > z_values[idx+1] && increasing ) ||
312 ( z_values[idx] < z_values[idx+1] && !increasing ) )
316 std::ostringstream message;
317 message <<
"Unordered, non-increasing or non-decreasing sequence."
319 <<
" Unordered z_values sequence detected !" <<
G4endl
320 <<
" Check z_values with indexes: "
321 << idx <<
" " << (idx+1) <<
".";
322 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
328#ifdef G4_EXPERIMENTAL_CODE
359 for(
G4int idx = 1; idx < sections+1; idx++ )
361 if( z_values[idx-1] > z_values[idx] )
363 G4double toothdist = std::fabs( z_values[idx-1] - z_values[idx] );
364 G4double aftertoothdist = std::fabs( z_values[idx+1] - z_values[idx] );
365 if( toothdist > aftertoothdist )
369 if( RMAX[idx-1] < RMAX[idx+1] || RMIN[idx-1] > RMIN[idx+1] )
373 std::ostringstream message;
374 message <<
"Unordered sequence of z_values detected." <<
G4endl
375 <<
" Conflicting RMAX or RMIN values!" <<
G4endl
376 <<
" Check z_values with indexes: "
377 << (idx-1) <<
" " << idx <<
" " << (idx+1) <<
".";
378 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
387 for(
G4int a=0;a<sections;a++)
389 Length = z_values[a+1] - z_values[a];
399 for(
G4int b = 0; b < sides; b++ )
409 if( RMIN[a+1] != 0.0 )
413 MaxSurfaceVec[Count] =
414 CreateTrapezoidalSurface( RMIN[a], RMIN[a+1],
416 TmpAxis, PartAngle, EInverse );
423 MaxSurfaceVec[Count] =
424 CreateTriangularSurface( RMIN[a], RMIN[a+1],
426 TmpAxis, PartAngle, EInverse );
429 else if( RMIN[a+1] != 0.0 )
434 MaxSurfaceVec[Count] =
435 CreateTriangularSurface( RMIN[a], RMIN[a+1], LocalOrigin, Length,
436 TmpAxis, PartAngle, EInverse );
443 MaxSurfaceVec[Count] = 0;
451 if( MaxSurfaceVec[Count] != 0 )
466 if( RMAX[a+1] != 0.0 )
470 MaxSurfaceVec[Count] =
471 CreateTrapezoidalSurface( RMAX[a], RMAX[a+1],
473 TmpAxis, PartAngle, ENormal );
480 MaxSurfaceVec[Count] =
481 CreateTriangularSurface( RMAX[a], RMAX[a+1],
483 TmpAxis, PartAngle, ENormal );
486 else if( RMAX[a+1] != 0.0 )
491 MaxSurfaceVec[Count] =
492 CreateTriangularSurface( RMAX[a], RMAX[a+1], LocalOrigin, Length,
493 TmpAxis, PartAngle, ENormal );
500 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
502 "Two consecutive RMAX values cannot be zero!" );
514 if( RMAX[a] != RMAX[a+1] && RMIN[a] != RMIN[a+1] )
551 if( RMIN[a] > RMAX[a+1] || RMAX[a] < RMIN[a+1] )
553 std::ostringstream message;
554 message <<
"The values of RMIN[" << a <<
"] & RMAX[" << a+1
555 <<
"] or RMAX[" << a <<
"] & RMIN[" << a+1 <<
"]" <<
G4endl
556 <<
"generate an invalid configuration of solid: "
558 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
565 if( RMAX[a] > RMAX[a+1] )
569 if( RMIN[a] < RMIN[a+1] )
572 OuterSurfSense = EInverse;
573 InnerSurfSense = EInverse;
575 else if( RMAX[a+1] != RMIN[a])
578 OuterSurfSense = EInverse;
579 InnerSurfSense = ENormal;
584 OuterSurfSense = EInverse;
585 InnerSurfSense = ENormal;
591 if( RMIN[a] > RMIN[a+1] )
594 OuterSurfSense = ENormal;
595 InnerSurfSense = ENormal;
597 else if( RMIN[a+1] != RMAX[a] )
600 OuterSurfSense = ENormal;
601 InnerSurfSense = EInverse;
606 OuterSurfSense = ENormal;
607 InnerSurfSense = EInverse;
616 MaxSurfaceVec[Count] =
617 ComputePlanarSurface( RMAX[a], RMAX[a+1], LocalOrigin, TmpAxis,
618 sides, PartAngle, OuterSurfSense );
619 if( MaxSurfaceVec[Count] == 0 )
632 MaxSurfaceVec[Count] =
633 ComputePlanarSurface( RMIN[a], RMIN[a+1], LocalOrigin, TmpAxis,
634 sides, PartAngle, InnerSurfSense );
635 if( MaxSurfaceVec[Count] == 0 )
670 if( RMAX[a] != RMAX[a+1] )
680 SurfSense = EInverse;
689 else if(RMIN[a] != RMIN[a+1])
705 SurfSense = EInverse;
710 std::ostringstream message;
711 message <<
"Error in construction." <<
G4endl
712 <<
" Exactly the same z, rmin and rmax given for"
714 <<
" consecutive indices, " << a <<
" and " << a+1;
715 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
722 MaxSurfaceVec[Count] =
723 ComputePlanarSurface( R1, R2, LocalOrigin, TmpAxis,
724 sides, PartAngle, SurfSense );
725 if( MaxSurfaceVec[Count] == 0 )
740 LocalOrigin = LocalOrigin + (Length*Axis);
744 if(opening_angle >= 2*pi-perMillion)
751 MaxSurfaceVec[Count] =
752 ComputePlanarSurface( RMIN[0], RMAX[0], Origin, TmpAxis,
753 sides, PartAngle, ENormal );
755 if( MaxSurfaceVec[Count] == 0 )
768 MaxSurfaceVec[Count] =
769 ComputePlanarSurface( RMIN[sections], RMAX[sections],
770 LocalOrigin, TmpAxis,
771 sides, PartAngle, EInverse );
773 if( MaxSurfaceVec[Count] == 0 )
794 LocalOrigin = Origin;
795 G4int points = sections*2+2;
796 G4int PointCount = 0;
801 for(
G4int d=0;d<sections+1;d++)
803 GapPointList[PointCount] = LocalOrigin + (RMAX[d]*TmpAxis);
804 GapPointList[points-1-PointCount] = LocalOrigin + (RMIN[d]*TmpAxis);
806 GapPointList2[PointCount] = LocalOrigin + (RMAX[d]*TmpAxis2);
807 GapPointList2[points-1-PointCount] = LocalOrigin + (RMIN[d]*TmpAxis2);
811 Length = z_values[d+1] - z_values[d];
812 LocalOrigin = LocalOrigin+(Length*Axis);
817 MaxSurfaceVec[Count++] =
new G4FPlane( &GapPointList, 0, ENormal );
818 MaxSurfaceVec[Count++] =
new G4FPlane( &GapPointList2, 0, EInverse );
822 TmpAxis.
rotateZ(opening_angle);
829 for(
G4int c=0;c<sides+1;c++)
832 EndPointList[c] = Origin + (RMAX[0] * TmpAxis);
833 EndPointList[(sides+1)*2-1-c] = Origin + (RMIN[0] * TmpAxis);
834 EndPointList2[c] = LocalOrigin + (RMAX[sections] * TmpAxis);
835 EndPointList2[(sides+1)*2-1-c] = LocalOrigin + (RMIN[sections] * TmpAxis);
844 if(RMAX[0]-RMIN[0] >= perMillion)
846 MaxSurfaceVec[Count] =
new G4FPlane( &EndPointList, 0, EInverse );
850 MaxSurfaceVec[Count] = 0;
856 if(RMAX[sections]-RMIN[sections] >= perMillion)
858 MaxSurfaceVec[Count] =
new G4FPlane( &EndPointList2, 0, ENormal );
862 MaxSurfaceVec[Count] = 0;
872 for(
G4int srf = 0; srf < MaxNbOfSurfaces; srf++ )
874 if( MaxSurfaceVec[srf] != 0 )
890 std::ostringstream message;
891 message <<
"Bad number of surfaces!" <<
G4endl
894 <<
" Count : " << Count;
895 G4Exception(
"G4BREPSolidPolyhedra::G4BREPSolidPolyhedra()",
901 delete [] MaxSurfaceVec;
939 G4Ray r(Pttmp, Vtmp);
957 G4int hits=0, samehit=0;
982 for(
G4int i=0; i<a; i++)
1021 G4int normPlane = 0;
1025 if( minDist > dist )
1030 if( dist < sqrHalfTolerance)
1053 return hitNorm.
unit();
1087 if( std::fabs(Dist) > std::fabs(dists[a]) )
1093 if(Dist == kInfinity)
1101 return std::fabs(Dist);
1125 G4Ray r(Pttmp, Vtmp);
1149 if( surfDistance > sqrHalfTolerance )
1160 if( (Norm * Vtmp) < 0 )
1221 G4Ray r(Pttmp, Vtmp);
1240 if( intersects != 0 )
1248 if( surfDistance > sqrHalfTolerance )
1318 if( std::fabs(Dist) > std::fabs(dists[a]) )
1327 if(Dist == kInfinity)
1336 return std::fabs(Dist);
1350 <<
"\n start_angle: " << constructorParams.start_angle
1351 <<
"\n opening_angle: " << constructorParams.opening_angle
1352 <<
"\n sides: " << constructorParams.sides
1353 <<
"\n num_z_planes: " << constructorParams.num_z_planes
1354 <<
"\n z_start: " << constructorParams.z_start
1357 for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
1359 os << constructorParams.z_values[idx] <<
" ";
1362 for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
1364 os << constructorParams.RMIN[idx] <<
" ";
1367 for( idx = 0; idx < constructorParams.num_z_planes; idx++ )
1369 os << constructorParams.RMAX[idx] <<
" ";
1371 os <<
"\n-----------------------------------------------------------\n";
1377G4BREPSolidPolyhedra::CreateTrapezoidalSurface(
G4double r1,
1391 PointList[0] = origin + ( r1 * xAxis);
1392 PointList[3] = origin + ( distance * zAxis) + (r2 * xAxis);
1396 PointList[2] = origin + ( distance * zAxis) + (r2 * xAxis);
1397 PointList[1] = origin + ( r1 * xAxis);
1401 trapsrf =
new G4FPlane( &PointList, 0, sense );
1407G4BREPSolidPolyhedra::CreateTriangularSurface(
G4double r1,
1421 PointList[0] = origin + ( r1 * xAxis);
1422 PointList[2] = origin + ( distance * zAxis) + (r2 * xAxis);
1428 PointList[1] = origin + ( distance * zAxis) + (r2 * xAxis);
1432 PointList[1] = origin + ( r1 * xAxis);
1437 trapsrf =
new G4FPlane( &PointList, 0, sense );
1443G4BREPSolidPolyhedra::ComputePlanarSurface(
G4double r1,
1480 for(
G4int pidx = 0; pidx < sides; pidx++ )
1484 OuterPointList[pidx] = origin + ( rOut * xAxis);
1487 InnerPointList[pidx] = origin + ( rIn * xAxis);
1491 if( rIn != 0.0 && rOut != 0.0 )
1495 planarSrf =
new G4FPlane( &OuterPointList, &InnerPointList, sense );
1497 else if( rOut != 0.0 )
1502 planarSrf =
new G4FPlane( &OuterPointList, 0, sense );
1520 constructorParams.opening_angle,
1521 constructorParams.sides,
1522 constructorParams.num_z_planes,
1523 constructorParams.z_values,
1524 constructorParams.RMIN,
1525 constructorParams.RMAX);
std::vector< G4Point3D > G4Point3DVector
G4ThreeVector SurfaceNormal(const G4ThreeVector &) const
G4Polyhedron * CreatePolyhedron() const
std::ostream & StreamInfo(std::ostream &os) const
G4BREPSolidPolyhedra & operator=(const G4BREPSolidPolyhedra &rhs)
EInside Inside(register const G4ThreeVector &Pt) const
G4BREPSolidPolyhedra(const G4String &name, G4double phi1, G4double dphi, G4int sides, G4int num_z_planes, G4double z_start, G4double z_values[], G4double RMIN[], G4double RMAX[])
G4double DistanceToIn(const G4ThreeVector &) const
G4double DistanceToOut(register const G4ThreeVector &Pt, register const G4ThreeVector &V, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
G4BREPSolid & operator=(const G4BREPSolid &rhs)
G4int StartInside() const
G4int Intersect(register const G4Ray &) const
virtual std::ostream & StreamInfo(std::ostream &os) const
void CheckSurfaceNormals()
virtual void CalcBBoxes()
const G4BoundingBox3D * GetBBox() const
static G4double ShortestDistance
void TestSurfaceBBoxes(register const G4Ray &) const
const G4String & GetName() const
G4Point3D GetSrfPoint() const
G4Vector3D SurfaceNormal(const G4Point3D &Pt) const
virtual G4int Intersect(const G4Ray &)
virtual G4Vector3D SurfaceNormal(const G4Point3D &Pt) const =0
virtual G4double HowNear(const G4Vector3D &x) const
G4double GetDistance() const
BasicVector3D< T > & rotateZ(T a)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)