From e67c7ec7b39d51d8a0ce0ada4b1a689b99b25125 Mon Sep 17 00:00:00 2001 From: Gonzalo Martinez Lema Date: Thu, 2 Nov 2023 13:17:20 +0200 Subject: [PATCH] Implement and test `n4::boolean_shape::trans{,form}` --- nain4/src/n4-boolean-shape.hh | 7 ++++++- nain4/test/test-nain4.cc | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/nain4/src/n4-boolean-shape.hh b/nain4/src/n4-boolean-shape.hh index 4b386738..e18103c7 100644 --- a/nain4/src/n4-boolean-shape.hh +++ b/nain4/src/n4-boolean-shape.hh @@ -1,5 +1,6 @@ #pragma once +#include "G4Transform3D.hh" #include #include @@ -16,10 +17,14 @@ struct boolean_shape : shape { friend shape; G4VSolid* solid() const override; + + boolean_shape& trans (G4Transform3D& t ) { return transform(t); } + boolean_shape& transform(G4Transform3D& t ) { transformation = t * transformation; return *this; } + boolean_shape& rotate (G4RotationMatrix& r ) { transformation = HepGeom::Rotate3D{r} * transformation; return *this; } boolean_shape& rotate_x(double delta ) { auto rot = G4RotationMatrix{}; rot.rotateX(delta); return rotate(rot);} boolean_shape& rotate_y(double delta ) { auto rot = G4RotationMatrix{}; rot.rotateY(delta); return rotate(rot);} boolean_shape& rotate_z(double delta ) { auto rot = G4RotationMatrix{}; rot.rotateZ(delta); return rotate(rot);} - boolean_shape& rotate (G4RotationMatrix& r ) { transformation = HepGeom::Rotate3D{r} * transformation; return *this; } + boolean_shape& rot (G4RotationMatrix& r ) { return rotate(r); } boolean_shape& rot_x (double delta ) { return rotate_x(delta); } boolean_shape& rot_y (double delta ) { return rotate_y(delta); } diff --git a/nain4/test/test-nain4.cc b/nain4/test/test-nain4.cc index 8427fbdc..705125b7 100644 --- a/nain4/test/test-nain4.cc +++ b/nain4/test/test-nain4.cc @@ -1554,6 +1554,36 @@ TEST_CASE("nain boolean rotation", "[nain][geometry][boolean][rotation]") { CHECK(with_rot -> EstimateCubicVolume(n, eps) == 0 ); } +TEST_CASE("boolean transform", "[boolean][transform]") { + auto l = 3*m; + auto rotation = G4RotationMatrix{}; rotation.rotateY(90 * deg); + auto translation = G4ThreeVector{0., 0., l/4}; + auto transform = G4Transform3D{rotation, translation}; + + auto usolid1 = n4::box("box1").xy(1*m).z( l) + .sub( n4::box("box2").yz(1*m).x(l/4)) + .transform(transform) + .solid(); + + auto usolid2 = n4::box("box1").xy(1*m).z( l) + .sub( n4::box("box2").yz(1*m).x(l/4)) + .trans(transform) + .solid(); + + auto n = 100000; + auto eps = 1e-3; + auto vbox = l * 1*m * 1*m; + + // The small box is 1/4 of the big box, so the result two + // disconnected boxes: one with 1/2 volume and another one with 1/4 + // volume + CHECK( usolid1 -> EstimateCubicVolume(n, eps) / m3 == Approx(3*vbox/4 / m3).margin(3e-3)); + CHECK( usolid1 -> EstimateCubicVolume(n, eps) / m3 == Approx(3*vbox/4 / m3).margin(3e-3)); + CHECK( usolid2 -> EstimateCubicVolume(n, eps) / m3 == Approx(3*vbox/4 / m3).margin(3e-3)); + CHECK( usolid2 -> EstimateCubicVolume(n, eps) / m3 == Approx(3*vbox/4 / m3).margin(3e-3)); +} + + TEST_CASE("nain envelope_of", "[nain][envelope_of]") { auto material_1 = n4::material("G4_Fe"); auto material_2 = n4::material("G4_Au");