File indexing completed on 2025-10-25 07:57:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Surfaces/AnnulusBounds.hpp"
0013 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0014 #include "Acts/Surfaces/DiamondBounds.hpp"
0015 #include "Acts/Surfaces/DiscSurface.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Surfaces/RadialBounds.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0020 #include "ActsPlugins/ActSVG/SurfaceSvgConverter.hpp"
0021 #include "ActsPlugins/ActSVG/SvgUtils.hpp"
0022
0023 #include <fstream>
0024 #include <numbers>
0025
0026 using namespace Acts;
0027 using namespace ActsPlugins;
0028
0029 namespace ActsTests {
0030
0031
0032
0033
0034
0035 void runPlanarTests(const Surface& surface, const Svg::Style& style,
0036 const std::string& identification) {
0037
0038 GeometryContext geoCtx;
0039
0040 using SurfaceOptions = Svg::SurfaceConverter::Options;
0041
0042 SurfaceOptions sOptions;
0043 sOptions.style = style;
0044 sOptions.templateSurface = true;
0045
0046
0047 auto svgTemplate = Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0048 auto xyTemplate = Svg::View::xy(svgTemplate, identification + "_template");
0049 Svg::toFile({xyTemplate}, xyTemplate._id + ".svg");
0050
0051 sOptions.templateSurface = false;
0052 auto svgObject = Svg::SurfaceConverter::convert(geoCtx, surface, sOptions);
0053 auto xyObject = Svg::View::xy(svgObject, identification);
0054 auto xyAxes = Svg::axesXY(static_cast<double>(xyObject._x_range[0]),
0055 static_cast<double>(xyObject._x_range[1]),
0056 static_cast<double>(xyObject._y_range[0]),
0057 static_cast<double>(xyObject._y_range[1]));
0058
0059 Svg::toFile({xyObject, xyAxes}, xyObject._id + ".svg");
0060
0061 auto svgSheet = Svg::Sheet::xy(svgTemplate, identification + "_sheet");
0062 Svg::toFile({svgSheet}, svgSheet._id + ".svg");
0063 }
0064
0065 BOOST_AUTO_TEST_SUITE(ActSvg)
0066
0067 BOOST_AUTO_TEST_CASE(PlanarSurfaces) {
0068
0069 Svg::Style planarStyle;
0070 planarStyle.fillColor = {51, 153, 255};
0071 planarStyle.fillOpacity = 0.75;
0072 planarStyle.highlightColor = {255, 153, 51};
0073 planarStyle.highlights = {"mouseover", "mouseout"};
0074 planarStyle.strokeWidth = 0.5;
0075 planarStyle.quarterSegments = 0u;
0076
0077
0078 auto rectangleBounds = std::make_shared<RectangleBounds>(36., 64.);
0079 auto transform = Transform3::Identity();
0080 transform.pretranslate(Vector3{20., 20., 100.});
0081 auto rectanglePlane =
0082 Surface::makeShared<PlaneSurface>(transform, rectangleBounds);
0083 runPlanarTests(*rectanglePlane, planarStyle, "rectangle");
0084
0085
0086 auto trapezoidBounds = std::make_shared<TrapezoidBounds>(36., 64., 105.);
0087 auto trapeozidPlane =
0088 Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0089 runPlanarTests(*trapeozidPlane, planarStyle, "trapezoid");
0090
0091
0092 double phi = std::numbers::pi / 8.;
0093 double radius = 150.;
0094 Vector3 center(radius * std::cos(phi), radius * std::sin(phi), 0.);
0095
0096 Vector3 localY(std::cos(phi), std::sin(phi), 0.);
0097 Vector3 localZ(0., 0., 1.);
0098 Vector3 localX = localY.cross(localZ);
0099 RotationMatrix3 rotation;
0100 rotation.col(0) = localX;
0101 rotation.col(1) = localY;
0102 rotation.col(2) = localZ;
0103 transform = Transform3(Translation3(center) * rotation);
0104
0105 auto trapeozidPlaneTransformed =
0106 Surface::makeShared<PlaneSurface>(transform, trapezoidBounds);
0107
0108 runPlanarTests(*trapeozidPlaneTransformed, planarStyle, "trapezoid_rotated");
0109
0110 GeometryContext geoCtx;
0111 actsvg::proto::surface<std::vector<Vector3>> reference;
0112 reference._vertices =
0113 trapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0114 auto referenceTrapezoid = Svg::View::xy(reference, "trapezoid");
0115 auto referenceAxes = Svg::axesXY(-200., 200., -200., 200);
0116 Svg::toFile({referenceTrapezoid, referenceAxes}, "trapezoid_reference.svg");
0117
0118
0119 Vector3 flocalZ(0., 0., -1.);
0120 Vector3 flocalX = localY.cross(flocalZ);
0121 RotationMatrix3 frotation;
0122 frotation.col(0) = flocalX;
0123 frotation.col(1) = localY;
0124 frotation.col(2) = flocalZ;
0125 auto ftransform = Transform3(Translation3(center) * frotation);
0126
0127 auto ftrapeozidPlaneTransformed =
0128 Surface::makeShared<PlaneSurface>(ftransform, trapezoidBounds);
0129
0130 runPlanarTests(*ftrapeozidPlaneTransformed, planarStyle,
0131 "flipped_trapezoid_rotated");
0132 actsvg::proto::surface<std::vector<Vector3>> freference;
0133 freference._vertices =
0134 ftrapeozidPlaneTransformed->polyhedronRepresentation(geoCtx, 1u).vertices;
0135
0136 auto freferenceTrapezoid = Svg::View::xy(freference, "flipped_trapezoid");
0137 Svg::toFile({freferenceTrapezoid, referenceAxes},
0138 "flipped_trapezoid_reference.svg");
0139
0140
0141 auto diamondBounds = std::make_shared<DiamondBounds>(36., 64., 14., 40., 30.);
0142 transform = Transform3::Identity();
0143 auto diamond = Surface::makeShared<PlaneSurface>(transform, diamondBounds);
0144 runPlanarTests(*diamond, planarStyle, "diamond");
0145
0146
0147 std::vector<Vector2> vertices = {
0148 {-10., -10.}, {10., -15.}, {20., 5.}, {-5., 15.}, {-12, 0.}};
0149 auto polygonBounds = std::make_shared<ConvexPolygonBounds<5u>>(vertices);
0150 auto polygon = Surface::makeShared<PlaneSurface>(transform, polygonBounds);
0151 runPlanarTests(*polygon, planarStyle, "polygon");
0152 }
0153
0154 BOOST_AUTO_TEST_CASE(DiscSurfaces) {
0155
0156 Svg::Style discStyle;
0157 discStyle.fillColor = {0, 204, 153};
0158 discStyle.fillOpacity = 0.75;
0159 discStyle.highlightColor = {153, 204, 0};
0160 discStyle.highlights = {"mouseover", "mouseout"};
0161 discStyle.strokeWidth = 0.5;
0162 discStyle.quarterSegments = 72u;
0163
0164 auto transform = Transform3::Identity();
0165 transform.pretranslate(Vector3{20., 20., 100.});
0166
0167
0168 auto fullDiscBounds = std::make_shared<RadialBounds>(0., 64.);
0169 auto fullDisc = Surface::makeShared<DiscSurface>(transform, fullDiscBounds);
0170 runPlanarTests(*fullDisc, discStyle, "full_disc");
0171
0172
0173 auto fullRingBounds = std::make_shared<RadialBounds>(36., 64.);
0174 auto fullRing = Surface::makeShared<DiscSurface>(transform, fullRingBounds);
0175 runPlanarTests(*fullRing, discStyle, "full_ring");
0176
0177
0178 auto sectoralDiscBounds = std::make_shared<RadialBounds>(
0179 0., 64., std::numbers::pi / 4., std::numbers::pi / 2.);
0180 auto sectoralDisc =
0181 Surface::makeShared<DiscSurface>(transform, sectoralDiscBounds);
0182 runPlanarTests(*sectoralDisc, discStyle, "full_disc");
0183
0184
0185 double minRadius = 7.2;
0186 double maxRadius = 12.0;
0187 double minPhi = 0.74195;
0188 double maxPhi = 1.33970;
0189
0190 Vector2 offset{-3., 2.};
0191
0192 auto annulusDiscBounds = std::make_shared<AnnulusBounds>(
0193 minRadius, maxRadius, minPhi, maxPhi, offset);
0194 auto annulusDisc =
0195 Surface::makeShared<DiscSurface>(transform, annulusDiscBounds);
0196 runPlanarTests(*annulusDisc, discStyle, "annulus_disc");
0197 }
0198
0199 BOOST_AUTO_TEST_SUITE_END()
0200
0201 }