Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:32:37

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 <cmath>
0012 #include <iomanip>
0013 #include <iostream>
0014 #include <sstream>
0015 
0016 namespace actsvg {
0017 
0018 namespace utils {
0019 
0020 /** Helper method to run enumerate(...) with structured binding
0021  * over STL type containers.
0022  *
0023  * @param iterable is a std-like iterable container type
0024  *
0025  **/
0026 template <typename container_type,
0027           typename container_type_iter =
0028               decltype(std::begin(std::declval<container_type>())),
0029           typename = decltype(std::end(std::declval<container_type>()))>
0030 constexpr auto enumerate(container_type &&iterable) {
0031     struct iterator {
0032         size_t i;
0033         container_type_iter iter;
0034 
0035         bool operator!=(const iterator &rhs) const { return iter != rhs.iter; }
0036 
0037         /** Increase index and iterator at once */
0038         void operator++() {
0039             ++i;
0040             ++iter;
0041         }
0042 
0043         /** Tie them together for returning */
0044         auto operator*() const { return std::tie(i, *iter); }
0045     };
0046     struct iterable_wrapper {
0047         container_type iterable;
0048         auto begin() { return iterator{0, std::begin(iterable)}; }
0049         auto end() { return iterator{0, std::end(iterable)}; }
0050     };
0051     return iterable_wrapper{std::forward<container_type>(iterable)};
0052 }
0053 
0054 /** Helper for perp
0055  *
0056  * @param p_ the point
0057  *
0058  * @return a scalar of the norm
0059  **/
0060 template <typename point2_type>
0061 scalar perp(const point2_type &p_) {
0062     return std::sqrt(p_[0] * p_[0] + p_[1] * p_[1]);
0063 }
0064 
0065 /** Helper from id to url
0066  * @param id_ the idnetification to be transformed
0067  **/
0068 static inline std::string id_to_url(const std::string &id_) {
0069     return std::string("url(#") + id_ + ")";
0070 }
0071 
0072 /** Helper to format point2
0073  *
0074  * @param s_ the scalar
0075  * @param pr_ the precision
0076  *
0077  * @return a string
0078  */
0079 static inline std::string to_string(const scalar &s_, size_t pr_ = 4) {
0080     std::stringstream sstream;
0081     sstream << std::setprecision(pr_) << s_;
0082     return sstream.str();
0083 }
0084 
0085 /** Helper to format point2
0086  *
0087  * @param p_ the point
0088  * @param pr_ the precision
0089  *
0090  * @return a string
0091  */
0092 template <typename point2_type>
0093 std::string to_string(const point2_type &p_, size_t pr_ = 4) {
0094     std::stringstream sstream;
0095     sstream << std::setprecision(pr_) << "(" << p_[0] << "," << p_[1] << ")";
0096     return sstream.str();
0097 }
0098 
0099 /** Check if a parameter is within range
0100  *
0101  * @param p_ parameter to be checked
0102  * @param range_ the range
0103  *
0104  * @note borders are included in this check
0105  **/
0106 template <typename range_type>
0107 bool inside_range(scalar p_, const range_type &range_) {
0108     return (range_[0] <= p_ and p_ <= range_[1]);
0109 }
0110 
0111 /** Helper method to calculate the barycenter
0112  *
0113  * @param vs_ vertices
0114  *
0115  * @return a new barycenter
0116  **/
0117 template <typename point2_type>
0118 point2_type barycenter(const std::vector<point2_type> &vs_) {
0119     point2_type rv = {0., 0.};
0120     for (const auto &v : vs_) {
0121         rv[0] += v[0];
0122         rv[1] += v[1];
0123     }
0124     rv[0] /= vs_.size();
0125     rv[1] /= vs_.size();
0126     return rv;
0127 }
0128 
0129 /** Helper method to rotate a 2-d point
0130  * @param p_ the point to be rotated
0131  * @param a_ the angle alpha
0132  *
0133  * @return the rotated point
0134  **/
0135 template <typename point2_type>
0136 point2_type rotate(const point2_type &p_, scalar a_) {
0137     point2_type p_rot;
0138     p_rot[0] = std::cos(a_) * p_[0] - std::sin(a_) * p_[1];
0139     p_rot[1] = std::sin(a_) * p_[0] + std::cos(a_) * p_[1];
0140     return p_rot;
0141 }
0142 
0143 /** Helper method toscala a point3 object
0144  *
0145  * @param p0_ the point3 object and @param s_ the scale
0146  *
0147  * @return a new point3
0148  **/
0149 template <typename point3_type>
0150 point3_type scale(const point3_type &p0_, scalar s_) {
0151     point3_type scaled;
0152     scaled[0] = s_ * p0_[0];
0153     scaled[1] = s_ * p0_[1];
0154     scaled[2] = s_ * p0_[2];
0155     return scaled;
0156 }
0157 
0158 /** Helper method to add two point3 objects
0159  *
0160  * @param p0_ and @param p1_ the 3D points
0161  *
0162  * @return a new point3
0163  **/
0164 template <typename point3_type>
0165 point3_type add(const point3_type &p0_, const point3_type &p1_) {
0166     point3_type added;
0167     added[0] = p0_[0] + p1_[0];
0168     added[1] = p0_[1] + p1_[1];
0169     added[2] = p0_[2] + p1_[2];
0170     return added;
0171 }
0172 
0173 /** Helper method to rotate a 3D point @param p_ under
0174  * roatation @param rt_
0175  *
0176  * @return new rotated point3
0177  **/
0178 template <typename point3_type>
0179 point3_type rotate(const std::array<point3_type, 3> &rt_,
0180                    const point3_type &p_) {
0181 
0182     point3_type rotated;
0183     rotated[0] = rt_[0][0] * p_[0] + rt_[0][1] * p_[1] + rt_[0][2] * p_[2];
0184     rotated[1] = rt_[1][0] * p_[0] + rt_[1][1] * p_[1] + rt_[1][2] * p_[2];
0185     rotated[2] = rt_[2][0] * p_[0] + rt_[2][1] * p_[1] + rt_[2][2] * p_[2];
0186     return rotated;
0187 }
0188 
0189 /** Helper method to place a 3D point @param p_ under
0190  * @param tr_ transform and @param rt_ rotation
0191  *
0192  * @return new transform
0193  **/
0194 template <typename point3_type>
0195 point3_type place(const point3_type &p_, const point3_type &tr_,
0196                   const std::array<point3_type, 3> &rt_) {
0197     point3_type placed = rotate(rt_, p_);
0198     placed[0] = p_[0] + tr_[0];
0199     placed[1] = p_[1] + tr_[1];
0200     placed[2] = p_[2] + tr_[2];
0201     return placed;
0202 }
0203 
0204 /** Helper method to place a 3D points @param pc_ under
0205  * @param tr_ transform and @param rt_ rotation
0206  *
0207  * @return new transformed point3 collection
0208  **/
0209 template <typename point3_collection, typename point3_type>
0210 point3_collection place_vertices(const point3_collection &pc_,
0211                                  const point3_type &tr_,
0212                                  const std::array<point3_type, 3> &rt_) {
0213     point3_collection placed;
0214     for (const auto &p : pc_) {
0215         placed.push_back(place(p, tr_, rt_));
0216     }
0217     return placed;
0218 }
0219 
0220 }  // namespace utils
0221 
0222 }  // namespace actsvg