File indexing completed on 2025-01-30 09:32:37
0001
0002
0003
0004
0005
0006
0007
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
0021
0022
0023
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
0038 void operator++() {
0039 ++i;
0040 ++iter;
0041 }
0042
0043
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
0055
0056
0057
0058
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
0066
0067
0068 static inline std::string id_to_url(const std::string &id_) {
0069 return std::string("url(#") + id_ + ")";
0070 }
0071
0072
0073
0074
0075
0076
0077
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
0086
0087
0088
0089
0090
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
0100
0101
0102
0103
0104
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
0112
0113
0114
0115
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
0130
0131
0132
0133
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
0144
0145
0146
0147
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
0159
0160
0161
0162
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
0174
0175
0176
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
0190
0191
0192
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
0205
0206
0207
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 }
0221
0222 }