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