Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoTrd2.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 31/01/02
3// TGeoTrd2::Contains() and DistFromInside() implemented by Mihaela Gheata
4
5/*************************************************************************
6 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13/** \class TGeoTrd2
14\ingroup Trapezoids
15
16A trapezoid with only X varying with Z. It is defined by the
17half-length in Z, the half-length in X at the lowest and highest Z
18planes and the half-length in Y:
19Begin_Macro
20{
21 TCanvas *c = new TCanvas("c", "c",0,0,600,600);
22 new TGeoManager("trd2", "poza9");
23 TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
24 TGeoMedium *med = new TGeoMedium("MED",1,mat);
25 TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
26 gGeoManager->SetTopVolume(top);
27 TGeoVolume *vol = gGeoManager->MakeTrd2("Trd2",med, 10,20,30,10,40);
28 vol->SetLineWidth(2);
29 gGeoManager->CloseGeometry();
30 gGeoManager->SetNsegments(80);
31 top->Draw();
32 TView *view = gPad->GetView();
33 if (view) view->ShowAxis();
34}
35End_Macro
36
37*/
38
39#include <iostream>
40
41#include "TGeoManager.h"
42#include "TGeoMatrix.h"
43#include "TGeoVolume.h"
44#include "TGeoTrd2.h"
45#include "TMath.h"
46
47
48////////////////////////////////////////////////////////////////////////////////
49/// dummy ctor
50
56
57////////////////////////////////////////////////////////////////////////////////
58/// constructor.
59
61{
63 fDx1 = dx1;
64 fDx2 = dx2;
65 fDy1 = dy1;
66 fDy2 = dy2;
67 fDz = dz;
68 if ((fDx1 < 0) || (fDx2 < 0) || (fDy1 < 0) || (fDy2 < 0) || (fDz < 0)) {
70 printf("trd2 : dx1=%f, dx2=%f, dy1=%f, dy2=%f, dz=%f\n", dx1, dx2, dy1, dy2, dz);
71 } else
73}
74
75////////////////////////////////////////////////////////////////////////////////
76/// constructor.
77
79 : TGeoBBox(name, 0, 0, 0)
80{
82 fDx1 = dx1;
83 fDx2 = dx2;
84 fDy1 = dy1;
85 fDy2 = dy2;
86 fDz = dz;
87 if ((fDx1 < 0) || (fDx2 < 0) || (fDy1 < 0) || (fDy2 < 0) || (fDz < 0)) {
89 printf("trd2 : dx1=%f, dx2=%f, dy1=%f, dy2=%f, dz=%f\n", dx1, dx2, dy1, dy2, dz);
90 } else
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// ctor with an array of parameters
96/// - param[0] = dx1
97/// - param[1] = dx2
98/// - param[2] = dy1
99/// - param[3] = dy2
100/// - param[4] = dz
101
103{
105 SetDimensions(param);
106 if ((fDx1 < 0) || (fDx2 < 0) || (fDy1 < 0) || (fDy2 < 0) || (fDz < 0))
108 else
109 ComputeBBox();
110}
111
112////////////////////////////////////////////////////////////////////////////////
113/// destructor
114
116
117////////////////////////////////////////////////////////////////////////////////
118/// Computes capacity of the shape in [length^3]
119
121{
122 Double_t capacity = 2 * (fDx1 + fDx2) * (fDy1 + fDy2) * fDz + (2. / 3.) * (fDx1 - fDx2) * (fDy1 - fDy2) * fDz;
123 return capacity;
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// compute bounding box for a trd2
128
130{
133 fDZ = fDz;
134 memset(fOrigin, 0, 3 * sizeof(Double_t));
135}
136
137////////////////////////////////////////////////////////////////////////////////
138/// Compute normal to closest surface from POINT.
139
140void TGeoTrd2::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
141{
143 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
144 Double_t calf = 1. / TMath::Sqrt(1.0 + fx * fx);
145 // check Z facettes
146 safe = safemin = TMath::Abs(fDz - TMath::Abs(point[2]));
147 norm[0] = norm[1] = 0;
148 norm[2] = (dir[2] >= 0) ? 1 : -1;
150 return;
151 // check X facettes
152 Double_t distx = 0.5 * (fDx1 + fDx2) - fx * point[2];
153 if (distx >= 0) {
154 safe = TMath::Abs(distx - TMath::Abs(point[0])) * calf;
155 if (safe < safemin) {
156 safemin = safe;
157 norm[0] = (point[0] > 0) ? calf : (-calf);
158 norm[1] = 0;
159 norm[2] = calf * fx;
160 Double_t dot = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
161 if (dot < 0) {
162 norm[0] = -norm[0];
163 norm[2] = -norm[2];
164 }
166 return;
167 }
168 }
169
170 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
171 calf = 1. / TMath::Sqrt(1.0 + fy * fy);
172
173 // check Y facettes
174 distx = 0.5 * (fDy1 + fDy2) - fy * point[2];
175 if (distx >= 0) {
176 safe = TMath::Abs(distx - TMath::Abs(point[1])) * calf;
177 if (safe < safemin) {
178 norm[0] = 0;
179 norm[1] = (point[1] > 0) ? calf : (-calf);
180 norm[2] = calf * fy;
181 Double_t dot = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
182 if (dot < 0) {
183 norm[1] = -norm[1];
184 norm[2] = -norm[2];
185 }
186 }
187 }
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// test if point is inside this shape
192/// check Z range
193
195{
196 if (TMath::Abs(point[2]) > fDz)
197 return kFALSE;
198 // then y
199 Double_t dy = 0.5 * (fDy2 * (point[2] + fDz) + fDy1 * (fDz - point[2])) / fDz;
200 if (TMath::Abs(point[1]) > dy)
201 return kFALSE;
202 // then x
203 Double_t dx = 0.5 * (fDx2 * (point[2] + fDz) + fDx1 * (fDz - point[2])) / fDz;
204 if (TMath::Abs(point[0]) > dx)
205 return kFALSE;
206 return kTRUE;
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Compute distance from inside point to surface of the trd2
211/// Boundary safe algorithm
212
215{
216 if (iact < 3 && safe) {
217 // compute safe distance
218 *safe = Safety(point, kTRUE);
219 if (iact == 0)
220 return TGeoShape::Big();
221 if (iact == 1 && step < *safe)
222 return TGeoShape::Big();
223 }
224
225 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
226 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
227 Double_t cn;
228
229 Double_t distx = 0.5 * (fDx1 + fDx2) - fx * point[2];
230 Double_t disty = 0.5 * (fDy1 + fDy2) - fy * point[2];
231
232 //--- Compute distance to this shape
233 // first check if Z facettes are crossed
234 Double_t dist[3];
235 for (Int_t i = 0; i < 3; i++)
236 dist[i] = TGeoShape::Big();
237 if (dir[2] < 0) {
238 dist[0] = -(point[2] + fDz) / dir[2];
239 } else if (dir[2] > 0) {
240 dist[0] = (fDz - point[2]) / dir[2];
241 }
242 if (dist[0] <= 0)
243 return 0.0;
244 // now check X facettes
245 cn = -dir[0] + fx * dir[2];
246 if (cn > 0) {
247 dist[1] = point[0] + distx;
248 if (dist[1] <= 0)
249 return 0.0;
250 dist[1] /= cn;
251 }
252 cn = dir[0] + fx * dir[2];
253 if (cn > 0) {
254 Double_t s = distx - point[0];
255 if (s <= 0)
256 return 0.0;
257 s /= cn;
258 if (s < dist[1])
259 dist[1] = s;
260 }
261 // now check Y facettes
262 cn = -dir[1] + fy * dir[2];
263 if (cn > 0) {
264 dist[2] = point[1] + disty;
265 if (dist[2] <= 0)
266 return 0.0;
267 dist[2] /= cn;
268 }
269 cn = dir[1] + fy * dir[2];
270 if (cn > 0) {
271 Double_t s = disty - point[1];
272 if (s <= 0)
273 return 0.0;
274 s /= cn;
275 if (s < dist[2])
276 dist[2] = s;
277 }
278 return dist[TMath::LocMin(3, dist)];
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Compute distance from outside point to surface of the trd2
283/// Boundary safe algorithm
284
287{
288 if (iact < 3 && safe) {
289 // compute safe distance
290 *safe = Safety(point, kFALSE);
291 if (iact == 0)
292 return TGeoShape::Big();
293 if (iact == 1 && step < *safe)
294 return TGeoShape::Big();
295 }
296 // find a visible face
298 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
299 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
300 Double_t cn;
301 // check visibility of X faces
302 Double_t distx = 0.5 * (fDx1 + fDx2) - fx * point[2];
303 Double_t disty = 0.5 * (fDy1 + fDy2) - fy * point[2];
304 Bool_t in = kTRUE;
305 Double_t safx = distx - TMath::Abs(point[0]);
306 Double_t safy = disty - TMath::Abs(point[1]);
307 Double_t safz = fDz - TMath::Abs(point[2]);
308 //--- Compute distance to this shape
309 // first check if Z facettes are crossed
310 if (point[2] <= -fDz) {
311 cn = -dir[2];
312 if (cn >= 0)
313 return TGeoShape::Big();
314 in = kFALSE;
315 Double_t snxt = (fDz + point[2]) / cn;
316 // find extrapolated X and Y
317 xnew = point[0] + snxt * dir[0];
318 if (TMath::Abs(xnew) < fDx1) {
319 ynew = point[1] + snxt * dir[1];
320 if (TMath::Abs(ynew) < fDy1)
321 return snxt;
322 }
323 } else if (point[2] >= fDz) {
324 cn = dir[2];
325 if (cn >= 0)
326 return TGeoShape::Big();
327 in = kFALSE;
328 Double_t snxt = (fDz - point[2]) / cn;
329 // find extrapolated X and Y
330 xnew = point[0] + snxt * dir[0];
331 if (TMath::Abs(xnew) < fDx2) {
332 ynew = point[1] + snxt * dir[1];
333 if (TMath::Abs(ynew) < fDy2)
334 return snxt;
335 }
336 }
337 // check if X facettes are crossed
338 if (point[0] <= -distx) {
339 cn = -dir[0] + fx * dir[2];
340 if (cn >= 0)
341 return TGeoShape::Big();
342 in = kFALSE;
343 Double_t snxt = (point[0] + distx) / cn;
344 // find extrapolated Y and Z
345 znew = point[2] + snxt * dir[2];
346 if (TMath::Abs(znew) < fDz) {
347 Double_t dy = 0.5 * (fDy1 + fDy2) - fy * znew;
348 ynew = point[1] + snxt * dir[1];
349 if (TMath::Abs(ynew) < dy)
350 return snxt;
351 }
352 }
353 if (point[0] >= distx) {
354 cn = dir[0] + fx * dir[2];
355 if (cn >= 0)
356 return TGeoShape::Big();
357 in = kFALSE;
358 Double_t snxt = (distx - point[0]) / cn;
359 // find extrapolated Y and Z
360 znew = point[2] + snxt * dir[2];
361 if (TMath::Abs(znew) < fDz) {
362 Double_t dy = 0.5 * (fDy1 + fDy2) - fy * znew;
363 ynew = point[1] + snxt * dir[1];
364 if (TMath::Abs(ynew) < dy)
365 return snxt;
366 }
367 }
368 // finally check Y facettes
369 if (point[1] <= -disty) {
370 cn = -dir[1] + fy * dir[2];
371 in = kFALSE;
372 if (cn >= 0)
373 return TGeoShape::Big();
374 Double_t snxt = (point[1] + disty) / cn;
375 // find extrapolated X and Z
376 znew = point[2] + snxt * dir[2];
377 if (TMath::Abs(znew) < fDz) {
378 Double_t dx = 0.5 * (fDx1 + fDx2) - fx * znew;
379 xnew = point[0] + snxt * dir[0];
380 if (TMath::Abs(xnew) < dx)
381 return snxt;
382 }
383 }
384 if (point[1] >= disty) {
385 cn = dir[1] + fy * dir[2];
386 if (cn >= 0)
387 return TGeoShape::Big();
388 in = kFALSE;
389 Double_t snxt = (disty - point[1]) / cn;
390 // find extrapolated X and Z
391 znew = point[2] + snxt * dir[2];
392 if (TMath::Abs(znew) < fDz) {
393 Double_t dx = 0.5 * (fDx1 + fDx2) - fx * znew;
394 xnew = point[0] + snxt * dir[0];
395 if (TMath::Abs(xnew) < dx)
396 return snxt;
397 }
398 }
399 if (!in)
400 return TGeoShape::Big();
401 // Point actually inside
402 if (safz < safx && safz < safy) {
403 if (point[2] * dir[2] >= 0)
404 return TGeoShape::Big();
405 return 0.0;
406 }
407 if (safy < safx) {
408 cn = TMath::Sign(1.0, point[1]) * dir[1] + fy * dir[2];
409 if (cn >= 0)
410 return TGeoShape::Big();
411 return 0.0;
412 }
413 cn = TMath::Sign(1.0, point[0]) * dir[0] + fx * dir[2];
414 if (cn >= 0)
415 return TGeoShape::Big();
416 return 0.0;
417}
418
419////////////////////////////////////////////////////////////////////////////////
420/// Get range of shape for a given axis.
421
423{
424 xlo = 0;
425 xhi = 0;
426 Double_t dx = 0;
427 switch (iaxis) {
428 case 3:
429 xlo = -fDz;
430 xhi = fDz;
431 dx = xhi - xlo;
432 return dx;
433 }
434 return dx;
435}
436
437////////////////////////////////////////////////////////////////////////////////
438/// get the most visible corner from outside point and the normals
439
441{
442 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
443 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
444 Double_t calf = 1. / TMath::Sqrt(1.0 + fx * fx);
445 Double_t salf = calf * fx;
446 Double_t cbet = 1. / TMath::Sqrt(1.0 + fy * fy);
447 Double_t sbet = cbet * fy;
448 // check visibility of X,Y faces
449 Double_t distx = fDx1 - fx * (fDz + point[2]);
450 Double_t disty = fDy1 - fy * (fDz + point[2]);
451 memset(normals, 0, 9 * sizeof(Double_t));
452 TGeoTrd2 *trd2 = (TGeoTrd2 *)this;
453 if (point[0] > distx) {
454 // hi x face visible
455 trd2->SetShapeBit(kGeoVisX);
456 normals[0] = calf;
457 normals[2] = salf;
458 } else {
459 trd2->SetShapeBit(kGeoVisX, kFALSE);
460 normals[0] = -calf;
461 normals[2] = salf;
462 }
463 if (point[1] > disty) {
464 // hi y face visible
465 trd2->SetShapeBit(kGeoVisY);
466 normals[4] = cbet;
467 normals[5] = sbet;
468 } else {
469 trd2->SetShapeBit(kGeoVisY, kFALSE);
470 normals[4] = -cbet;
471 normals[5] = sbet;
472 }
473 if (point[2] > fDz) {
474 // hi z face visible
475 trd2->SetShapeBit(kGeoVisZ);
476 normals[8] = 1;
477 } else {
478 trd2->SetShapeBit(kGeoVisZ, kFALSE);
479 normals[8] = -1;
480 }
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// get the opposite corner of the intersected face
486
488{
489 TGeoTrd2 *trd2 = (TGeoTrd2 *)this;
490 if (inorm != 0) {
491 // change x face
492 trd2->SetShapeBit(kGeoVisX, !TestShapeBit(kGeoVisX));
493 normals[0] = -normals[0];
494 }
495 if (inorm != 1) {
496 // change y face
497 trd2->SetShapeBit(kGeoVisY, !TestShapeBit(kGeoVisY));
498 normals[4] = -normals[4];
499 }
500 if (inorm != 2) {
501 // hi z face visible
502 trd2->SetShapeBit(kGeoVisZ, !TestShapeBit(kGeoVisZ));
503 normals[8] = -normals[8];
504 }
506}
507
508////////////////////////////////////////////////////////////////////////////////
509/// Divide this trd2 shape belonging to volume "voldiv" into ndiv volumes
510/// called divname, from start position with the given step. Only Z divisions
511/// are supported. For Z divisions just return the pointer to the volume to be
512/// divided. In case a wrong division axis is supplied, returns pointer to
513/// volume that was divided.
514
517{
518 TGeoShape *shape; //--- shape to be created
519 TGeoVolume *vol; //--- division volume to be created
520 TGeoVolumeMulti *vmulti; //--- generic divided volume
521 TGeoPatternFinder *finder; //--- finder to be attached
522 TString opt = ""; //--- option to be attached
523 Double_t zmin, zmax, dx1n, dx2n, dy1n, dy2n;
524 Int_t id;
525 Double_t end = start + ndiv * step;
526 switch (iaxis) {
527 case 1: Warning("Divide", "dividing a Trd2 on X not implemented"); return nullptr;
528 case 2: Warning("Divide", "dividing a Trd2 on Y not implemented"); return nullptr;
529 case 3:
530 finder = new TGeoPatternZ(voldiv, ndiv, start, end);
532 voldiv->SetFinder(finder);
533 finder->SetDivIndex(voldiv->GetNdaughters());
534 for (id = 0; id < ndiv; id++) {
535 zmin = start + id * step;
536 zmax = start + (id + 1) * step;
537 dx1n = 0.5 * (fDx1 * (fDz - zmin) + fDx2 * (fDz + zmin)) / fDz;
538 dx2n = 0.5 * (fDx1 * (fDz - zmax) + fDx2 * (fDz + zmax)) / fDz;
539 dy1n = 0.5 * (fDy1 * (fDz - zmin) + fDy2 * (fDz + zmin)) / fDz;
540 dy2n = 0.5 * (fDy1 * (fDz - zmax) + fDy2 * (fDz + zmax)) / fDz;
541 shape = new TGeoTrd2(dx1n, dx2n, dy1n, dy2n, step / 2.);
542 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
543 vmulti->AddVolume(vol);
544 opt = "Z";
545 voldiv->AddNodeOffset(vol, id, start + step / 2 + id * step, opt.Data());
546 ((TGeoNodeOffset *)voldiv->GetNodes()->At(voldiv->GetNdaughters() - 1))->SetFinder(finder);
547 }
548 return vmulti;
549 default: Error("Divide", "Wrong axis type for division"); return nullptr;
550 }
551}
552
553////////////////////////////////////////////////////////////////////////////////
554/// Fill vector param[4] with the bounding cylinder parameters. The order
555/// is the following : Rmin, Rmax, Phi1, Phi2
556
561
562////////////////////////////////////////////////////////////////////////////////
563/// Fills real parameters of a positioned box inside this. Returns 0 if successful.
564
566{
567 dx = dy = dz = 0;
568 if (mat->IsRotation()) {
569 Error("GetFittingBox", "cannot handle parametrized rotated volumes");
570 return 1; // ### rotation not accepted ###
571 }
572 //--> translate the origin of the parametrized box to the frame of this box.
573 Double_t origin[3];
574 mat->LocalToMaster(parambox->GetOrigin(), origin);
575 if (!Contains(origin)) {
576 Error("GetFittingBox", "wrong matrix - parametrized box is outside this");
577 return 1; // ### wrong matrix ###
578 }
579 //--> now we have to get the valid range for all parametrized axis
580 Double_t dd[3];
581 dd[0] = parambox->GetDX();
582 dd[1] = parambox->GetDY();
583 dd[2] = parambox->GetDZ();
584 //-> check if Z range is fixed
585 if (dd[2] < 0) {
586 dd[2] = TMath::Min(origin[2] + fDz, fDz - origin[2]);
587 if (dd[2] < 0) {
588 Error("GetFittingBox", "wrong matrix");
589 return 1;
590 }
591 }
592 if (dd[0] >= 0 && dd[1] >= 0) {
593 dx = dd[0];
594 dy = dd[1];
595 dz = dd[2];
596 return 0;
597 }
598 //-> check now range at Z = origin[2] +/- dd[2]
599 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
600 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
601 Double_t dx0 = 0.5 * (fDx1 + fDx2);
602 Double_t dy0 = 0.5 * (fDy1 + fDy2);
603 Double_t z = origin[2] - dd[2];
604 dd[0] = dx0 - fx * z - origin[0];
605 dd[1] = dy0 - fy * z - origin[1];
606 z = origin[2] + dd[2];
607 dd[0] = TMath::Min(dd[0], dx0 - fx * z - origin[0]);
608 dd[1] = TMath::Min(dd[1], dy0 - fy * z - origin[1]);
609 if (dd[0] < 0 || dd[1] < 0) {
610 Error("GetFittingBox", "wrong matrix");
611 return 1;
612 }
613 dx = dd[0];
614 dy = dd[1];
615 dz = dd[2];
616 return 0;
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// in case shape has some negative parameters, these has to be computed
621/// in order to fit the mother
622
624{
626 return nullptr;
627 if (!mother->TestShapeBit(kGeoTrd2)) {
628 Error("GetMakeRuntimeShape", "invalid mother");
629 return nullptr;
630 }
631 Double_t dx1, dx2, dy1, dy2, dz;
632 if (fDx1 < 0)
633 dx1 = ((TGeoTrd2 *)mother)->GetDx1();
634 else
635 dx1 = fDx1;
636 if (fDx2 < 0)
637 dx2 = ((TGeoTrd2 *)mother)->GetDx2();
638 else
639 dx2 = fDx2;
640 if (fDy1 < 0)
641 dy1 = ((TGeoTrd2 *)mother)->GetDy1();
642 else
643 dy1 = fDy1;
644 if (fDy2 < 0)
645 dy2 = ((TGeoTrd2 *)mother)->GetDy2();
646 else
647 dy2 = fDy2;
648 if (fDz < 0)
649 dz = ((TGeoTrd2 *)mother)->GetDz();
650 else
651 dz = fDz;
652
653 return (new TGeoTrd2(dx1, dx2, dy1, dy2, dz));
654}
655
656////////////////////////////////////////////////////////////////////////////////
657/// print shape parameters
658
660{
661 printf("*** Shape %s: TGeoTrd2 ***\n", GetName());
662 printf(" dx1 = %11.5f\n", fDx1);
663 printf(" dx2 = %11.5f\n", fDx2);
664 printf(" dy1 = %11.5f\n", fDy1);
665 printf(" dy2 = %11.5f\n", fDy2);
666 printf(" dz = %11.5f\n", fDz);
667 printf(" Bounding box:\n");
669}
670
671////////////////////////////////////////////////////////////////////////////////
672/// computes the closest distance from given point to this shape, according
673/// to option. The matching point on the shape is stored in spoint.
674
676{
677 Double_t saf[3];
678 //--- Compute safety first
679 // check Z facettes
680 saf[0] = fDz - TMath::Abs(point[2]);
681 Double_t fx = 0.5 * (fDx1 - fDx2) / fDz;
682 Double_t calf = 1. / TMath::Sqrt(1.0 + fx * fx);
683 // check X facettes
684 Double_t distx = 0.5 * (fDx1 + fDx2) - fx * point[2];
685 if (distx < 0)
686 saf[1] = TGeoShape::Big();
687 else
688 saf[1] = (distx - TMath::Abs(point[0])) * calf;
689
690 Double_t fy = 0.5 * (fDy1 - fDy2) / fDz;
691 calf = 1. / TMath::Sqrt(1.0 + fy * fy);
692 // check Y facettes
693 distx = 0.5 * (fDy1 + fDy2) - fy * point[2];
694 if (distx < 0)
695 saf[2] = TGeoShape::Big();
696 else
697 saf[2] = (distx - TMath::Abs(point[1])) * calf;
698
699 if (in)
700 return saf[TMath::LocMin(3, saf)];
701 for (Int_t i = 0; i < 3; i++)
702 saf[i] = -saf[i];
703 return saf[TMath::LocMax(3, saf)];
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Save a primitive as a C++ statement(s) on output stream "out".
708
709void TGeoTrd2::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
710{
712 return;
713 out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
714 out << " dx1 = " << fDx1 << ";" << std::endl;
715 out << " dx2 = " << fDx2 << ";" << std::endl;
716 out << " dy1 = " << fDy1 << ";" << std::endl;
717 out << " dy2 = " << fDy2 << ";" << std::endl;
718 out << " dz = " << fDZ << ";" << std::endl;
719 out << " TGeoShape *" << GetPointerName() << " = new TGeoTrd2(\"" << GetName() << "\", dx1,dx2,dy1,dy2,dz);"
720 << std::endl;
722}
723
724////////////////////////////////////////////////////////////////////////////////
725/// set arb8 params in one step :
726
728{
729 fDx1 = param[0];
730 fDx2 = param[1];
731 fDy1 = param[2];
732 fDy2 = param[3];
733 fDz = param[4];
734 ComputeBBox();
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// create trd2 mesh points
739
741{
742 if (!points)
743 return;
744 points[0] = -fDx1;
745 points[1] = -fDy1;
746 points[2] = -fDz;
747 points[3] = -fDx1;
748 points[4] = fDy1;
749 points[5] = -fDz;
750 points[6] = fDx1;
751 points[7] = fDy1;
752 points[8] = -fDz;
753 points[9] = fDx1;
754 points[10] = -fDy1;
755 points[11] = -fDz;
756 points[12] = -fDx2;
757 points[13] = -fDy2;
758 points[14] = fDz;
759 points[15] = -fDx2;
760 points[16] = fDy2;
761 points[17] = fDz;
762 points[18] = fDx2;
763 points[19] = fDy2;
764 points[20] = fDz;
765 points[21] = fDx2;
766 points[22] = -fDy2;
767 points[23] = fDz;
768}
769
770////////////////////////////////////////////////////////////////////////////////
771/// create trd2 mesh points
772
774{
775 if (!points)
776 return;
777 points[0] = -fDx1;
778 points[1] = -fDy1;
779 points[2] = -fDz;
780 points[3] = -fDx1;
781 points[4] = fDy1;
782 points[5] = -fDz;
783 points[6] = fDx1;
784 points[7] = fDy1;
785 points[8] = -fDz;
786 points[9] = fDx1;
787 points[10] = -fDy1;
788 points[11] = -fDz;
789 points[12] = -fDx2;
790 points[13] = -fDy2;
791 points[14] = fDz;
792 points[15] = -fDx2;
793 points[16] = fDy2;
794 points[17] = fDz;
795 points[18] = fDx2;
796 points[19] = fDy2;
797 points[20] = fDz;
798 points[21] = fDx2;
799 points[22] = -fDy2;
800 points[23] = fDz;
801}
802
803////////////////////////////////////////////////////////////////////////////////
804/// set vertex of a corner according to visibility flags
805
807{
808 if (TestShapeBit(kGeoVisX)) {
809 if (TestShapeBit(kGeoVisZ)) {
810 vertex[0] = fDx2;
811 vertex[2] = fDz;
812 vertex[1] = (TestShapeBit(kGeoVisY)) ? fDy2 : -fDy2;
813 } else {
814 vertex[0] = fDx1;
815 vertex[2] = -fDz;
816 vertex[1] = (TestShapeBit(kGeoVisY)) ? fDy1 : -fDy1;
817 }
818 } else {
819 if (TestShapeBit(kGeoVisZ)) {
820 vertex[0] = -fDx2;
821 vertex[2] = fDz;
822 vertex[1] = (TestShapeBit(kGeoVisY)) ? fDy2 : -fDy2;
823 } else {
824 vertex[0] = -fDx1;
825 vertex[2] = -fDz;
826 vertex[1] = (TestShapeBit(kGeoVisY)) ? fDy1 : -fDy1;
827 }
828 }
829}
830
831////////////////////////////////////////////////////////////////////////////////
832/// fill size of this 3-D object
833
835{
837}
838
839////////////////////////////////////////////////////////////////////////////////
840/// Check the inside status for each of the points in the array.
841/// Input: Array of point coordinates + vector size
842/// Output: Array of Booleans for the inside of each point
843
845{
846 for (Int_t i = 0; i < vecsize; i++)
847 inside[i] = Contains(&points[3 * i]);
848}
849
850////////////////////////////////////////////////////////////////////////////////
851/// Compute the normal for an array o points so that norm.dot.dir is positive
852/// Input: Arrays of point coordinates and directions + vector size
853/// Output: Array of normal directions
854
856{
857 for (Int_t i = 0; i < vecsize; i++)
858 ComputeNormal(&points[3 * i], &dirs[3 * i], &norms[3 * i]);
859}
860
861////////////////////////////////////////////////////////////////////////////////
862/// Compute distance from array of input points having directions specified by dirs. Store output in dists
863
865 Double_t *step) const
866{
867 for (Int_t i = 0; i < vecsize; i++)
868 dists[i] = DistFromInside(&points[3 * i], &dirs[3 * i], 3, step[i]);
869}
870
871////////////////////////////////////////////////////////////////////////////////
872/// Compute distance from array of input points having directions specified by dirs. Store output in dists
873
875 Double_t *step) const
876{
877 for (Int_t i = 0; i < vecsize; i++)
878 dists[i] = DistFromOutside(&points[3 * i], &dirs[3 * i], 3, step[i]);
879}
880
881////////////////////////////////////////////////////////////////////////////////
882/// Compute safe distance from each of the points in the input array.
883/// Input: Array of point coordinates, array of statuses for these points, size of the arrays
884/// Output: Safety values
885
886void TGeoTrd2::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
887{
888 for (Int_t i = 0; i < vecsize; i++)
889 safe[i] = Safety(&points[3 * i], inside[i]);
890}
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGeoManager * gGeoManager
Box class.
Definition TGeoBBox.h:17
Double_t fDX
Definition TGeoBBox.h:20
void GetBoundingCylinder(Double_t *param) const override
Fill vector param[4] with the bounding cylinder parameters.
Definition TGeoBBox.cxx:600
Double_t fOrigin[3]
Definition TGeoBBox.h:23
void InspectShape() const override
Prints shape parameters.
Definition TGeoBBox.cxx:810
void Sizeof3D() const override
Double_t fDY
Definition TGeoBBox.h:21
Double_t fDZ
Definition TGeoBBox.h:22
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
Geometrical transformation package.
Definition TGeoMatrix.h:38
Node containing an offset.
Definition TGeoNode.h:184
base finder class for patterns. A pattern is specifying a division type
a Z axis divison pattern
Base abstract class for all shapes.
Definition TGeoShape.h:25
static Double_t Big()
Definition TGeoShape.h:94
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
const char * GetPointerName() const
Provide a pointer name containing uid.
const char * GetName() const override
Get the shape name.
@ kGeoSavePrimitive
Definition TGeoShape.h:64
@ kGeoRunTimeShape
Definition TGeoShape.h:40
static Double_t Tolerance()
Definition TGeoShape.h:97
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:175
A trapezoid with only X varying with Z.
Definition TGeoTrd2.h:17
void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Definition TGeoTrd2.cxx:874
Double_t fDx2
Definition TGeoTrd2.h:21
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Compute normal to closest surface from POINT.
Definition TGeoTrd2.cxx:140
Int_t GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const override
Fills real parameters of a positioned box inside this. Returns 0 if successful.
Definition TGeoTrd2.cxx:565
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from outside point to surface of the trd2 Boundary safe algorithm.
Definition TGeoTrd2.cxx:286
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
computes the closest distance from given point to this shape, according to option.
Definition TGeoTrd2.cxx:675
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
Definition TGeoTrd2.cxx:709
Double_t fDy1
Definition TGeoTrd2.h:22
void SetPoints(Double_t *points) const override
create trd2 mesh points
Definition TGeoTrd2.cxx:740
void Sizeof3D() const override
fill size of this 3-D object
Definition TGeoTrd2.cxx:834
Double_t Capacity() const override
Computes capacity of the shape in [length^3].
Definition TGeoTrd2.cxx:120
Double_t fDx1
Definition TGeoTrd2.h:20
void ComputeBBox() override
compute bounding box for a trd2
Definition TGeoTrd2.cxx:129
Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const override
Get range of shape for a given axis.
Definition TGeoTrd2.cxx:422
void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const override
Compute safe distance from each of the points in the input array.
Definition TGeoTrd2.cxx:886
void SetDimensions(Double_t *param) override
set arb8 params in one step :
Definition TGeoTrd2.cxx:727
void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Definition TGeoTrd2.cxx:864
TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step) override
Divide this trd2 shape belonging to volume "voldiv" into ndiv volumes called divname,...
Definition TGeoTrd2.cxx:516
Double_t fDy2
Definition TGeoTrd2.h:23
void GetBoundingCylinder(Double_t *param) const override
Fill vector param[4] with the bounding cylinder parameters.
Definition TGeoTrd2.cxx:557
void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize) override
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
Definition TGeoTrd2.cxx:855
void GetOppositeCorner(const Double_t *point, Int_t inorm, Double_t *vertex, Double_t *normals) const
get the opposite corner of the intersected face
Definition TGeoTrd2.cxx:487
void SetVertex(Double_t *vertex) const
set vertex of a corner according to visibility flags
Definition TGeoTrd2.cxx:806
Bool_t Contains(const Double_t *point) const override
test if point is inside this shape check Z range
Definition TGeoTrd2.cxx:194
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from inside point to surface of the trd2 Boundary safe algorithm.
Definition TGeoTrd2.cxx:214
void InspectShape() const override
print shape parameters
Definition TGeoTrd2.cxx:659
void GetVisibleCorner(const Double_t *point, Double_t *vertex, Double_t *normals) const
get the most visible corner from outside point and the normals
Definition TGeoTrd2.cxx:440
void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const override
Check the inside status for each of the points in the array.
Definition TGeoTrd2.cxx:844
TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const override
in case shape has some negative parameters, these has to be computed in order to fit the mother
Definition TGeoTrd2.cxx:623
Double_t fDz
Definition TGeoTrd2.h:24
~TGeoTrd2() override
destructor
Definition TGeoTrd2.cxx:115
TGeoTrd2()
dummy ctor
Definition TGeoTrd2.cxx:51
Volume families.
Definition TGeoVolume.h:266
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:43
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
Long64_t LocMin(Long64_t n, const T *a)
Returns index of array with the minimum element.
Definition TMath.h:993
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
T1 Sign(T1 a, T2 b)
Returns a value with the magnitude of a and the sign of b.
Definition TMathBase.h:176
Long64_t LocMax(Long64_t n, const T *a)
Returns index of array with the maximum element.
Definition TMath.h:1099
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124