diff options
Diffstat (limited to 'app/c++')
| -rw-r--r-- | app/c++/SConscript | 37 | ||||
| -rw-r--r-- | app/c++/ico.hpp | 170 | ||||
| -rw-r--r-- | app/c++/ico_bar.hpp | 37 | ||||
| -rw-r--r-- | app/c++/ico_ct.hpp | 19 |
4 files changed, 263 insertions, 0 deletions
diff --git a/app/c++/SConscript b/app/c++/SConscript new file mode 100644 index 0000000..beb41e5 --- /dev/null +++ b/app/c++/SConscript @@ -0,0 +1,37 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +core_env = env.Clone(); + +core_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +core_env.headers = sorted(glob.glob(dir_path + "/*.hpp")) + +env.sources += core_env.sources; +env.headers += core_env.headers; + +## Shared lib +objects_shared = [] +core_env.add_source_files(objects_shared, core_env.sources, shared=True); +env.library_shared = core_env.SharedLibrary('#build/icosahedrical_destruction', [objects_shared]); + +# Set Alias +env.Alias('library', [env.library_shared]); + +env.targets += ['library']; + +# Install +env.Install('$prefix/lib/', [env.library_shared]); +env.Install('$prefix/include/sims/icosahedrical_destruction', [core_env.headers]); + +# Test +# Export('core_env'); +# SConscript('tests/SConscript'); diff --git a/app/c++/ico.hpp b/app/c++/ico.hpp new file mode 100644 index 0000000..5dc00a0 --- /dev/null +++ b/app/c++/ico.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include <array> +#include <cassert> +#include <cstdint> + +namespace kel { +namespace impl { +struct ico_surface_helper { + /** + * On each triangle we assume a ccw order and we start on the top-left part of the + * triangle. The orientation of the triangle is determined by the horizontal line + * (on the 2D foldout of the icosahedron) which is the down direction. + */ + static constexpr std::array<std::array<uint8_t,3u>, 20u> neighbour_map {{ + {1,4,5},//0 + {2,0,6},//1 + {3,1,7},//2 + {4,2,8},//3 + {0,3,9},//4 + {14,10,0},//5 + {10,11,1},//6 + {11,12,2},//7 + {12,13,3},//8 + {13,14,4},//9 + {6,5,15},//10 + {7,6,16},//11 + {8,7,17},//12 + {9,8,18},//13 + {5,9,19},//14 + {19,16,10},//15 + {15,17,11},//16 + {16,18,12},//17 + {17,19,13},//18 + {18,15,14} //19 + }}; +}; + +template<uint64_t SubD> +class ico_addr { +private: + std::array<uint8_t, SubD> vals_; +public: + uint8_t& at(uint64_t i){ + return vals_[i]; + } + + const uint8_t& at(uint64_t i) const { + return vals_[i]; + } + + constexpr uint64_t size() const { + return SubD; + } + + bool is_equal(const ico_addr<SubD>& rhs) const { + bool eq = true; + + for(uint64_t i = 0u; i < size(); ++i){ + eq &= (at(i) == rhs.at(i)); + } + + return eq; + } + + bool has_zero() const { + uint64_t z_ctr = 0u; + for(uint64_t i = 1u; i < size(); ++i){ + z_ctr += (at(i) == 0u ? 1u : 0u); + } + return (z_ctr > 0u); + } + + std::array<uint64_t,4u> count_groups() const { + std::array<uint64_t,4u> grps{0,0,0,0}; + + for(uint64_t i = 1u; i < size(); ++i){ + auto& addr_i = vals_[i]; + assert(addr_i < 4); + + ++grps[addr_i]; + } + + return grps; + } + + uint64_t count_non_zero_groups() const { + auto ctr = count_groups(); + + uint64_t grp_ctr = 0u; + for(uint64_t i = 1u; i < ctr.size(); ++i){ + grp_ctr += (ctr[i] > 0u ? 1u : 0u); + } + return grp_ctr; + } + + bool has_all_non_zero_groups() const { + auto ctr = count_non_zero_groups(); + return (ctr == 3u); + } + + ico_addr<SubD> go_to(uint8_t dir_i){ + ico_addr<SubD> cpy_addr; + cpy_addr.vals_ = vals_; + + if(at(size() - 1u) == 0u){ + cpy_addr.at(size() - 1u) = dir_i + 1u; + } + if(at(size() - 1u) == (dir_i + 1u)){ + cpy_addr.at(size() - 1u) = 0u; + } + + return cpy_addr; + } + + bool borders_root() const { + return not (has_all_non_zero_groups() or has_zero()); + } +}; + +template<typename T, uint64_t D> +class ico_triangle { +private: + std::array<ico_triangle<T,D-1u>,4u> subdivs_; +public: + + ico_triangle<T,D-1u>& at(uint8_t i){ + return subdivs_[i]; + } + + template<uint64_t AddrOrigLen> + ico_triangle<T,0u> at(const ico_addr<AddrOrigLen>& addr, uint64_t next_i){ + auto& addr_i = addr[next_i]; + + auto& sub_triangle = subdivs_[addr_i]; + if constexpr ( D == 1u){ + return sub_triangle; + } + return sub_triangle.at(addr,next_i+1u); + } +}; + +template<typename T> +class ico_triangle<T,0u> final { +private: + T val_; +public: +}; + +namespace impl { +} + +template<typename T, uint64_t SubD> +class icosahedron final { +private: + std::array<ico_triangle<T,SubD>,20u> surfaces_; +public: + + template<uint64_t AddrD> + ico_triangle<T,SubD+1u-AddrD> at(const ico_addr<AddrD>& addr){ + static_assert(AddrD <= (SubD+1u), "Addr length to large."); + static_assert(AddrD > 0u, "Addr length to small."); + + auto& root_addr = addr[0u]; + auto& root_triangle = surfaces_[root_addr]; + return root_triangle.at(addr, 1u); + } +}; +} +} diff --git a/app/c++/ico_bar.hpp b/app/c++/ico_bar.hpp new file mode 100644 index 0000000..780e28e --- /dev/null +++ b/app/c++/ico_bar.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "ico.hpp" + +namespace kel { + +template<uint64_t SubD = 0u> +class ico_coordinate { +private: + static constexpr uint64_t sub_divs_ = impl::power_two<SubD>::value; + + uint64_t t_; + uint64_t x_; + uint64_t y_; +public: + ico_coordinate(uint64_t t__, uint64_t x__, uint64_t y__): + t_{t__}, + x_{x__}, + y_{y__} + {} + + bool is_on_border() const { + auto comb = x_+y_; + + bool farside_b = (comb == sub_divs_); + bool right_b = (y_ == 0u); + bool left_b = (x_ == 0u); + + return farside_b or right_b or left_b; + } + + ico_coordinate<SubD> move_x_pos() const { + uint64_t x_mov = x_ + 1u; + + } +}; +} diff --git a/app/c++/ico_ct.hpp b/app/c++/ico_ct.hpp new file mode 100644 index 0000000..2209f66 --- /dev/null +++ b/app/c++/ico_ct.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace kel { +namespace ct { +template<typename Orig, typename... Dirs> +struct Point {}; + +template<typename P0, typename P1, uint64_t FracU, uint64_t FracD> +struct Direction { + static_assert(FracU <= FracD, "Can't exceed 1"); + static_assert(FracD > 0u, "Can't divide by 0"); +}; + +namespace impl { + +} + +} +} |
