Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:41:54

0001 // This file is part of the actsvg package.
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 planar view operator, assuming a contour in x/y plane
0058      *
0059      * @tparam point3 is a 3D-point type assuming [] operators exit
0060      *
0061      * @param point_ the point global coordinates
0062      *
0063      * @return a 2D point
0064      */
0065     template <typename point3_type>
0066     point2 point(const point3_type &point_) const {
0067         return point2{static_cast<scalar>(point_[0]),
0068                       static_cast<scalar>(point_[1])};
0069     }
0070 
0071     /** A planar view operator, assuming a contour in x/y plane
0072      *
0073      * @tparam point3_container is a 3D-point container, where elements
0074      * of a single p3 object can be accessed via [] operators
0075      *
0076      * @param vertices_ the vertices of the surface, they are
0077      * assumed to be in global/display coorindates
0078      *
0079      * @return a 2D contour array
0080      */
0081     template <typename point3_container>
0082     contour path(const point3_container &vertices_) const {
0083         contour c;
0084         c.reserve(vertices_.size());
0085         for (const auto &v : vertices_) {
0086             // flip y coordinate */
0087             c.push_back(point(v));
0088         }
0089         return c;
0090     }
0091 
0092     /** A planar view operator, assuming a contour in x/y plane
0093      *
0094      * @tparam point3_container is a 3D-point container, where elements
0095      * of a single p3 object can be accessed via [] operators
0096      *
0097      * @param vertices_ the vertices of the surface, they are
0098      * assumed to be in global/display coorindates
0099      *
0100      * @return a 2D contour array
0101      */
0102     template <typename point3_container>
0103     contour operator()(const point3_container &vertices_) const {
0104         return path(vertices_);
0105     }
0106 };
0107 
0108 /// z_r projection view
0109 struct z_r {
0110 
0111     /// Scene setting
0112     scene _scene = scene();
0113 
0114     /// Make it screen obvious
0115     std::array<std::string, 2> _axis_names = {"z", "r"};
0116 
0117     /** A r-z view operator for single objects
0118      *
0119      * @tparam point3 is a 3D-point type assuming [] operators exit
0120      *
0121      * @param point_ the point global coordinates
0122      *
0123      * @return a 2D point
0124      */
0125     template <typename point3_type>
0126     point2 point(const point3_type &point_) const {
0127         scalar r = std::sqrt(point_[0] * point_[0] + point_[1] * point_[1]);
0128         return point2{static_cast<scalar>(point_[2]), r};
0129     }
0130 
0131     /** A r-z view operator
0132      *
0133      * @tparam point3_container is a 3D-point container, where elements
0134      * of a single p3 object can be accessed via [] operators
0135      *
0136      * @param vertices_ the vertices of the surface
0137      *
0138      * @return a 2D contour array
0139      */
0140     template <typename point3_container>
0141     contour path(const point3_container &vertices_) const {
0142         // Fill the contour accordingly
0143         contour c;
0144         c.reserve(vertices_.size());
0145         for (const auto &v : vertices_) {
0146             c.push_back(point(v));
0147         }
0148         return c;
0149     }
0150 
0151     /** A planar view operator
0152      *
0153      * @tparam point3_container is a 3D-point container, where elements
0154      * of a single p3 object can be accessed via [] operators
0155      *
0156      * @param vertices_ the vertices of the surface, they are
0157      * assumed to be in global/display coorindates
0158      *
0159      * @return a 2D contour array
0160      */
0161     template <typename point3_container>
0162     contour operator()(const point3_container &vertices_) const {
0163         return path(vertices_);
0164     }
0165 };
0166 
0167 // z-phi projection view
0168 struct z_phi {
0169 
0170     /// Scene setting
0171     scene _scene = scene();
0172 
0173     /// Switch the phi protection on (wrapping in phi detection)
0174     bool _protect_phi = true;
0175 
0176     /// Make it screen obvious
0177     std::array<std::string, 2> _axis_names = {"z", "phi"};
0178 
0179     /** A z-phi view operator
0180      *
0181      * @tparam point3 is a 3D-point type assuming [] operators exit
0182      *
0183      * @param point_ the point global coordinates
0184      *
0185      * @return a 2D point
0186      */
0187     template <typename point3_type>
0188     point2 point(const point3_type &point_) const {
0189         scalar phi = std::atan2(point_[1], point_[0]);
0190         return point2{static_cast<scalar>(point_[2]), phi};
0191     }
0192 
0193     /** A z-phi view operator
0194      *
0195      * @tparam point3_container is a 3D-point container, where elements
0196      * of a single p3 object can be accessed via [] operators
0197      *
0198      * @param vertices_ the vertices of the surface
0199      *
0200      *
0201      * @return a 2D contour array
0202      */
0203     template <typename point3_container>
0204     contour path(const point3_container &vertices_) const {
0205 
0206         // Fill the contour accordingly
0207         contour c;
0208         c.reserve(vertices_.size());
0209         std::vector<scalar> phi_values;
0210         phi_values.reserve(vertices_.size());
0211 
0212         for (const auto &v : vertices_) {
0213             auto p2 = point(v);
0214             phi_values.push_back(v[1u]);
0215             c.push_back(p2);
0216         }
0217         // Run the phi detection and protection
0218         if (_protect_phi) {
0219             auto min_phi =
0220                 std::min_element(phi_values.begin(), phi_values.end());
0221             auto max_phi =
0222                 std::max_element(phi_values.begin(), phi_values.end());
0223 
0224             if ((*min_phi) < 0. and (*max_phi) > 0. and
0225                 ((*max_phi) - (*min_phi)) > M_PI) {
0226                 for (auto &cv : c) {
0227                     if (cv[1] < 0.) {
0228                         cv[1] += 2_scalar * pi;
0229                     }
0230                 }
0231             }
0232         }
0233         return c;
0234     }
0235 
0236     /** A planar view operator
0237      *
0238      * @tparam point3_container is a 3D-point container, where elements
0239      * of a single p3 object can be accessed via [] operators
0240      *
0241      * @param vertices_ the vertices of the surface, they are
0242      * assumed to be in global/display coorindates
0243      *
0244      * @return a 2D contour array
0245      */
0246     template <typename point3_container>
0247     contour operator()(const point3_container &vertices_) const {
0248         return path(vertices_);
0249     }
0250 };
0251 
0252 // z_rphi projection view
0253 struct z_rphi {
0254 
0255     /// Scene setting
0256     scene _scene = scene();
0257 
0258     /// A fixed radius is needed for this view
0259     scalar _fixed_r = std::numeric_limits<scalar>::quiet_NaN();
0260 
0261     /// Make it screen obvious
0262     std::array<std::string, 2> _axis_names = {"z", "r ยท phi"};
0263 
0264     /** A z-rphi view operator
0265      *
0266      * @tparam point3 is a 3D-point type assuming [] operators exit
0267      *
0268      * @param point_ the point global coordinates
0269      *
0270      * @return a 2D point
0271      */
0272     template <typename point3_type>
0273     point2 point(const point3_type &point_) const {
0274         scalar r = _fixed_r;
0275         if (std::isnan(r)) {
0276             r = std::sqrt(point_[0] * point_[0] + point_[1] * point_[1]);
0277         }
0278         scalar phi = std::atan2(point_[1], point_[0]);
0279         return point2{static_cast<float>(point_[2]), r * phi};
0280     }
0281 
0282     /** A z-rphi view operator
0283      *
0284      * @tparam point3_container is a 3D-point container, where elements
0285      * of a single p3 object can be accessed via [] operators
0286      *
0287      * @param vertices_ the vertices of the surface
0288      *
0289      * @return a 2D contour array
0290      */
0291     template <typename point3_container>
0292     contour path(const point3_container &vertices_) const {
0293         // Fill the contour accordingly
0294         contour c;
0295         c.reserve(vertices_.size());
0296         for (const auto &v : vertices_) {
0297             c.push_back(point(v));
0298         }
0299         return c;
0300     }
0301 
0302     /** A planar view operator
0303      *
0304      * @tparam point3_container is a 3D-point container, where elements
0305      * of a single p3 object can be accessed via [] operators
0306      *
0307      * @param vertices_ the vertices of the surface, they are
0308      * assumed to be in global/display coorindates
0309      *
0310      * @return a 2D contour array
0311      */
0312     template <typename point3_container>
0313     contour operator()(const point3_container &vertices_) const {
0314         return path(vertices_);
0315     }
0316 };
0317 
0318 }  // namespace views
0319 
0320 }  // namespace actsvg