Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoXtru.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Mihaela Gheata 24/01/04
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGeoXtru
13\ingroup Shapes_classes
14A TGeoXtru shape is represented by the extrusion of an arbitrary
15polygon with fixed outline between several Z sections. Each Z section is
16a scaled version of the same "blueprint" polygon. Different global XY
17translations are allowed from section to section. Corresponding polygon
18vertices from consecutive sections are connected.
19
20An extruded polygon can be created using the constructor:
21
22~~~ {.cpp}
23TGeoXtru::TGeoXtru(Int_t nplanes);
24~~~
25
26 - `nplanes: `number of Z sections (minimum 2)
27
28Begin_Macro
29{
30 new TGeoManager("xtru", "poza12");
31 TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
32 TGeoMedium *med = new TGeoMedium("MED",1,mat);
33 TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
34 gGeoManager->SetTopVolume(top);
35 TGeoVolume *vol = gGeoManager->MakeXtru("XTRU",med,4);
36 TGeoXtru *xtru = (TGeoXtru*)vol->GetShape();
37 Double_t x[8] = {-30,-30,30,30,15,15,-15,-15};
38 Double_t y[8] = {-30,30,30,-30,-30,15,15,-30};
39 xtru->DefinePolygon(8,x,y);
40 xtru->DefineSection(0,-40, -20., 10., 1.5);
41 xtru->DefineSection(1, 10, 0., 0., 0.5);
42 xtru->DefineSection(2, 10, 0., 0., 0.7);
43 xtru->DefineSection(3, 40, 10., 20., 0.9);
44 top->AddNode(vol,1);
45 gGeoManager->CloseGeometry();
46 gGeoManager->SetNsegments(80);
47 top->Draw();
48 if (gPad) {
49 TView *view = gPad->GetView();
50 if (view) view->ShowAxis();
51 }
52}
53End_Macro
54
55The lists of X and Y positions for all vertices have to be provided for
56the "blueprint" polygon:
57
58~~~{.cpp}
59TGeoXtru::DefinePolygon (Int_t nvertices, Double_t *xv,
60Double_t *yv);
61~~~
62
63 - `nvertices: `number of vertices of the polygon
64 - `xv,yv: `arrays of X and Y coordinates for polygon vertices
65
66The method creates an object of the class **`TGeoPolygon`** for which
67the convexity is automatically determined . The polygon is decomposed
68into convex polygons if needed.
69
70Next step is to define the Z positions for each section plane as well as
71the XY offset and scaling for the corresponding polygons.
72
73~~~{.cpp}
74TGeoXtru::DefineSection(Int_t snum,Double_t zsection,Double_t x0,
75Double_t y0, Double_t scale);
76~~~
77
78 - `snum: `Z section index (0, nplanes-1). The section with
79 `snum = nplanes-1` must be defined last and triggers the computation
80 of the bounding box for the whole shape
81 - `zsection: `Z position of section `snum`. Sections must be defined
82 in increasing order of Z (e.g. `snum=0` correspond to the minimum Z
83 and `snum=nplanes-1` to the maximum one).
84 - `x0,y0: `offset of section `snum` with respect to the local shape
85 reference frame `T`
86 - `scale: `factor that multiplies the X/Y coordinates of each vertex
87 of the polygon at section `snum`:
88 - `x[ivert] = x0 + scale*xv[ivert]`
89 - `y[ivert] = y0 + scale*yv[ivert]`
90*/
91
92#include "TGeoXtru.h"
93
94#include <iostream>
95
96#include "TBuffer3D.h"
97#include "TBuffer3DTypes.h"
98#include "TMath.h"
99
100#include "TVirtualGeoPainter.h"
101#include "TGeoManager.h"
102#include "TGeoVolume.h"
103#include "TGeoPolygon.h"
104
105std::atomic<UInt_t> TGeoXtru::fgInstanceCount{0};
106
108 std::unique_ptr<Double_t[]> fXc;
109 std::unique_ptr<Double_t[]> fYc;
110 std::unique_ptr<TGeoPolygon> fPoly;
111
112 explicit OwnedThreadData_t(std::size_t size) : fXc(new Double_t[size]), fYc(new Double_t[size]) {}
113};
114
115////////////////////////////////////////////////////////////////////////////////
116/// (Re)build the per-thread scratch state for this shape into the given slot.
117/// Cold path: runs once per (thread, shape, generation).
118
120{
121 auto data = std::make_unique<OwnedThreadData_t>(fNvert);
122 memcpy(data->fXc.get(), fX, fNvert * sizeof(Double_t));
123 memcpy(data->fYc.get(), fY, fNvert * sizeof(Double_t));
124 data->fPoly = std::make_unique<TGeoPolygon>(fNvert);
125 data->fPoly->SetXY(data->fXc.get(), data->fYc.get());
126 data->fPoly->FinishPolygon();
127 Double_t *xc = data->fXc.get();
128 Double_t *yc = data->fYc.get();
129 TGeoPolygon *poly = data->fPoly.get();
130
131 std::lock_guard<std::mutex> guard(fOwnedDataMutex);
132 fOwnedData.push_back(std::move(data));
133 td.fSeg = 0;
134 td.fIz = 0;
135 td.fXc = xc;
136 td.fYc = yc;
137 td.fPoly = poly;
138 td.fInitGen = fGeneration.load(std::memory_order_acquire);
139 // The polygon is identical in every thread, so report an illegal one exactly once
140 // instead of once per thread (previously: only for thread id 0).
141 if (td.fPoly->IsIllegalCheck() && !fIllegalChecked.exchange(kTRUE, std::memory_order_relaxed))
142 Error("DefinePolygon", "Shape %s of type XTRU has an illegal polygon.", GetName());
143}
144
145////////////////////////////////////////////////////////////////////////////////
146/// Release the large scratch buffers. Navigation using this shape must not be active.
147
149{
150 std::lock_guard<std::mutex> guard(fOwnedDataMutex);
151 fOwnedData.clear();
152 fGeneration.fetch_add(1, std::memory_order_release);
153 fIllegalChecked.store(kFALSE, std::memory_order_relaxed);
154}
155
156////////////////////////////////////////////////////////////////////////////////
157/// Set current z-plane.
158
160{
161 GetThreadData().fIz = iz;
162}
163////////////////////////////////////////////////////////////////////////////////
164/// Set current segment.
165
170
171////////////////////////////////////////////////////////////////////////////////
172/// dummy ctor
173
175 : TGeoBBox(),
176 fNvert(0),
177 fNz(0),
178 fZcurrent(0.),
179 fX(nullptr),
180 fY(nullptr),
181 fZ(nullptr),
182 fScale(nullptr),
183 fX0(nullptr),
184 fY0(nullptr)
185{
187}
188
189////////////////////////////////////////////////////////////////////////////////
190/// Default constructor
191
193 : TGeoBBox(0, 0, 0),
194 fNvert(0),
195 fNz(nz),
196 fZcurrent(0.),
197 fX(nullptr),
198 fY(nullptr),
199 fZ(new Double_t[nz]),
200 fScale(new Double_t[nz]),
201 fX0(new Double_t[nz]),
202 fY0(new Double_t[nz])
203{
205 if (nz < 2) {
206 Error("ctor", "Cannot create TGeoXtru %s with less than 2 Z planes", GetName());
208 return;
209 }
210}
211
212////////////////////////////////////////////////////////////////////////////////
213/// Default constructor in GEANT3 style
214/// - param[0] = nz // number of z planes
215///
216/// - param[1] = z1 // Z position of first plane
217/// - param[2] = x1 // X position of first plane
218/// - param[3] = y1 // Y position of first plane
219/// - param[4] = scale1 // scale factor for first plane
220/// ...
221/// - param[4*(nz-1]+1] = zn
222/// - param[4*(nz-1)+2] = xn
223/// - param[4*(nz-1)+3] = yn
224/// - param[4*(nz-1)+4] = scalen
225
227 : TGeoBBox(0, 0, 0),
228 fNvert(0),
229 fNz(0),
230 fZcurrent(0.),
231 fX(nullptr),
232 fY(nullptr),
233 fZ(nullptr),
234 fScale(nullptr),
235 fX0(nullptr),
236 fY0(nullptr)
237{
239 SetDimensions(param);
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// destructor
244
246{
247 if (fX) {
248 delete[] fX;
249 fX = nullptr;
250 }
251 if (fY) {
252 delete[] fY;
253 fY = nullptr;
254 }
255 if (fZ) {
256 delete[] fZ;
257 fZ = nullptr;
258 }
259 if (fScale) {
260 delete[] fScale;
261 fScale = nullptr;
262 }
263 if (fX0) {
264 delete[] fX0;
265 fX0 = nullptr;
266 }
267 if (fY0) {
268 delete[] fY0;
269 fY0 = nullptr;
270 }
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// Compute capacity [length^3] of this shape.
276
278{
280 Int_t iz;
281 Double_t capacity = 0;
283 TGeoXtru *xtru = (TGeoXtru *)this;
284 xtru->SetCurrentVertices(0., 0., 1.);
285 area = td.fPoly->Area();
286 for (iz = 0; iz < fNz - 1; iz++) {
287 dz = fZ[iz + 1] - fZ[iz];
289 continue;
290 sc1 = fScale[iz];
291 sc2 = fScale[iz + 1];
292 capacity += (area * dz / 3.) * (sc1 * sc1 + sc1 * sc2 + sc2 * sc2);
293 }
294 return capacity;
295}
296
297////////////////////////////////////////////////////////////////////////////////
298/// compute bounding box of the pcon
299
301{
303 if (!fX || !fZ || !fNvert) {
304 Error("ComputeBBox", "In shape %s polygon not defined", GetName());
306 return;
307 }
308 Double_t zmin = fZ[0];
309 Double_t zmax = fZ[fNz - 1];
314 for (Int_t i = 0; i < fNz; i++) {
315 SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
316 for (Int_t j = 0; j < fNvert; j++) {
317 if (td.fXc[j] < xmin)
318 xmin = td.fXc[j];
319 if (td.fXc[j] > xmax)
320 xmax = td.fXc[j];
321 if (td.fYc[j] < ymin)
322 ymin = td.fYc[j];
323 if (td.fYc[j] > ymax)
324 ymax = td.fYc[j];
325 }
326 }
327 fOrigin[0] = 0.5 * (xmin + xmax);
328 fOrigin[1] = 0.5 * (ymin + ymax);
329 fOrigin[2] = 0.5 * (zmin + zmax);
330 fDX = 0.5 * (xmax - xmin);
331 fDY = 0.5 * (ymax - ymin);
332 fDZ = 0.5 * (zmax - zmin);
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Compute normal to closest surface from POINT.
337
338void TGeoXtru::ComputeNormal(const Double_t * /*point*/, const Double_t *dir, Double_t *norm) const
339{
341 if (td.fIz < 0) {
342 memset(norm, 0, 3 * sizeof(Double_t));
343 norm[2] = (dir[2] > 0) ? 1 : -1;
344 return;
345 }
346 Double_t vert[12];
347 GetPlaneVertices(td.fIz, td.fSeg, vert);
349 Double_t ndotd = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
350 if (ndotd < 0) {
351 norm[0] = -norm[0];
352 norm[1] = -norm[1];
353 norm[2] = -norm[2];
354 }
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// test if point is inside this shape
359
361{
363 // Check Z range
364 TGeoXtru *xtru = (TGeoXtru *)this;
365 if (point[2] < fZ[0])
366 return kFALSE;
367 if (point[2] > fZ[fNz - 1])
368 return kFALSE;
369 Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
370 if (iz < 0 || iz == fNz - 1)
371 return kFALSE;
372 if (TGeoShape::IsSameWithinTolerance(point[2], fZ[iz])) {
373 xtru->SetIz(-1);
374 xtru->SetCurrentVertices(fX0[iz], fY0[iz], fScale[iz]);
375 if (td.fPoly->Contains(point))
376 return kTRUE;
377 if (iz > 1 && TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz - 1])) {
378 xtru->SetCurrentVertices(fX0[iz - 1], fY0[iz - 1], fScale[iz - 1]);
379 return td.fPoly->Contains(point);
380 } else if (iz < fNz - 2 && TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz + 1])) {
381 xtru->SetCurrentVertices(fX0[iz + 1], fY0[iz + 1], fScale[iz + 1]);
382 return td.fPoly->Contains(point);
383 }
384 }
385 xtru->SetCurrentZ(point[2], iz);
386 if (TMath::Abs(point[2] - fZ[iz]) < TGeoShape::Tolerance() ||
387 TMath::Abs(fZ[iz + 1] - point[2]) < TGeoShape::Tolerance())
388 xtru->SetIz(-1);
389 // Now td.fXc,fYc represent the vertices of the section at point[2]
390 return td.fPoly->Contains(point);
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// compute closest distance from point px,py to each corner
395
401
402////////////////////////////////////////////////////////////////////////////////
403/// Draw the section polygon.
404
406{
408 if (td.fPoly)
409 td.fPoly->Draw(option);
410}
411
412////////////////////////////////////////////////////////////////////////////////
413/// Compute distance to a Xtru lateral surface.
414
416 Bool_t in) const
417{
420 Double_t vert[12];
421 Double_t norm[3];
423 Double_t pt[3];
425 if (TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz + 1]) && !in) {
426 TGeoXtru *xtru = (TGeoXtru *)this;
427 snext = (fZ[iz] - point[2]) / dir[2];
428 if (snext < 0)
429 return TGeoShape::Big();
430 pt[0] = point[0] + snext * dir[0];
431 pt[1] = point[1] + snext * dir[1];
432 pt[2] = point[2] + snext * dir[2];
433 if (dir[2] < 0.)
434 xtru->SetCurrentVertices(fX0[iz], fY0[iz], fScale[iz]);
435 else
436 xtru->SetCurrentVertices(fX0[iz + 1], fY0[iz + 1], fScale[iz + 1]);
437 if (!td.fPoly->Contains(pt))
438 return TGeoShape::Big();
439 return snext;
440 }
443 Double_t ndotd = norm[0] * dir[0] + norm[1] * dir[1] + norm[2] * dir[2];
444 if (in) {
445 if (ndotd <= 0)
446 return TGeoShape::Big();
447 safe = (vert[0] - point[0]) * norm[0] + (vert[1] - point[1]) * norm[1] + (vert[2] - point[2]) * norm[2];
448 if (safe < -1.E-8)
449 return TGeoShape::Big(); // direction outwards plane
450 } else {
451 ndotd = -ndotd;
452 if (ndotd <= 0)
453 return TGeoShape::Big();
454 safe = (point[0] - vert[0]) * norm[0] + (point[1] - vert[1]) * norm[1] + (point[2] - vert[2]) * norm[2];
455 if (safe < -1.E-8)
456 return TGeoShape::Big(); // direction outwards plane
457 }
458 snext = safe / ndotd;
459 if (snext > stepmax)
460 return TGeoShape::Big();
461 if (fZ[iz] < fZ[iz + 1]) {
462 znew = point[2] + snext * dir[2];
463 if (znew < fZ[iz])
464 return TGeoShape::Big();
465 if (znew > fZ[iz + 1])
466 return TGeoShape::Big();
467 }
468 pt[0] = point[0] + snext * dir[0];
469 pt[1] = point[1] + snext * dir[1];
470 pt[2] = point[2] + snext * dir[2];
472 return TGeoShape::Big();
473 return TMath::Max(snext, 0.);
474}
475
476////////////////////////////////////////////////////////////////////////////////
477/// compute distance from inside point to surface of the polycone
478/// locate Z segment
479
482{
484 if (iact < 3 && safe) {
485 *safe = Safety(point, kTRUE);
486 if (iact == 0)
487 return TGeoShape::Big();
488 if (iact == 1 && step < *safe)
489 return TGeoShape::Big();
490 }
491 TGeoXtru *xtru = (TGeoXtru *)this;
492 Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
493 if (iz < 0) {
494 if (dir[2] <= 0) {
495 xtru->SetIz(-1);
496 return 0.;
497 }
498 iz = 0;
499 }
500 if (iz == fNz - 1) {
501 if (dir[2] >= 0) {
502 xtru->SetIz(-1);
503 return 0.;
504 }
505 iz--;
506 } else {
507 if (iz > 0) {
508 if (TGeoShape::IsSameWithinTolerance(point[2], fZ[iz])) {
509 if (TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz + 1]) && dir[2] < 0)
510 iz++;
511 else if (TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz - 1]) && dir[2] > 0)
512 iz--;
513 }
514 }
515 }
516 Bool_t convex = td.fPoly->IsConvex();
517 // Double_t stepmax = step;
518 // if (stepmax>TGeoShape::Big()) stepmax = TGeoShape::Big();
520 Double_t dist, sz;
521 Double_t pt[3];
522 Int_t iv, ipl, inext;
523 // we treat the special case when dir[2]=0
524 if (TGeoShape::IsSameWithinTolerance(dir[2], 0)) {
525 for (iv = 0; iv < fNvert; iv++) {
526 xtru->SetIz(-1);
527 dist = DistToPlane(point, dir, iz, iv, TGeoShape::Big(), kTRUE);
528 if (dist < snext) {
529 snext = dist;
530 xtru->SetSeg(iv);
531 if (convex)
532 return snext;
533 }
534 }
535 if (snext < 1.E10)
536 return snext;
537 return TGeoShape::Tolerance();
538 }
539
540 // normal case
541 Int_t incseg = (dir[2] > 0) ? 1 : -1;
542 Int_t iznext = iz;
544 while (iz >= 0 && iz < fNz - 1) {
545 // find the distance to current segment end Z surface
546 ipl = iz + ((incseg + 1) >> 1); // next plane
547 inext = ipl + incseg; // next next plane
548 sz = (fZ[ipl] - point[2]) / dir[2];
549 if (sz < snext) {
550 iznext += incseg;
551 // we cross the next Z section before stepmax
552 pt[0] = point[0] + sz * dir[0];
553 pt[1] = point[1] + sz * dir[1];
554 xtru->SetCurrentVertices(fX0[ipl], fY0[ipl], fScale[ipl]);
555 if (td.fPoly->Contains(pt)) {
556 // ray gets through next polygon - is it the last one?
557 if (ipl == 0 || ipl == fNz - 1) {
558 xtru->SetIz(-1);
559 if (convex)
560 return sz;
561 zexit = kTRUE;
562 snext = sz;
563 }
564 // maybe a Z discontinuity - check this
566 xtru->SetCurrentVertices(fX0[inext], fY0[inext], fScale[inext]);
567 // if we do not cross the next polygone, we are out
568 if (!td.fPoly->Contains(pt)) {
569 xtru->SetIz(-1);
570 if (convex)
571 return sz;
572 zexit = kTRUE;
573 snext = sz;
574 } else {
575 iznext = inext;
576 }
577 }
578 }
579 } else {
580 iznext = fNz - 1; // stop
581 }
582 // ray may cross the lateral surfaces of section iz
583 for (iv = 0; iv < fNvert; iv++) {
584 dist = DistToPlane(point, dir, iz, iv, TGeoShape::Big(), kTRUE);
585 if (dist < snext) {
586 xtru->SetIz(iz);
587 xtru->SetSeg(iv);
588 snext = dist;
589 if (convex)
590 return snext;
591 zexit = kTRUE;
592 }
593 }
594 if (zexit)
595 return snext;
596 iz = iznext;
597 }
598 return TGeoShape::Tolerance();
599}
600
601////////////////////////////////////////////////////////////////////////////////
602/// compute distance from outside point to surface of the tube
603/// Warning("DistFromOutside", "not implemented");
604
607{
609 if (iact < 3 && safe) {
610 *safe = Safety(point, kTRUE);
611 if (iact == 0)
612 return TGeoShape::Big();
613 if (iact == 1 && step < *safe)
614 return TGeoShape::Big();
615 }
616 // Check if the bounding box is crossed within the requested distance
617 Double_t sdist = TGeoBBox::DistFromOutside(point, dir, fDX, fDY, fDZ, fOrigin, step);
618 if (sdist >= step)
619 return TGeoShape::Big();
620 Double_t stepmax = step;
621 if (stepmax > TGeoShape::Big())
623 Double_t snext = 0.;
624 Int_t i, iv;
625 Double_t pt[3];
626 memcpy(pt, point, 3 * sizeof(Double_t));
627 TGeoXtru *xtru = (TGeoXtru *)this;
628 // We might get out easy with Z checks
629 Int_t iz = TMath::BinarySearch(fNz, fZ, point[2]);
630 if (iz < 0) {
631 if (dir[2] <= 0)
632 return TGeoShape::Big();
633 // propagate to first Z plane
634 snext = (fZ[0] - point[2]) / dir[2];
635 if (snext > stepmax)
636 return TGeoShape::Big();
637 for (i = 0; i < 3; i++)
638 pt[i] = point[i] + snext * dir[i];
639 xtru->SetCurrentVertices(fX0[0], fY0[0], fScale[0]);
640 if (td.fPoly->Contains(pt)) {
641 xtru->SetIz(-1);
642 return snext;
643 }
644 iz = 0; // valid starting value = first segment
645 stepmax -= snext;
646 } else {
647 if (iz == fNz - 1) {
648 if (dir[2] >= 0)
649 return TGeoShape::Big();
650 // propagate to last Z plane
651 snext = (fZ[fNz - 1] - point[2]) / dir[2];
652 if (snext > stepmax)
653 return TGeoShape::Big();
654 for (i = 0; i < 3; i++)
655 pt[i] = point[i] + snext * dir[i];
656 xtru->SetCurrentVertices(fX0[fNz - 1], fY0[fNz - 1], fScale[fNz - 1]);
657 if (td.fPoly->Contains(pt)) {
658 xtru->SetIz(-1);
659 return snext;
660 }
661 iz = fNz - 2; // valid value = last segment
662 stepmax -= snext;
663 }
664 }
665 // Check if the bounding box is missed by the track
666 if (!TGeoBBox::Contains(pt)) {
667 Double_t dist = TGeoBBox::DistFromOutside(pt, dir, 3);
668 if (dist > stepmax)
669 return TGeoShape::Big();
670 if (dist > 1E-6)
671 dist -= 1E-6; // decrease snext to make sure we do not cross the xtru
672 else
673 dist = 0;
674 for (i = 0; i < 3; i++)
675 pt[i] += dist * dir[i]; // we are now closer
676 iz = TMath::BinarySearch(fNz, fZ, pt[2]);
677 if (iz < 0)
678 iz = 0;
679 else if (iz == fNz - 1)
680 iz = fNz - 2;
681 snext += dist;
682 stepmax -= dist;
683 }
684 // not the case - we have to do some work...
685 // Start tracking from current iz
686 // - first solve particular case dir[2]=0
687 Bool_t convex = td.fPoly->IsConvex();
688 Bool_t hit = kFALSE;
689 if (TGeoShape::IsSameWithinTolerance(dir[2], 0)) {
690 // loop lateral planes to see if we cross something
691 xtru->SetIz(iz);
692 for (iv = 0; iv < fNvert; iv++) {
693 Double_t dist = DistToPlane(pt, dir, iz, iv, stepmax, kFALSE);
694 if (dist < stepmax) {
695 xtru->SetSeg(iv);
696 if (convex)
697 return (snext + dist);
698 stepmax = dist;
699 hit = kTRUE;
700 }
701 }
702 if (hit)
703 return (snext + stepmax);
704 return TGeoShape::Big();
705 }
706 // general case
707 Int_t incseg = (dir[2] > 0) ? 1 : -1;
708 while (iz >= 0 && iz < fNz - 1) {
709 // compute distance to lateral planes
710 xtru->SetIz(iz);
711 if (TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz + 1]))
712 xtru->SetIz(-1);
713 for (iv = 0; iv < fNvert; iv++) {
714 Double_t dist = DistToPlane(pt, dir, iz, iv, stepmax, kFALSE);
715 if (dist < stepmax) {
716 // HIT
717 xtru->SetSeg(iv);
718 if (convex)
719 return (snext + dist);
720 stepmax = dist;
721 hit = kTRUE;
722 }
723 }
724 if (hit)
725 return (snext + stepmax);
726 iz += incseg;
727 }
728 return TGeoShape::Big();
729}
730
731////////////////////////////////////////////////////////////////////////////////
732/// Creates the polygon representing the blueprint of any Xtru section.
733/// - nvert = number of vertices >2
734/// - xv[nvert] = array of X vertex positions
735/// - yv[nvert] = array of Y vertex positions
736///
737/// *NOTE* should be called before DefineSection or ctor with 'param'
738
740{
741 if (nvert < 3) {
742 Error("DefinePolygon", "In shape %s cannot create polygon with less than 3 vertices", GetName());
744 return kFALSE;
745 }
746 for (Int_t i = 0; i < nvert - 1; i++) {
747 for (Int_t j = i + 1; j < nvert; j++) {
749 Error("DefinePolygon", "In shape %s 2 vertices cannot be identical", GetName());
751 // return kFALSE;
752 }
753 }
754 }
755 fNvert = nvert;
756 if (fX)
757 delete[] fX;
758 fX = new Double_t[nvert];
759 if (fY)
760 delete[] fY;
761 fY = new Double_t[nvert];
762 memcpy(fX, xv, nvert * sizeof(Double_t));
763 memcpy(fY, yv, nvert * sizeof(Double_t));
764
766
767 return kTRUE;
768}
769
770////////////////////////////////////////////////////////////////////////////////
771/// defines z position of a section plane, rmin and rmax at this z.
772
774{
775 if ((snum < 0) || (snum >= fNz))
776 return;
777 fZ[snum] = z;
778 fX0[snum] = x0;
779 fY0[snum] = y0;
780 fScale[snum] = scale;
781 if (snum) {
782 if (fZ[snum] < fZ[snum - 1]) {
783 Warning("DefineSection",
784 "In shape: %s, Z position of section "
785 "%i, z=%e, not in increasing order, %i, z=%e",
786 GetName(), snum, fZ[snum], snum - 1, fZ[snum - 1]);
787 return;
788 }
789 }
790 if (snum == (fNz - 1)) {
791 ComputeBBox();
793 InspectShape();
794 }
795}
796
797////////////////////////////////////////////////////////////////////////////////
798/// Return the Z coordinate for segment ipl.
799
801{
802 if (ipl < 0 || ipl > (fNz - 1)) {
803 Error("GetZ", "In shape %s, ipl=%i out of range (0,%i)", GetName(), ipl, fNz - 1);
804 return 0.;
805 }
806 return fZ[ipl];
807}
808////////////////////////////////////////////////////////////////////////////////
809/// Returns normal vector to the planar quadrilateral defined by vector VERT.
810/// The normal points outwards the xtru.
811
813{
814 Double_t cross = 0.;
815 Double_t v1[3], v2[3];
816 v1[0] = vert[9] - vert[0];
817 v1[1] = vert[10] - vert[1];
818 v1[2] = vert[11] - vert[2];
819 v2[0] = vert[3] - vert[0];
820 v2[1] = vert[4] - vert[1];
821 v2[2] = vert[5] - vert[2];
822 norm[0] = v1[1] * v2[2] - v1[2] * v2[1];
823 cross += norm[0] * norm[0];
824 norm[1] = v1[2] * v2[0] - v1[0] * v2[2];
825 cross += norm[1] * norm[1];
826 norm[2] = v1[0] * v2[1] - v1[1] * v2[0];
827 cross += norm[2] * norm[2];
828 if (cross < TGeoShape::Tolerance())
829 return;
830 cross = 1. / TMath::Sqrt(cross);
831 for (Int_t i = 0; i < 3; i++)
832 norm[i] *= cross;
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1)
837/// and polygon vertices (ivert, ivert+1). No range check.
838
840{
842 Double_t x, y, z1, z2;
843 Int_t iv1 = (ivert + 1) % fNvert;
844 Int_t icrt = 0;
845 z1 = fZ[iz];
846 z2 = fZ[iz + 1];
847 if (td.fPoly->IsClockwise()) {
848 x = fX[ivert] * fScale[iz] + fX0[iz];
849 y = fY[ivert] * fScale[iz] + fY0[iz];
850 vert[icrt++] = x;
851 vert[icrt++] = y;
852 vert[icrt++] = z1;
853 x = fX[iv1] * fScale[iz] + fX0[iz];
854 y = fY[iv1] * fScale[iz] + fY0[iz];
855 vert[icrt++] = x;
856 vert[icrt++] = y;
857 vert[icrt++] = z1;
858 x = fX[iv1] * fScale[iz + 1] + fX0[iz + 1];
859 y = fY[iv1] * fScale[iz + 1] + fY0[iz + 1];
860 vert[icrt++] = x;
861 vert[icrt++] = y;
862 vert[icrt++] = z2;
863 x = fX[ivert] * fScale[iz + 1] + fX0[iz + 1];
864 y = fY[ivert] * fScale[iz + 1] + fY0[iz + 1];
865 vert[icrt++] = x;
866 vert[icrt++] = y;
867 vert[icrt++] = z2;
868 } else {
869 x = fX[iv1] * fScale[iz] + fX0[iz];
870 y = fY[iv1] * fScale[iz] + fY0[iz];
871 vert[icrt++] = x;
872 vert[icrt++] = y;
873 vert[icrt++] = z1;
874 x = fX[ivert] * fScale[iz] + fX0[iz];
875 y = fY[ivert] * fScale[iz] + fY0[iz];
876 vert[icrt++] = x;
877 vert[icrt++] = y;
878 vert[icrt++] = z1;
879 x = fX[ivert] * fScale[iz + 1] + fX0[iz + 1];
880 y = fY[ivert] * fScale[iz + 1] + fY0[iz + 1];
881 vert[icrt++] = x;
882 vert[icrt++] = y;
883 vert[icrt++] = z2;
884 x = fX[iv1] * fScale[iz + 1] + fX0[iz + 1];
885 y = fY[iv1] * fScale[iz + 1] + fY0[iz + 1];
886 vert[icrt++] = x;
887 vert[icrt++] = y;
888 vert[icrt++] = z2;
889 }
890}
891
892////////////////////////////////////////////////////////////////////////////////
893/// Check shape convexity
894
896{
898 return (fNz == 2 && td.fPoly->IsConvex());
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Check if the quadrilateral defined by VERT contains a coplanar POINT.
903
905{
906 Double_t v1[3], v2[3];
907 Double_t cross;
908 Int_t j, k;
909 for (Int_t i = 0; i < 4; i++) { // loop vertices
910 j = 3 * i;
911 k = 3 * ((i + 1) % 4);
912 v1[0] = point[0] - vert[j];
913 v1[1] = point[1] - vert[j + 1];
914 v1[2] = point[2] - vert[j + 2];
915 v2[0] = vert[k] - vert[j];
916 v2[1] = vert[k + 1] - vert[j + 1];
917 v2[2] = vert[k + 2] - vert[j + 2];
918 cross = (v1[1] * v2[2] - v1[2] * v2[1]) * norm[0] + (v1[2] * v2[0] - v1[0] * v2[2]) * norm[1] +
919 (v1[0] * v2[1] - v1[1] * v2[0]) * norm[2];
920 if (cross < 0)
921 return kFALSE;
922 }
923 return kTRUE;
924}
925
926////////////////////////////////////////////////////////////////////////////////
927/// Print actual Xtru parameters.
928
930{
931 printf("*** Shape %s: TGeoXtru ***\n", GetName());
932 printf(" Nz = %i\n", fNz);
933 printf(" List of (x,y) of polygon vertices:\n");
934 for (Int_t ivert = 0; ivert < fNvert; ivert++)
935 printf(" x = %11.5f y = %11.5f\n", fX[ivert], fY[ivert]);
936 for (Int_t ipl = 0; ipl < fNz; ipl++)
937 printf(" plane %i: z=%11.5f x0=%11.5f y0=%11.5f scale=%11.5f\n", ipl, fZ[ipl], fX0[ipl], fY0[ipl],
938 fScale[ipl]);
939 printf(" Bounding box:\n");
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Creates a TBuffer3D describing *this* shape.
945/// Coordinates are in local reference frame.
946
948{
949 Int_t nz = GetNz();
950 Int_t nvert = GetNvert();
951 Int_t nbPnts = nz * nvert;
952 Int_t nbSegs = nvert * (2 * nz - 1);
953 Int_t nbPols = nvert * (nz - 1) + 2;
954
956 6 * (nbPols - 2) + 2 * (2 + nvert));
957 if (buff) {
958 SetPoints(buff->fPnts);
960 }
961
962 return buff;
963}
964
965////////////////////////////////////////////////////////////////////////////////
966/// Fill TBuffer3D structure for segments and polygons.
967
969{
970 Int_t nz = GetNz();
971 Int_t nvert = GetNvert();
973
974 Int_t i, j;
975 Int_t indx = 0, indx2, k;
976 for (i = 0; i < nz; i++) {
977 // loop Z planes
978 indx2 = i * nvert;
979 // loop polygon segments
980 for (j = 0; j < nvert; j++) {
981 k = (j + 1) % nvert;
982 buff.fSegs[indx++] = c;
983 buff.fSegs[indx++] = indx2 + j;
984 buff.fSegs[indx++] = indx2 + k;
985 }
986 } // total: nz*nvert polygon segments
987 for (i = 0; i < nz - 1; i++) {
988 // loop Z planes
989 indx2 = i * nvert;
990 // loop polygon segments
991 for (j = 0; j < nvert; j++) {
992 k = j + nvert;
993 buff.fSegs[indx++] = c;
994 buff.fSegs[indx++] = indx2 + j;
995 buff.fSegs[indx++] = indx2 + k;
996 }
997 } // total (nz-1)*nvert lateral segments
998
999 indx = 0;
1000
1001 // fill lateral polygons
1002 for (i = 0; i < nz - 1; i++) {
1003 indx2 = i * nvert;
1004 for (j = 0; j < nvert; j++) {
1005 k = (j + 1) % nvert;
1006 buff.fPols[indx++] = c + j % 3;
1007 buff.fPols[indx++] = 4;
1008 buff.fPols[indx++] = indx2 + j;
1009 buff.fPols[indx++] = nz * nvert + indx2 + k;
1010 buff.fPols[indx++] = indx2 + nvert + j;
1011 buff.fPols[indx++] = nz * nvert + indx2 + j;
1012 }
1013 } // total (nz-1)*nvert polys
1014 buff.fPols[indx++] = c + 2;
1015 buff.fPols[indx++] = nvert;
1016 indx2 = 0;
1017 for (j = nvert - 1; j >= 0; --j) {
1018 buff.fPols[indx++] = indx2 + j;
1019 }
1020
1021 buff.fPols[indx++] = c;
1022 buff.fPols[indx++] = nvert;
1023 indx2 = (nz - 1) * nvert;
1024
1025 for (j = 0; j < nvert; j++) {
1026 buff.fPols[indx++] = indx2 + j;
1027 }
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Compute safety to sector iz, returning also the closest segment index.
1032
1034{
1037 Bool_t in1, in2;
1038 Int_t iseg;
1039 // segment-break case
1040 if (TGeoShape::IsSameWithinTolerance(fZ[iz], fZ[iz + 1])) {
1041 safz = TMath::Abs(point[2] - fZ[iz]);
1042 if (safz > safmin)
1043 return TGeoShape::Big();
1044 SetCurrentVertices(fX0[iz], fY0[iz], fScale[iz]);
1045 saf1 = td.fPoly->Safety(point, iseg);
1046 in1 = td.fPoly->Contains(point);
1047 // if (!in1 && saf1>safmin) return TGeoShape::Big();
1048 SetCurrentVertices(fX0[iz + 1], fY0[iz + 1], fScale[iz + 1]);
1049 saf2 = td.fPoly->Safety(point, iseg);
1050 in2 = td.fPoly->Contains(point);
1051 if ((in1 & !in2) | (in2 & !in1)) {
1052 safe = safz;
1053 } else {
1056 }
1057 if (safe > safmin)
1058 return TGeoShape::Big();
1059 return safe;
1060 }
1061 // normal case
1062 safz = fZ[iz] - point[2];
1063 if (safz > safmin)
1064 return TGeoShape::Big();
1065 if (safz < 0) {
1066 saf1 = point[2] - fZ[iz + 1];
1067 if (saf1 > safmin)
1068 return TGeoShape::Big();
1069 if (saf1 < 0) {
1070 safz = TMath::Max(safz, saf1); // we are in between the 2 Z segments - we ignore safz
1071 } else {
1072 safz = saf1;
1073 }
1074 }
1075
1076 // loop segments
1077 Bool_t found = kFALSE;
1078 Double_t vert[12];
1079 Double_t norm[3];
1080 // printf("plane %d: safz=%f in=%d\n", iz, safz, in);
1081 for (iseg = 0; iseg < fNvert; iseg++) {
1084 saf1 = (point[0] - vert[0]) * norm[0] + (point[1] - vert[1]) * norm[1] + (point[2] - vert[2]) * norm[2];
1085 if (in)
1086 saf1 = -saf1;
1087 // printf("segment %d: (%f,%f)-(%f,%f) norm=(%f,%f,%f): saf1=%f\n", iseg,
1088 // vert[0],vert[1],vert[3],vert[4],norm[0],norm[1],norm[2],saf1);
1089 if (saf1 < -1.E-8)
1090 continue;
1092 safe = TMath::Abs(safe);
1093 if (safe > safmin)
1094 continue;
1095 safmin = safe;
1096 found = kTRUE;
1097 }
1098 if (found)
1099 return safmin;
1100 return TGeoShape::Big();
1101}
1102
1103////////////////////////////////////////////////////////////////////////////////
1104/// computes the closest distance from given point to this shape, according
1105/// to option. The matching point on the shape is stored in spoint.
1106///> localize the Z segment
1107
1109{
1111 Double_t safe;
1113 TGeoXtru *xtru = (TGeoXtru *)this;
1114 Int_t iz;
1115 if (in) {
1116 safmin = TMath::Min(point[2] - fZ[0], fZ[fNz - 1] - point[2]);
1117 for (iz = 0; iz < fNz - 1; iz++) {
1118 safe = xtru->SafetyToSector(point, iz, safmin, in);
1119 if (safe < safmin)
1120 safmin = safe;
1121 }
1122 return safmin;
1123 }
1124 // Accurate safety is expensive, use the bounding box
1125 if (!TGeoBBox::Contains(point))
1126 return TGeoBBox::Safety(point, in);
1127 iz = TMath::BinarySearch(fNz, fZ, point[2]);
1128 if (iz < 0) {
1129 iz = 0;
1130 safz = fZ[0] - point[2];
1131 } else {
1132 if (iz == fNz - 1) {
1133 iz = fNz - 2;
1134 safz = point[2] - fZ[fNz - 1];
1135 }
1136 }
1137 // loop segments from iz up
1138 Int_t i;
1139 for (i = iz; i < fNz - 1; i++) {
1140 safe = xtru->SafetyToSector(point, i, safmin, in);
1141 if (safe < safmin)
1142 safmin = safe;
1143 }
1144 // loop segments from iz-1 down
1145 for (i = iz - 1; i >= 0; i--) {
1146 safe = xtru->SafetyToSector(point, i, safmin, in);
1147 if (safe < safmin)
1148 safmin = safe;
1149 }
1151 return safe;
1152}
1153
1154////////////////////////////////////////////////////////////////////////////////
1155/// Save a primitive as a C++ statement(s) on output stream "out".
1156
1157void TGeoXtru::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1158{
1160 return;
1161 out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1162 out << " auto " << GetPointerName() << " = new TGeoXtru(" << fNz << ");" << std::endl;
1163 out << " " << GetPointerName() << "->SetName(\"" << GetName() << "\");" << std::endl;
1164 for (Int_t i = 0; i < fNvert; i++) {
1165 out << " xvert[" << i << "] = " << fX[i] << "; yvert[" << i << "] = " << fY[i] << ";" << std::endl;
1166 }
1167 out << " " << GetPointerName() << "->DefinePolygon(" << fNvert << ", xvert, yvert);" << std::endl;
1168 for (Int_t i = 0; i < fNz; i++)
1169 out << " " << GetPointerName() << "->DefineSection(" << i << ", " << fZ[i] << ", " << fX0[i] << ", " << fY0[i]
1170 << ", " << fScale[i] << ");" << std::endl;
1172}
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Recompute current section vertices for a given Z position within range of section iz.
1176
1178{
1179 Double_t x0, y0, scale, a, b;
1180 Int_t ind1, ind2;
1181 ind1 = iz;
1182 ind2 = iz + 1;
1183 Double_t invdz = 1. / (fZ[ind2] - fZ[ind1]);
1184 a = (fX0[ind1] * fZ[ind2] - fX0[ind2] * fZ[ind1]) * invdz;
1185 b = (fX0[ind2] - fX0[ind1]) * invdz;
1186 x0 = a + b * z;
1187 a = (fY0[ind1] * fZ[ind2] - fY0[ind2] * fZ[ind1]) * invdz;
1188 b = (fY0[ind2] - fY0[ind1]) * invdz;
1189 y0 = a + b * z;
1190 a = (fScale[ind1] * fZ[ind2] - fScale[ind2] * fZ[ind1]) * invdz;
1191 b = (fScale[ind2] - fScale[ind1]) * invdz;
1192 scale = a + b * z;
1194}
1195
1196////////////////////////////////////////////////////////////////////////////////
1197/// Set current vertex coordinates according X0, Y0 and SCALE.
1198
1200{
1202 for (Int_t i = 0; i < fNvert; i++) {
1203 td.fXc[i] = scale * fX[i] + x0;
1204 td.fYc[i] = scale * fY[i] + y0;
1205 }
1206}
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// - param[0] = nz // number of z planes
1210///
1211/// - param[1] = z1 // Z position of first plane
1212/// - param[2] = x1 // X position of first plane
1213/// - param[3] = y1 // Y position of first plane
1214/// - param[4] = scale1 // scale factor for first plane
1215/// ...
1216/// - param[4*(nz-1]+1] = zn
1217/// - param[4*(nz-1)+2] = xn
1218/// - param[4*(nz-1)+3] = yn
1219/// - param[4*(nz-1)+4] = scalen
1220
1222{
1223 fNz = (Int_t)param[0];
1224 if (fNz < 2) {
1225 Error("SetDimensions", "Cannot create TGeoXtru %s with less than 2 Z planes", GetName());
1227 return;
1228 }
1229 if (fZ)
1230 delete[] fZ;
1231 if (fScale)
1232 delete[] fScale;
1233 if (fX0)
1234 delete[] fX0;
1235 if (fY0)
1236 delete[] fY0;
1237 fZ = new Double_t[fNz];
1238 fScale = new Double_t[fNz];
1239 fX0 = new Double_t[fNz];
1240 fY0 = new Double_t[fNz];
1241
1242 for (Int_t i = 0; i < fNz; i++)
1243 DefineSection(i, param[1 + 4 * i], param[2 + 4 * i], param[3 + 4 * i], param[4 + 4 * i]);
1244}
1245
1246////////////////////////////////////////////////////////////////////////////////
1247/// create polycone mesh points
1248
1250{
1252 Int_t i, j;
1253 Int_t indx = 0;
1254 TGeoXtru *xtru = (TGeoXtru *)this;
1255 if (points) {
1256 for (i = 0; i < fNz; i++) {
1257 xtru->SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
1258 if (td.fPoly->IsClockwise()) {
1259 for (j = 0; j < fNvert; j++) {
1260 points[indx++] = td.fXc[j];
1261 points[indx++] = td.fYc[j];
1262 points[indx++] = fZ[i];
1263 }
1264 } else {
1265 for (j = 0; j < fNvert; j++) {
1266 points[indx++] = td.fXc[fNvert - 1 - j];
1267 points[indx++] = td.fYc[fNvert - 1 - j];
1268 points[indx++] = fZ[i];
1269 }
1270 }
1271 }
1272 }
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// create polycone mesh points
1277
1279{
1281 Int_t i, j;
1282 Int_t indx = 0;
1283 TGeoXtru *xtru = (TGeoXtru *)this;
1284 if (points) {
1285 for (i = 0; i < fNz; i++) {
1286 xtru->SetCurrentVertices(fX0[i], fY0[i], fScale[i]);
1287 if (td.fPoly->IsClockwise()) {
1288 for (j = 0; j < fNvert; j++) {
1289 points[indx++] = td.fXc[j];
1290 points[indx++] = td.fYc[j];
1291 points[indx++] = fZ[i];
1292 }
1293 } else {
1294 for (j = 0; j < fNvert; j++) {
1295 points[indx++] = td.fXc[fNvert - 1 - j];
1296 points[indx++] = td.fYc[fNvert - 1 - j];
1297 points[indx++] = fZ[i];
1298 }
1299 }
1300 }
1301 }
1302}
1303
1304////////////////////////////////////////////////////////////////////////////////
1305/// Returns numbers of vertices, segments and polygons composing the shape mesh.
1306
1308{
1309 Int_t nz = GetNz();
1310 Int_t nv = GetNvert();
1311 nvert = nz * nv;
1312 nsegs = nv * (2 * nz - 1);
1313 npols = nv * (nz - 1) + 2;
1314}
1315
1316////////////////////////////////////////////////////////////////////////////////
1317/// Return number of vertices of the mesh representation
1318
1320{
1322 return numPoints;
1323}
1324
1325////////////////////////////////////////////////////////////////////////////////
1326/// fill size of this 3-D object
1327
1328void TGeoXtru::Sizeof3D() const {}
1329
1330////////////////////////////////////////////////////////////////////////////////
1331/// Fills a static 3D buffer and returns a reference.
1332
1334{
1335 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
1336
1338
1340 Int_t nz = GetNz();
1341 Int_t nvert = GetNvert();
1342 Int_t nbPnts = nz * nvert;
1343 Int_t nbSegs = nvert * (2 * nz - 1);
1344 Int_t nbPols = nvert * (nz - 1) + 2;
1345 if (buffer.SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * (nbPols - 2) + 2 * (2 + nvert))) {
1347 }
1348 }
1349 // TODO: Push down to TGeoShape?
1351 SetPoints(buffer.fPnts);
1352 if (!buffer.fLocalFrame) {
1353 TransformPoints(buffer.fPnts, buffer.NbPnts());
1354 }
1355
1356 SetSegsAndPols(buffer);
1358 }
1359
1360 return buffer;
1361}
1362
1363////////////////////////////////////////////////////////////////////////////////
1364/// Check the inside status for each of the points in the array.
1365/// Input: Array of point coordinates + vector size
1366/// Output: Array of Booleans for the inside of each point
1367
1369{
1370 for (Int_t i = 0; i < vecsize; i++)
1371 inside[i] = Contains(&points[3 * i]);
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375/// Compute the normal for an array o points so that norm.dot.dir is positive
1376/// Input: Arrays of point coordinates and directions + vector size
1377/// Output: Array of normal directions
1378
1380{
1381 for (Int_t i = 0; i < vecsize; i++)
1382 ComputeNormal(&points[3 * i], &dirs[3 * i], &norms[3 * i]);
1383}
1384
1385////////////////////////////////////////////////////////////////////////////////
1386/// Compute distance from array of input points having directions specified by dirs. Store output in dists
1387
1389 Double_t *step) const
1390{
1391 for (Int_t i = 0; i < vecsize; i++)
1392 dists[i] = DistFromInside(&points[3 * i], &dirs[3 * i], 3, step[i]);
1393}
1394
1395////////////////////////////////////////////////////////////////////////////////
1396/// Compute distance from array of input points having directions specified by dirs. Store output in dists
1397
1399 Double_t *step) const
1400{
1401 for (Int_t i = 0; i < vecsize; i++)
1402 dists[i] = DistFromOutside(&points[3 * i], &dirs[3 * i], 3, step[i]);
1403}
1404
1405////////////////////////////////////////////////////////////////////////////////
1406/// Compute safe distance from each of the points in the input array.
1407/// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1408/// Output: Safety values
1409
1411{
1412 for (Int_t i = 0; i < vecsize; i++)
1413 safe[i] = Safety(&points[3 * i], inside[i]);
1414}
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
float xmin
float ymin
float xmax
float ymax
Generic 3D primitive description class.
Definition TBuffer3D.h:18
UInt_t NbPnts() const
Definition TBuffer3D.h:89
Bool_t SectionsValid(UInt_t mask) const
Definition TBuffer3D.h:76
void SetSectionsValid(UInt_t mask)
Definition TBuffer3D.h:74
Bool_t fLocalFrame
Definition TBuffer3D.h:99
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Double_t * fPnts
Definition TBuffer3D.h:122
Box class.
Definition TGeoBBox.h:18
void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const override
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Double_t fDX
Definition TGeoBBox.h:21
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 box.
Definition TGeoBBox.cxx:431
Double_t fOrigin[3]
Definition TGeoBBox.h:24
void InspectShape() const override
Prints shape parameters.
Definition TGeoBBox.cxx:845
Bool_t Contains(const Double_t *point) const override
Test if point is inside this shape.
Definition TGeoBBox.cxx:322
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
Computes the closest distance from given point to this shape.
Double_t fDY
Definition TGeoBBox.h:22
Double_t fDZ
Definition TGeoBBox.h:23
An arbitrary polygon defined by vertices.
Definition TGeoPolygon.h:19
static Double_t Big()
Definition TGeoShape.h:95
Int_t GetBasicColor() const
Get the basic color (0-7).
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
const char * GetPointerName() const
Provide a pointer name containing uid.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
const char * GetName() const override
Get the shape name.
@ kGeoSavePrimitive
Definition TGeoShape.h:65
static Double_t Tolerance()
Definition TGeoShape.h:98
Bool_t TestShapeBit(UInt_t f) const
Definition TGeoShape.h:177
A TGeoXtru shape is represented by the extrusion of an arbitrary polygon with fixed outline between s...
Definition TGeoXtru.h:25
Double_t * fScale
Definition TGeoXtru.h:71
ThreadData_t & GetThreadData() const
Per-thread non-owning cache of scratch state indexed by this shape.
Definition TGeoXtru.h:44
Int_t GetNmeshVertices() const override
Return number of vertices of the mesh representation.
Double_t * fX0
Definition TGeoXtru.h:72
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...
TGeoXtru()
dummy ctor
Definition TGeoXtru.cxx:174
void ClearThreadData() const override
Release object-owned scratch buffers and invalidate the non-owning TLS slots.
Definition TGeoXtru.cxx:148
Double_t Capacity() const override
Compute capacity [length^3] of this shape.
Definition TGeoXtru.cxx:277
Int_t fNz
Definition TGeoXtru.h:66
Double_t * fZ
Definition TGeoXtru.h:70
void ComputeBBox() override
compute bounding box of the pcon
Definition TGeoXtru.cxx:300
std::vector< std::unique_ptr< OwnedThreadData_t > > fOwnedData
! Object-owned per-thread buffers
Definition TGeoXtru.h:74
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.
Bool_t Contains(const Double_t *point) const override
test if point is inside this shape
Definition TGeoXtru.cxx:360
std::atomic< Bool_t > fIllegalChecked
bumped whenever the per-thread state must be rebuilt
Definition TGeoXtru.h:29
Int_t fNvert
Definition TGeoXtru.h:65
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
static std::atomic< UInt_t > fgInstanceCount
Definition TGeoXtru.h:105
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void GetPlaneVertices(Int_t iz, Int_t ivert, Double_t *vert) const
Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1) and polygon vertices (i...
Definition TGeoXtru.cxx:839
void InspectShape() const override
Print actual Xtru parameters.
Definition TGeoXtru.cxx:929
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
compute closest distance from point px,py to each corner
Definition TGeoXtru.cxx:396
Double_t * GetZ() const
Definition TGeoXtru.h:125
Bool_t IsPointInsidePlane(const Double_t *point, Double_t *vert, Double_t *norm) const
Check if the quadrilateral defined by VERT contains a coplanar POINT.
Definition TGeoXtru.cxx:904
void Sizeof3D() const override
fill size of this 3-D object
~TGeoXtru() override
destructor
Definition TGeoXtru.cxx:245
const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const override
Fills a static 3D buffer and returns a reference.
Int_t GetNvert() const
Definition TGeoXtru.h:119
Double_t * fY0
Definition TGeoXtru.h:73
void InitThreadSlot(ThreadData_t &td) const
(Re)build the per-thread scratch state for this shape into the given slot.
Definition TGeoXtru.cxx:119
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
Definition TGeoXtru.cxx:739
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz.
virtual void DefineSection(Int_t snum, Double_t z, Double_t x0=0., Double_t y0=0., Double_t scale=1.)
defines z position of a section plane, rmin and rmax at this z.
Definition TGeoXtru.cxx:773
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.
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...
std::atomic< Int_t > fGeneration
non-reused index of this shape into the per-thread vector
Definition TGeoXtru.h:28
void SetDimensions(Double_t *param) override
void DrawPolygon(Option_t *option="")
Draw the section polygon.
Definition TGeoXtru.cxx:405
void SetPoints(Double_t *points) const override
create polycone mesh points
Double_t SafetyToSector(const Double_t *point, Int_t iz, Double_t safmin, Bool_t in)
Compute safety to sector iz, returning also the closest segment index.
Double_t * fY
Definition TGeoXtru.h:69
std::mutex fOwnedDataMutex
! Protects cold allocation and cleanup
Definition TGeoXtru.h:75
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 polycone locate Z segment
Definition TGeoXtru.cxx:481
Double_t * fX
Definition TGeoXtru.h:68
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...
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Compute normal to closest surface from POINT.
Definition TGeoXtru.cxx:338
TBuffer3D * MakeBuffer3D() const override
Creates a TBuffer3D describing this shape.
Definition TGeoXtru.cxx:947
Double_t DistToPlane(const Double_t *point, const Double_t *dir, Int_t iz, Int_t ivert, Double_t stepmax, Bool_t in) const
Compute distance to a Xtru lateral surface.
Definition TGeoXtru.cxx:415
void SetSegsAndPols(TBuffer3D &buff) const override
Fill TBuffer3D structure for segments and polygons.
Definition TGeoXtru.cxx:968
void SetSeg(Int_t iseg)
Set current segment.
Definition TGeoXtru.cxx:166
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 tube Warning("DistFromOutside",...
Definition TGeoXtru.cxx:606
void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const override
Returns numbers of vertices, segments and polygons composing the shape mesh.
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
Definition TGeoXtru.cxx:812
void SetIz(Int_t iz)
Set current z-plane.
Definition TGeoXtru.cxx:159
Int_t GetNz() const
Definition TGeoXtru.h:118
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.
Bool_t IsConvex() const final
Check shape convexity.
Definition TGeoXtru.cxx:895
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
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:1082
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
TPaveText * pt
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
std::unique_ptr< Double_t[]> fYc
Definition TGeoXtru.cxx:109
std::unique_ptr< Double_t[]> fXc
Definition TGeoXtru.cxx:108
OwnedThreadData_t(std::size_t size)
Definition TGeoXtru.cxx:112
std::unique_ptr< TGeoPolygon > fPoly
Definition TGeoXtru.cxx:110
illegal-polygon warning already emitted
Definition TGeoXtru.h:32
Int_t fIz
current segment [0,fNvert-1]
Definition TGeoXtru.h:34