Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:07

0001 // This file is part of the actsvg packge.
0002 //
0003 // Copyright (C) 2022 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <algorithm>
0012 #include <array>
0013 #include <cmath>
0014 #include <vector>
0015 
0016 #include "defs.hpp"
0017 
0018 namespace actsvg {
0019 
0020 /** The view convert 3D point collections as given from
0021  * the geometry output, and convert them into 2D contours that can be displayed.
0022  *
0023  * @note Given the mathemtatical negative orientation of the x/y system in SVG,
0024  * it will flip the y coordinate accordingly.
0025  *
0026  */
0027 namespace views {
0028 
0029 /// A contour is a 2-dimensional object
0030 using contour = std::vector<point2>;
0031 
0032 /// A scene description
0033 struct scene {
0034     /// A camera position
0035     point2 _camera = {0., 0.};
0036     /// A view angle
0037     point2 _view = {0., -1.};
0038     /// A strict view, i.e. only see along the view direction
0039     bool _strict = false;
0040     /// What's actually shown
0041     std::array<std::array<scalar, 2>, 2> _range = {
0042         std::array<scalar, 2>{std::numeric_limits<scalar>::lowest(),
0043                               std::numeric_limits<scalar>::max()},
0044         std::array<scalar, 2>{std::numeric_limits<scalar>::lowest(),
0045                               std::numeric_limits<scalar>::max()}};
0046 };
0047 
0048 /// Single view per module/surface
0049 struct x_y {
0050 
0051     /// Scene setting
0052     scene _scene = scene();
0053 
0054     /// Make it screen obvious
0055     std::array<std::string, 2> _axis_names = {"x", "y"};
0056 
0057     /** A single planar view operator, asuming a contour in
0058      *  x/y plane
0059      *
0060      * @tparam point3_container is a 3D-point container, where elements
0061      * of a single p3 object can be accessed via [] operators
0062      *
0063      * @param vertices_ the vertices of the surface, they are
0064      * assumed to be in global/display coorindates
0065      *
0066      * @return a 2D contour array
0067      */
0068     template <typename point3_container>
0069     contour operator()(const point3_container &vertices_) const {
0070         contour c;
0071         c.reserve(vertices_.size());
0072         for (const auto &v : vertices_) {
0073             // flip y coordinate */
0074             c.push_back({static_cast<scalar>(v[0]), static_cast<scalar>(v[1])});
0075         }
0076         return c;
0077     }
0078 };
0079 
0080 /// z_r projection view
0081 struct z_r {
0082 
0083     /// Scene setting
0084     scene _scene = scene();
0085 
0086     /// Make it screen obvious
0087     std::array<std::string, 2> _axis_names = {"z", "r"};
0088 
0089     /** A r-z view operator
0090      *
0091      * @tparam point3_container is a 3D-point container, where elements
0092      * of a single p3 object can be accessed via [] operators
0093      *
0094      * @param vertices_ the vertices of the surface
0095      *
0096      * @return a 2D contour array
0097      */
0098     template <typename point3_container>
0099     contour operator()(const point3_container &vertices_) const {
0100         // Fill the contour accordingly
0101         contour c;
0102         c.reserve(vertices_.size());
0103         for (const auto &v : vertices_) {
0104             scalar r = std::sqrt(v[0] * v[0] + v[1] * v[1]);
0105             c.push_back({static_cast<scalar>(v[2]), r});
0106         }
0107         return c;
0108     }
0109 };
0110 
0111 // z-phi projection view
0112 struct z_phi {
0113 
0114     /// Scene setting
0115     scene _scene = scene();
0116 
0117     /// Switch the phi protection on (wrapping in phi detection)
0118     bool _protect_phi = true;
0119 
0120     /// Make it screen obvious
0121     std::array<std::string, 2> _axis_names = {"z", "phi"};
0122 
0123     /** A z-phi view operator
0124      *
0125      * @tparam point3_container is a 3D-point container, where elements
0126      * of a single p3 object can be accessed via [] operators
0127      *
0128      * @param vertices_ the vertices of the surface
0129      *
0130      *
0131      * @return a 2D contour array
0132      */
0133     template <typename point3_container>
0134     contour operator()(const point3_container &vertices_) const {
0135 
0136         // Fill the contour accordingly
0137         contour c;
0138         c.reserve(vertices_.size());
0139         std::vector<scalar> phi_values;
0140         phi_values.reserve(vertices_.size());
0141 
0142         for (const auto &v : vertices_) {
0143             scalar phi = std::atan2(v[1], v[0]);
0144             phi_values.push_back(phi);
0145             c.push_back({static_cast<scalar>(v[2]), phi});
0146         }
0147         // Run the phi detection and protection
0148         if (_protect_phi) {
0149             auto min_phi =
0150                 std::min_element(phi_values.begin(), phi_values.end());
0151             auto max_phi =
0152                 std::max_element(phi_values.begin(), phi_values.end());
0153 
0154             if ((*min_phi) < 0. and (*max_phi) > 0. and
0155                 ((*max_phi) - (*min_phi)) > M_PI) {
0156                 for (auto &cv : c) {
0157                     if (cv[1] < 0.) {
0158                         cv[1] += 2 * M_PI;
0159                     }
0160                 }
0161             }
0162         }
0163         return c;
0164     }
0165 };
0166 
0167 // z_rphi projection view
0168 struct z_rphi {
0169 
0170     /// Scene setting
0171     scene _scene = scene();
0172 
0173     /// A fixed radius is needed for this view
0174     scalar _fixed_r = std::numeric_limits<scalar>::quiet_NaN();
0175 
0176     /// Make it screen obvious
0177     std::array<std::string, 2> _axis_names = {"z", "r ยท phi"};
0178 
0179     /** A z-rphi view operator
0180      *
0181      * @tparam point3_container is a 3D-point container, where elements
0182      * of a single p3 object can be accessed via [] operators
0183      *
0184      * @param vertices_ the vertices of the surface
0185      *
0186      * @return a 2D contour array
0187      */
0188     template <typename point3_container>
0189     contour operator()(const point3_container &vertices_) const {
0190         // Fill the contour accordingly
0191         contour c;
0192         c.reserve(vertices_.size());
0193         for (const auto &v : vertices_) {
0194             scalar r = _fixed_r;
0195             if (std::isnan(r)) {
0196                 r = std::sqrt(v[0] * v[0] + v[1] * v[1]);
0197             }
0198             scalar phi = std::atan2(v[1], v[0]);
0199             c.push_back({static_cast<scalar>(v[2]), r * phi});
0200         }
0201         return c;
0202     }
0203 };
0204 
0205 }  // namespace views
0206 
0207 }  // namespace actsvg