BornAgain  1.19.79
Simulate and fit neutron and x-ray scattering at grazing incidence
particles.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/ba3d/model/particles.cpp
6 //! @brief Implements Particle class
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include <cmath>
17 
19 
20 QString const& name(EShape k)
21 {
22  static QString names[] = {"",
23  "BarGauss",
24  "BarLorentz",
25  "Bipyramid4",
26  "Box",
27  "CantellatedCube",
28  "Cone",
29  "CosineRippleBox",
30  "CosineRippleGauss",
31  "CosineRippleLorentz",
32  "Cylinder",
33  "Dodecahedron",
34  "EllipsoidalCylinder",
35  "Sphere",
36  "Spheroid",
37  "HemiEllipsoid",
38  "HorizontalCylinder",
39  "Icosahedron",
40  "PlatonicOctahedron",
41  "PlatonicTetrahedron",
42  "Prism3",
43  "Prism6",
44  "Pyramid2",
45  "Pyramid3",
46  "Pyramid4",
47  "Pyramid6",
48  "SawtoothRippleBox",
49  "SawtoothRippleGauss",
50  "SawtoothRippleLorentz",
51  "TruncatedCube",
52  "TruncatedSphere",
53  "TruncatedSpheroid"};
54  return names[uint(k)];
55 }
56 
57 //------------------------------------------------------------------------------
58 
59 using namespace GeometricID;
60 
62  : Object(key)
63  , scale(Vector3D::_1)
64 {
65 }
66 
68 {
70 }
71 
72 void Particle::transform(Vector3D rotate_, Vector3D translate_)
73 {
74  Object::transform(turn, scale, (rotate = rotate_), offset + (translate = translate_));
75 }
76 
77 void Particle::fancy(Vector3D rotate, float r)
78 {
80 }
81 
82 void Particle::addTransform(Vector3D rotate_, Vector3D translate_)
83 {
84  Object::transform(turn, scale, (rotate = rotate + rotate_),
85  offset + (translate = translate + translate_));
86 }
87 
89 {
91 }
92 
94 {
95  Object::addExtrinsicRotation(turn, scale, rotate, rotateExtrinsic,
96  (translate = offset + translate));
97 }
98 
99 //------------------------------------------------------------------------------
100 
101 static float const pi = float(M_PI);
102 static float const pi2f = float(M_PI_2);
103 static float const sqrt2f = std::sqrt(2.f);
104 static float const sqrt3f = std::sqrt(3.f);
105 
106 // see ~/BornAgain/GUI/ba3d/ba3d/model/geometry/ for BaseShape construction
107 
108 // TODO : issue #269 : wrong BaseShape model. Now Pyramid2 always has top vertex. The true Pyramid2
109 // should have top edge if L!=W.
110 Pyramid2::Pyramid2(float L, float W, float H, float alpha)
111  : Particle(Key(BaseShape::Column, (1.0f - H / (std::min(L, W) / 2 * std::tan(alpha))), 4))
112 {
113  isNull = (L <= 0 || W <= 0 || H <= 0 || alpha <= 0);
114  turn = Vector3D(0, 0, 45 * pi / 180.0f);
115  scale = Vector3D(L * sqrt2f, W * sqrt2f, H);
116  offset = Vector3D(0, 0, 0);
117  set();
118 }
119 
120 BarGauss::BarGauss(float L, float W, float H)
121  : Particle(Key(BaseShape::Column, 1.0f, 4))
122 {
123  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
124  turn = Vector3D(0, 0, 45 * pi / 180.0f);
125  scale = Vector3D(L * sqrt2f, W * sqrt2f, H);
126  offset = Vector3D(0, 0, 0);
127  set();
128 }
129 
130 BarLorentz::BarLorentz(float L, float W, float H)
131  : Particle(Key(BaseShape::Column, 1.0f, 4))
132 {
133  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
134  turn = Vector3D(0, 0, 45 * pi / 180.0f);
135  scale = Vector3D(L * sqrt2f, W * sqrt2f, H);
136  offset = Vector3D(0, 0, 0);
137  set();
138 }
139 
140 Box::Box(float L, float W, float H)
141  : Particle(Key(BaseShape::Column, 1.0f, 4))
142 {
143  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
144  turn = Vector3D(0, 0, 45 * pi / 180.0f);
145  scale = Vector3D(L * sqrt2f, W * sqrt2f, H);
146  offset = Vector3D(0, 0, 0);
147  set();
148 }
149 
150 Cone::Cone(float R, float H, float alpha)
151  : Particle(Key(BaseShape::Column, (1.0f - H / (R * std::tan(alpha))), 0))
152 {
153  isNull = (R <= 0 || H <= 0 || alpha <= 0);
154  scale = Vector3D(R * 2, R * 2, H);
155  offset = Vector3D(0, 0, 0);
156  set();
157 }
158 
159 Pyramid6::Pyramid6(float R, float H, float alpha)
160  : Particle(Key(BaseShape::Column, (1.0f - H / (R * sqrt3f / 2 * std::tan(alpha))), 6))
161 {
162  isNull = (R <= 0 || H <= 0 || alpha <= 0);
163  scale = Vector3D(R * 2, R * 2, H);
164  offset = Vector3D(0, 0, 0);
165  set();
166 }
167 
168 Bipyramid4::Bipyramid4(float L, float H, float rH, float alpha)
169  : Particle(Key(BaseShape::Bipyramid4, rH, alpha, H / L))
170 {
171  isNull = (L <= 0 || H <= 0 || rH <= 0 || alpha >= pi2f);
172  scale = Vector3D(L, L, L);
173  offset = Vector3D(0, 0, 0);
174  set();
175 }
176 
177 Cylinder::Cylinder(float R, float H)
178  : Particle(Key(BaseShape::Column, 1.0f, 0))
179 {
180  isNull = (R <= 0 || H <= 0);
181  scale = Vector3D(R * 2, R * 2, H);
182  offset = Vector3D(0, 0, 0);
183  set();
184 }
185 
188 {
189  isNull = (L <= 0);
190  float R = L / DodecahedronL2R;
191  scale = Vector3D(R * 2, R * 2, R * 2);
192  offset = Vector3D(0, 0, 0);
193  set();
194 }
195 
196 EllipsoidalCylinder::EllipsoidalCylinder(float Ra, float Rb, float H)
197  : Particle(Key(BaseShape::Column, 1.0f, 0))
198 {
199  isNull = (Ra <= 0 || Rb <= 0 || H <= 0);
200  scale = Vector3D(Ra * 2, Rb * 2, H);
201  offset = Vector3D(0, 0, 0);
202  set();
203 }
204 
206  : Particle(Key(BaseShape::Sphere, 0, 0.5f))
207 {
208  isNull = (R <= 0);
209  scale = Vector3D(R * 2);
210  offset = Vector3D(0, 0, 0);
211  set();
212 }
213 
214 Spheroid::Spheroid(float R, float H)
215  : Particle(Key(BaseShape::Sphere, 0, 0.5f))
216 {
217  isNull = (R <= 0 || H <= 0);
218  scale = Vector3D(R * 2, R * 2, H);
219  offset = Vector3D(0, 0, 0);
220  set();
221 }
222 
223 HemiEllipsoid::HemiEllipsoid(float Ra, float Rb, float H)
224  : Particle(Key(BaseShape::Sphere, .5f, 0.0f))
225 {
226  isNull = (Ra <= 0 || Rb <= 0 || H <= 0);
227  scale = Vector3D(Ra * 2, Rb * 2, H * 2);
228  offset = Vector3D(0, 0, 0);
229  set();
230 }
231 
234 {
235  isNull = (L <= 0);
236  scale = Vector3D(L, L, L);
237  offset = Vector3D(0, 0, 0);
238  set();
239 }
240 
241 Prism3::Prism3(float L, float H)
242  : Particle(Key(BaseShape::Column, 1.0f, 3))
243 {
244  isNull = (L <= 0 || H <= 0);
245  float D = L / sqrt3f;
246  scale = Vector3D(D * 2, D * 2, H);
247  offset = Vector3D(0, 0, 0);
248  set();
249 }
250 
251 Prism6::Prism6(float R, float H)
252  : Particle(Key(BaseShape::Column, 1.0f, 6))
253 {
254  isNull = (R <= 0 || H <= 0);
255  scale = Vector3D(R * 2, R * 2, H);
256  offset = Vector3D(0, 0, 0);
257  set();
258 }
259 
260 Pyramid4::Pyramid4(float L, float H, float alpha)
261  : Particle(Key(BaseShape::Column, (1.0f - H / (L / 2 * std::tan(alpha))), 4))
262 {
263  isNull = (L <= 0 || H <= 0 || alpha <= 0);
264  float L2 = L * sqrt2f;
265  turn = Vector3D(0, 0, 45 * pi / 180.0f);
266  scale = Vector3D(L2, L2, H);
267  offset = Vector3D(0, 0, 0);
268  set();
269 }
270 
271 CosineRippleBox::CosineRippleBox(float L, float W, float H)
272  : Particle(Key(BaseShape::Ripple, 0, 0))
273 {
274  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
275  turn = Vector3D(0, 0, 0);
276  scale = Vector3D(L, W, H);
277  offset = Vector3D(0, 0, 0);
278  set();
279 }
280 
281 CosineRippleGauss::CosineRippleGauss(float L, float W, float H)
282  : Particle(Key(BaseShape::Ripple, 0, 0))
283 {
284  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
285  turn = Vector3D(0, 0, 0);
286  scale = Vector3D(L, W, H);
287  offset = Vector3D(0, 0, 0);
288  set();
289 }
290 
292  : Particle(Key(BaseShape::Ripple, 0, 0))
293 {
294  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
295  turn = Vector3D(0, 0, 0);
296  scale = Vector3D(L, W, H);
297  offset = Vector3D(0, 0, 0);
298  set();
299 }
300 
301 SawtoothRippleBox::SawtoothRippleBox(float L, float W, float H)
302  : Particle(Key(BaseShape::Ripple, 0, 0))
303 {
304  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
305  turn = Vector3D(0, 0, 0);
306  scale = Vector3D(L, W, H);
307  offset = Vector3D(0, 0, 0);
308  set();
309 }
310 
312  : Particle(Key(BaseShape::Ripple, 0, 0))
313 {
314  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
315  turn = Vector3D(0, 0, 0);
316  scale = Vector3D(L, W, H);
317  offset = Vector3D(0, 0, 0);
318  set();
319 }
320 
322  : Particle(Key(BaseShape::Ripple, 0, 0))
323 {
324  isNull = (L < 0 || W < 0 || H < 0) || (L <= 0 && W <= 0 && H <= 0);
325  turn = Vector3D(0, 0, 0);
326  scale = Vector3D(L, W, H);
327  offset = Vector3D(0, 0, 0);
328  set();
329 }
330 
331 Pyramid3::Pyramid3(float L, float H, float alpha)
332  : Particle(Key(BaseShape::Column, (1.0f - H / (L / (2 * sqrt3f) * std::tan(alpha))), 3))
333 {
334  isNull = (L <= 0 || H <= 0 || alpha <= 0);
335  float D = L / sqrt3f;
336  scale = Vector3D(D * 2, D * 2, H);
337  offset = Vector3D(0, 0, 0);
338  set();
339 }
340 
342  : Particle(Key(BaseShape::TruncatedBox, 2 * t / L))
343 {
344  isNull = (L <= 0);
345  scale = Vector3D(L, L, L);
346  offset = Vector3D(0, 0, 0);
347  set();
348 }
349 
350 TruncatedSphere::TruncatedSphere(float R, float H, float deltaH)
351  : Particle(Key(BaseShape::Sphere, 1 - H / R / 2, (H - R) / R / 2, deltaH / R / 2))
352 {
353  isNull = (R <= 0 || H <= 0);
354  scale = Vector3D(R * 2);
355  offset = Vector3D(0, 0, 0);
356  set();
357 }
358 
359 TruncatedSpheroid::TruncatedSpheroid(float R, float H, float fp, float deltaH)
360  : Particle(
361  Key(BaseShape::Sphere, 1 - H / fp / R / 2, (H - fp * R) / fp / R / 2, deltaH / fp / R / 2))
362 {
363  isNull = (R <= 0 || H <= 0 || fp <= 0);
364  scale = Vector3D(R * 2, R * 2, fp * R * 2);
365  offset = Vector3D(0, 0, 0);
366  set();
367 }
368 
369 // TODO : issue #269 : change base shape to cantellated box
371  : Particle(Key(BaseShape::TruncatedBox, 2 * t / L))
372 {
373  isNull = (L <= 0);
374  scale = Vector3D(L, L, L);
375  offset = Vector3D(0, 0, 0);
376  set();
377 }
378 
379 HorizontalCylinder::HorizontalCylinder(float R, float L, float s_b, float s_t)
380  : Particle(Key(BaseShape::Column, 1.0f, 0))
381 {
382  isNull = (R <= 0 || L <= 0 || s_b >= s_t);
383  turn = Vector3D(90 * pi / 180.0f, 90 * pi / 180.0f, 0);
384  scale = Vector3D(L, R * 2, R * 2);
385  offset = Vector3D(0, 0, 0);
386  set();
387 }
388 
390  : Particle(Key(BaseShape::Bipyramid4, 1.0f, asin(sqrt(2.0f / 3)), 1.0f / sqrt(2.0f)))
391 {
392  isNull = (L <= 0);
393  scale = Vector3D(L, L, L);
394  offset = Vector3D(0, 0, 0);
395  set();
396 }
397 
399  : Particle(Key(BaseShape::Column, 0, 3))
400 {
401  isNull = (L <= 0);
402  float D = L / sqrt3f;
403  scale = Vector3D(D * 2, D * 2, L * sqrt(6.f) / 3);
404  offset = Vector3D(0, 0, 0);
405  set();
406 }
407 
408 } // namespace GUI::RealSpace::Particles
A geometric object.
Definition: object.h:28
void transform(float scale, Vector3D rotate, Vector3D translate)
Definition: object.cpp:51
void addExtrinsicRotation(Vector3D turn, Vector3D scale, Vector3D &rotate, Vector3D rotateExtrinsic, Vector3D &translate)
Definition: object.cpp:79
BarGauss(float L, float W, float H)
Definition: particles.cpp:120
BarLorentz(float L, float W, float H)
Definition: particles.cpp:130
Bipyramid4(float L, float H, float rH, float alpha)
Definition: particles.cpp:168
Box(float L, float W, float H)
Definition: particles.cpp:140
Cone(float R, float H, float alpha)
Definition: particles.cpp:150
CosineRippleBox(float L, float W, float H)
Definition: particles.cpp:271
CosineRippleGauss(float L, float W, float H)
Definition: particles.cpp:281
CosineRippleLorentz(float L, float W, float H)
Definition: particles.cpp:291
EllipsoidalCylinder(float Ra, float Rb, float H)
Definition: particles.cpp:196
HemiEllipsoid(float Ra, float Rb, float H)
Definition: particles.cpp:223
HorizontalCylinder(float R, float L, float s_b, float s_t)
Definition: particles.cpp:379
void transform(Vector3D rotate, Vector3D translate)
Definition: particles.cpp:72
void addExtrinsicRotation(Vector3D rotateExtrinsic)
Definition: particles.cpp:93
void fancy(Vector3D rotate, float r)
Definition: particles.cpp:77
void addTransform(Vector3D rotate, Vector3D translate)
Definition: particles.cpp:82
void addTranslation(Vector3D translate_)
Definition: particles.cpp:88
Pyramid2(float L, float W, float H, float alpha)
Definition: particles.cpp:110
Pyramid3(float L, float H, float alpha)
Definition: particles.cpp:331
Pyramid4(float L, float H, float alpha)
Definition: particles.cpp:260
Pyramid6(float R, float H, float alpha)
Definition: particles.cpp:159
SawtoothRippleBox(float L, float W, float H)
Definition: particles.cpp:301
SawtoothRippleGauss(float L, float W, float H)
Definition: particles.cpp:311
SawtoothRippleLorentz(float L, float W, float H)
Definition: particles.cpp:321
TruncatedSphere(float R, float H, float deltaH=0.0f)
Definition: particles.cpp:350
TruncatedSpheroid(float R, float H, float fp, float deltaH=0.0f)
Definition: particles.cpp:359
BaseShape
Enum id for basic shapes.
Definition: geometry_inc.h:38
QString const & name(EShape k)
Definition: particles.cpp:20
static float const pi2f
Definition: particles.cpp:102
static float const sqrt3f
Definition: particles.cpp:104
static float const pi
Definition: particles.cpp:101
static float const sqrt2f
Definition: particles.cpp:103
const float DodecahedronL2R
Defines Particle class.
Real shapes will be parameterized by BaseShape enum and possibly two floats.
Definition: geometry_inc.h:51
static Vector3D const _0
Definition: def.h:46