VGM Version 5.3
Loading...
Searching...
No Matches
Arb8.cxx
Go to the documentation of this file.
1// $Id$
2
3// -----------------------------------------------------------------------
4// The Geant4GM package of the Virtual Geometry Model
5// Copyright (C) 2007, Ivana Hrivnacova
6// All rights reserved.
7//
8// For the licensing terms see vgm/LICENSE.
9// Contact: ivana@ipno.in2p3.fr
10// -----------------------------------------------------------------------
11
12//
13// Class Arb8
14// --------------------
15// VGM implementation for Geant4 Arb8 solid.
16//
17// Author: Ivana Hrivnacova; IPN Orsay
18
21
22#include "ClhepVGM/Units.h"
23
24#include "G4QuadrangularFacet.hh"
25#include "G4TessellatedSolid.hh"
26#include "G4TriangularFacet.hh"
27
28#include <iostream>
29
30const int Geant4GM::Arb8::fgkNofVertices = 8;
31const double Geant4GM::Arb8::fgkTolerance = 1E-3;
32
33//_____________________________________________________________________________
34bool Geant4GM::Arb8::IsTwisted(std::vector<VGM::TwoVector> vertices)
35{
39
40 bool twisted = false;
41 double dx1, dy1, dx2, dy2;
42 int nv = fgkNofVertices / 2;
43 for (int i = 0; i < 4; i++) {
44
45 dx1 = vertices[(i + 1) % nv].first - vertices[i].first;
46 dy1 = vertices[(i + 1) % nv].second - vertices[i].second;
47 if (dx1 == 0 && dy1 == 0) continue;
48
49 dx2 = vertices[nv + (i + 1) % nv].first - vertices[nv + i].first;
50 dy2 = vertices[nv + (i + 1) % nv].second - vertices[nv + i].second;
51 if (dx2 == 0 && dy2 == 0) continue;
52
53 if (fabs(dy1 * dx2 - dx1 * dy2) < fgkTolerance) continue;
54
55 twisted = true;
56 }
57 return twisted;
58}
59
60//_____________________________________________________________________________
62 const std::string& name, double hz, std::vector<VGM::TwoVector> vertices)
63 : VGM::ISolid(),
64 VGM::IArb8(),
65 BaseVGM::VArb8(),
66 fHz(hz),
67 fVertices(vertices),
68 fTessellatedSolid(0)
69{
90
91 if (IsTwisted(vertices)) {
92 std::cerr << "+++ Error +++" << std::endl;
93 std::cerr << " Twisted Arb8 is not supported " << std::endl;
94 exit(1);
95 }
96
97 // 3D vertices
98 G4int nv = fgkNofVertices / 2;
99 std::vector<G4ThreeVector> downVertices;
100 for (G4int i = 0; i < nv; i++)
101 downVertices.push_back(
102 G4ThreeVector(vertices[i].first / ClhepVGM::Units::Length(),
103 vertices[i].second / ClhepVGM::Units::Length(),
104 -hz / ClhepVGM::Units::Length()));
105
106 std::vector<G4ThreeVector> upVertices;
107 for (G4int i = nv; i < 2 * nv; i++)
108 upVertices.push_back(
109 G4ThreeVector(vertices[i].first / ClhepVGM::Units::Length(),
110 vertices[i].second / ClhepVGM::Units::Length(),
112
113 // Reorder vertices if they are not ordered anti-clock wise
114 G4ThreeVector cross = (downVertices[1] - downVertices[0])
115 .cross(downVertices[2] - downVertices[1]);
116 if (cross.z() > 0.0) {
117 ReorderVertices(downVertices);
118 ReorderVertices(upVertices);
119 }
120
121 fTessellatedSolid = new G4TessellatedSolid(name);
122
123 G4VFacet* facet = 0;
124 facet = MakeDownFacet(downVertices, 0, 1, 2);
125 if (facet) fTessellatedSolid->AddFacet(facet);
126
127 facet = MakeDownFacet(downVertices, 0, 2, 3);
128 if (facet) fTessellatedSolid->AddFacet(facet);
129
130 facet = MakeUpFacet(upVertices, 0, 2, 1);
131 if (facet) fTessellatedSolid->AddFacet(facet);
132
133 facet = MakeUpFacet(upVertices, 0, 3, 2);
134 if (facet) fTessellatedSolid->AddFacet(facet);
135
136 // The quadrangular sides
137 for (G4int i = 0; i < nv; ++i) {
138 G4int j = (i + 1) % nv;
139 facet = MakeSideFacet(
140 downVertices[j], downVertices[i], upVertices[i], upVertices[j]);
141
142 if (facet) fTessellatedSolid->AddFacet(facet);
143 }
144
145 fTessellatedSolid->SetSolidClosed(true);
146
147 // G4cout << "Arb8 solid " << Name() << G4endl;
148 // G4cout << *fTessellatedSolid << G4endl;
149
150 Geant4GM::SolidMap::Instance()->AddSolid(this, fTessellatedSolid);
151}
152
153//_____________________________________________________________________________
155 : VGM::ISolid(),
156 VGM::IArb8(),
157 BaseVGM::VArb8(),
158 fHz(0),
159 fVertices(),
160 fTessellatedSolid(0)
161{
163}
164
165//_____________________________________________________________________________
167 : VGM::ISolid(rhs),
168 VGM::IArb8(rhs),
169 BaseVGM::VArb8(rhs),
170 fHz(0),
171 fVertices(),
172 fTessellatedSolid(0)
173{
175}
176
177//_____________________________________________________________________________
179{
180 //
181}
182
183//_____________________________________________________________________________
184void Geant4GM::Arb8::ReorderVertices(std::vector<G4ThreeVector>& vertices)
185{
186 // Reorder the vector of vertices
187
188 std::vector<G4ThreeVector> oldVertices(vertices);
189
190 for (unsigned int i = 0; i < oldVertices.size(); ++i) {
191 vertices[i] = oldVertices[oldVertices.size() - 1 - i];
192 }
193}
194
195//_____________________________________________________________________________
196G4VFacet* Geant4GM::Arb8::MakeDownFacet(
197 std::vector<G4ThreeVector> fromVertices, int ind1, int ind2, int ind3) const
198{
199 // Create a triangular facet from the polygon points given by indices
200 // forming the down side ( the normal goes in -z)
201
202 // Do not create facet if 2 vertices are the same
203 if (fromVertices[ind1] == fromVertices[ind2] ||
204 fromVertices[ind2] == fromVertices[ind3] ||
205 fromVertices[ind1] == fromVertices[ind3])
206 return 0;
207
208 std::vector<G4ThreeVector> vertices;
209 vertices.push_back(fromVertices[ind1]);
210 vertices.push_back(fromVertices[ind2]);
211 vertices.push_back(fromVertices[ind3]);
212
213 // first vertex most left
214 //
215 G4ThreeVector cross =
216 (vertices[1] - vertices[0]).cross(vertices[2] - vertices[1]);
217
218 if (cross.z() > 0.0) {
219 // Should not happen, as vertices should have been reordered
220 // at this stage
221 std::cerr << " Geant4GM::Arb8::MakeDownFacet:" << std::endl;
222 std::cerr << " Vertices in wrong order." << std::endl;
223 std::cerr << "*** Error: Aborting execution ***" << std::endl;
224 exit(1);
225 }
226
227 return new G4TriangularFacet(vertices[0], vertices[1], vertices[2], ABSOLUTE);
228}
229
230//_____________________________________________________________________________
231G4VFacet* Geant4GM::Arb8::MakeUpFacet(
232 std::vector<G4ThreeVector> fromVertices, int ind1, int ind2, int ind3) const
233{
234 // Creates a triangular facet from the polygon points given by indices
235 // forming the upper side ( z>0 )
236
237 // Do not create facet if 2 vertices are the same
238 if (fromVertices[ind1] == fromVertices[ind2] ||
239 fromVertices[ind2] == fromVertices[ind3] ||
240 fromVertices[ind1] == fromVertices[ind3])
241 return 0;
242
243 std::vector<G4ThreeVector> vertices;
244 vertices.push_back(fromVertices[ind1]);
245 vertices.push_back(fromVertices[ind2]);
246 vertices.push_back(fromVertices[ind3]);
247
248 // first vertex most left
249 //
250 G4ThreeVector cross =
251 (vertices[1] - vertices[0]).cross(vertices[2] - vertices[1]);
252
253 if (cross.z() < 0.0) {
254 // Should not happen, as vertices should have been reordered
255 // at this stage
256 std::cerr << " Geant4GM::Arb8::MakeUpFacet:" << std::endl;
257 std::cerr << " Vertices in wrong order." << std::endl;
258 std::cerr << "*** Error: Aborting execution ***" << std::endl;
259 exit(1);
260 }
261
262 return new G4TriangularFacet(vertices[0], vertices[1], vertices[2], ABSOLUTE);
263}
264
265//_____________________________________________________________________________
266G4VFacet* Geant4GM::Arb8::MakeSideFacet(G4ThreeVector downVertex0,
267 G4ThreeVector downVertex1, G4ThreeVector upVertex1,
268 G4ThreeVector upVertex0) const
269{
270 // Creates a triangular facet from the polygon points given by indices
271 // forming the upper side ( z>0 )
272
273 if (downVertex0 == downVertex1 && upVertex0 == upVertex1) return 0;
274
275 if (downVertex0 == downVertex1)
276 return new G4TriangularFacet(downVertex0, upVertex1, upVertex0, ABSOLUTE);
277
278 if (upVertex0 == upVertex1)
279 return new G4TriangularFacet(downVertex0, downVertex1, upVertex0, ABSOLUTE);
280
281 return new G4QuadrangularFacet(
282 downVertex0, downVertex1, upVertex1, upVertex0, ABSOLUTE);
283}
284
285//_____________________________________________________________________________
286std::string Geant4GM::Arb8::Name() const
287{
288 return fTessellatedSolid->GetName();
289}
290
291//_____________________________________________________________________________
292int Geant4GM::Arb8::NofVertices() const { return fgkNofVertices; }
293
294//_____________________________________________________________________________
296{
297 if (index < 0 || index >= NofVertices()) {
298 std::cerr << "+++ Error +++" << std::endl;
299 std::cerr << " Wrong vertex index: " << index << std::endl;
300 exit(1);
301 }
302
303 return fVertices[index];
304}
305
306//_____________________________________________________________________________
307double Geant4GM::Arb8::TwistAngle(int index) const
308{
309 // Just return 0, as twisted arb8 are not supported
310
311 if (index < 0 || index >= 4) {
312 std::cerr << "+++ Error +++" << std::endl;
313 std::cerr << " Wrong twist angle index: " << index << std::endl;
314 exit(1);
315 }
316
317 return 0;
318}
319
320//_____________________________________________________________________________
321double Geant4GM::Arb8::ZHalfLength() const { return fHz; }
static double Length()
Return CLHEP default length unit in VGM units.
Definition Units.cxx:83
VGM implementation for Geant4 Arb8 solid, the shape is implemented using G4TessellatedSolid.
Definition Arb8.h:41
static bool IsTwisted(std::vector< VGM::TwoVector > vertices)
Definition Arb8.cxx:34
virtual ~Arb8()
Definition Arb8.cxx:178
virtual int NofVertices() const
Return the number of vertices.
Definition Arb8.cxx:292
virtual double ZHalfLength() const
Return the half-length along the z axis in mm.
Definition Arb8.cxx:321
virtual VGM::TwoVector Vertex(int index) const
Return the index-th vertex.
Definition Arb8.cxx:295
virtual double TwistAngle(int index) const
Return the index-th twist angle.
Definition Arb8.cxx:307
virtual std::string Name() const
Return the name of this solid.
Definition Arb8.cxx:286
static SolidMap * Instance()
Definition SolidMap.cxx:28
void AddSolid(VGM::ISolid *, G4VSolid *)
Definition SolidMap.cxx:59
BaseVGM utilities.
Definition utilities.h:23
VGM interfaces.
Definition VMedium.h:28
std::pair< double, double > TwoVector
Definition TwoVector.h:28