Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
TGeoTet.cc
Go to the documentation of this file.
1#include <iostream>
2
3#include "Garfield/TGeoTet.hh"
4
5#include "TGeoManager.h"
6#include "TGeoMatrix.h"
7#include "TGeoVolume.h"
8#include "TVirtualGeoPainter.h"
9#include "TBuffer3D.h"
10#include "TBuffer3DTypes.h"
11
12// ClassImp(TGeoTet)
13
14using Vec = std::array<double, 3>;
15
16namespace {
17
18Vec Dir(const Vec& a, const Vec& b) {
19 Vec c;
20 for (size_t i = 0; i < 3; ++i) c[i] = b[i] - a[i];
21 return c;
22}
23
24Vec Cross(const Vec& a, const Vec& b) {
25
26 Vec c = {a[1] * b[2] - a[2] * b[1],
27 a[2] * b[0] - a[0] * b[2],
28 a[0] * b[1] - a[1] - b[0]};
29 return c;
30}
31
32double Dot(const Vec& a, const Vec& b) {
33 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
34}
35
36}
37
38TGeoTet::TGeoTet(const char *name,
39 const std::array<Vec, 4>& vertices)
40 : TGeoBBox(name, 0, 0, 0) {
41 fVertices = vertices;
42
43 Vec u;
44 Vec v;
45 Vec w;
46 for (size_t i = 0; i < 3; ++i) {
47 u[i] = fVertices[1][i] - fVertices[0][i];
48 v[i] = fVertices[2][i] - fVertices[0][i];
49 w[i] = fVertices[3][i] - fVertices[0][i];
50 }
51 Vec x = Cross(v, w);
52 double det = Dot(x, u);
53 if (det < 0.) std::swap(fVertices[0], fVertices[1]);
54}
55
57 const double kBig = TGeoShape::Big();
58 double vmin[3] = {kBig, kBig, kBig};
59 double vmax[3] = {-kBig, -kBig, -kBig};
60 for (size_t i = 0; i < 4; ++i) {
61 for (size_t j = 0; j < 3; ++j) {
62 vmin[j] = std::min(vmin[j], fVertices[i][j]);
63 vmax[j] = std::max(vmax[j], fVertices[i][j]);
64 }
65 }
66 fDX = 0.5 * (vmax[0] - vmin[0]);
67 fDY = 0.5 * (vmax[1] - vmin[1]);
68 fDZ = 0.5 * (vmax[2] - vmin[2]);
69 for (size_t i = 0; i < 3; ++i) {
70 fOrigin[i] = 0.5 * (vmax[i] + vmin[i]);
71 }
72}
73
74TBuffer3D *TGeoTet::MakeBuffer3D() const {
75 // Number of vertices.
76 constexpr int nv = 4;
77 // Number of segments.
78 // constexpr int ns = 6;
79 constexpr int ns = 12;
80 // Number of polygons.
81 constexpr int np = 4;
82 auto buff = new TBuffer3D(TBuffer3DTypes::kGeneric, nv, 3 * nv, ns, 3 * ns, np, 5 * np);
83 SetPoints(buff->fPnts);
84 SetSegsAndPols(*buff);
85 return buff;
86}
87
88void TGeoTet::Print(Option_t *) const {
89 std::cout << "=== Tetrahedron " << GetName() << "\n";
90}
91
92void TGeoTet::SetSegsAndPols(TBuffer3D &buff) const {
93 const int c = GetBasicColor();
94
95 auto v01 = Dir(fVertices[0], fVertices[1]);
96 auto v02 = Dir(fVertices[0], fVertices[2]);
97 auto v03 = Dir(fVertices[0], fVertices[3]);
98
99 auto v12 = Dir(fVertices[1], fVertices[2]);
100 auto v13 = Dir(fVertices[1], fVertices[3]);
101 auto v10 = Dir(fVertices[1], fVertices[0]);
102
103 auto v23 = Dir(fVertices[2], fVertices[3]);
104 auto v20 = Dir(fVertices[2], fVertices[0]);
105 auto v21 = Dir(fVertices[2], fVertices[1]);
106
107 auto v30 = Dir(fVertices[3], fVertices[0]);
108 auto v31 = Dir(fVertices[3], fVertices[1]);
109 auto v32 = Dir(fVertices[3], fVertices[2]);
110
111 std::vector<std::array<int, 3> > faces;
112 if (Dot(Cross(v01, v02), v03) > 0) {
113 faces.push_back({1, 0, 2});
114 } else {
115 faces.push_back({0, 1, 2});
116 }
117
118 if (Dot(Cross(v12, v13), v10) > 0) {
119 faces.push_back({2, 1, 3});
120 } else {
121 faces.push_back({1, 2, 3});
122 }
123
124 if (Dot(Cross(v23, v20), v21) > 0) {
125 faces.push_back({3, 2, 0});
126 } else {
127 faces.push_back({2, 3, 0});
128 }
129
130 if (Dot(Cross(v30, v31), v32) > 0) {
131 faces.push_back({0, 3, 1});
132 } else {
133 faces.push_back({3, 0, 1});
134 }
135
136 size_t ind = 0;
137 for (const auto& face : faces) {
138 buff.fSegs[ind++] = c;
139 buff.fSegs[ind++] = face[0];
140 buff.fSegs[ind++] = face[1];
141 buff.fSegs[ind++] = c;
142 buff.fSegs[ind++] = face[1];
143 buff.fSegs[ind++] = face[2];
144 buff.fSegs[ind++] = c;
145 buff.fSegs[ind++] = face[2];
146 buff.fSegs[ind++] = face[0];
147 }
148
149 ind = 0;
150 for (size_t i = 0; i < 4; ++i) {
151 buff.fPols[ind++] = c;
152 buff.fPols[ind++] = 3;
153 buff.fPols[ind++] = 3 * i;
154 buff.fPols[ind++] = 3 * i + 1;
155 buff.fPols[ind++] = 3 * i + 2;
156 }
157}
158
159void TGeoTet::SetPoints(double *points) const {
160 size_t ind = 0;
161 for (const auto& vertex : fVertices) {
162 points[ind++] = vertex[0];
163 points[ind++] = vertex[1];
164 points[ind++] = vertex[2];
165 }
166}
167
168void TGeoTet::SetPoints(float *points) const {
169 size_t ind = 0;
170 for (const auto& vertex : fVertices) {
171 points[ind++] = vertex[0];
172 points[ind++] = vertex[1];
173 points[ind++] = vertex[2];
174 }
175}
176
177/// Fills a static 3D buffer and returns a reference.
178const TBuffer3D& TGeoTet::GetBuffer3D(int reqSections, bool localFrame) const {
179 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
180
181 FillBuffer3D(buffer, reqSections, localFrame);
182
183 constexpr int nv = 4;
184 // constexpr int ns = 6;
185 constexpr int ns = 12;
186 constexpr int np = 4;
187 if (reqSections & TBuffer3D::kRawSizes) {
188 if (buffer.SetRawSizes(nv, 3 * nv, ns, 3 * ns, np, 5 * np)) {
189 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
190 }
191 }
192 if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
193 SetPoints(buffer.fPnts);
194 if (!buffer.fLocalFrame) {
195 TransformPoints(buffer.fPnts, buffer.NbPnts());
196 }
197 SetSegsAndPols(buffer);
198 buffer.SetSectionsValid(TBuffer3D::kRaw);
199 }
200 return buffer;
201}
202
std::array< double, 3 > Vec
Definition TGeoTet.cc:14
TGeoTet()
Definition TGeoTet.hh:11
const TBuffer3D & GetBuffer3D(int reqSections, bool localFrame) const override
Fills a static 3D buffer and returns a reference.
Definition TGeoTet.cc:178
void SetSegsAndPols(TBuffer3D &buff) const override
Definition TGeoTet.cc:92
TBuffer3D * MakeBuffer3D() const override
Definition TGeoTet.cc:74
void Print(Option_t *option="") const override
Definition TGeoTet.cc:88
void SetPoints(double *points) const override
Definition TGeoTet.cc:159
void ComputeBBox() override
Definition TGeoTet.cc:56