diff --git a/vis/include/mirror.hpp b/vis/include/mirror.hpp index 7b6b1fe..58eeb22 100644 --- a/vis/include/mirror.hpp +++ b/vis/include/mirror.hpp @@ -1,18 +1,75 @@ #pragma once #include -#include + #include #include #include -glm::vec4 round(const glm::vec4 &f, int prec) { - auto dec = (float) pow(10, prec); - auto res = glm::trunc(f * dec + 0.5f) / dec; - return res; +template +using vec = std::array; + +using vec1 = vec<1>; +using vec2 = vec<2>; +using vec3 = vec<3>; +using vec4 = vec<4>; +using vec5 = vec<5>; + +template +V operator*(V a, float b) { + for (auto &e : a) e *= b; + return a; } -float dot(int n, const glm::vec4 &a, const glm::vec4 &b) { +template +V operator*(float b, V a) { + for (auto &e : a) e *= b; + return a; +} + +template +V operator/(V a, float b) { + for (auto &e : a) e /= b; + return a; +} + +template +V operator+(V a, V b) { + for (int i = 0; i < a.size(); ++i) { + a[i] += b[i]; + } + return a; +} + +template +V operator-(V a, V b) { + for (int i = 0; i < a.size(); ++i) { + a[i] -= b[i]; + } + return a; +} + +template +void operator-=(V &a, V b) { + for (int i = 0; i < a.size(); ++i) { + a[i] -= b[i]; + } +} + +template +float length(V a) { + float sum = 0; + for (auto e : a) sum += e * e; + return sqrtf(sum); +} + +template +V normalized(V a) { + return a / length(a); +} + +template +float dot(int n, const V &a, const V &b) { float sum = 0; for (int i = 0; i < n; ++i) { sum += a[i] * b[i]; @@ -20,15 +77,17 @@ float dot(int n, const glm::vec4 &a, const glm::vec4 &b) { return sum; } -float dot(int n, const std::vector &a, const std::vector &b) { +template +float dot(const V &a, const V &b) { float sum = 0; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < a.size(); ++i) { sum += a[i] * b[i]; } return sum; } -std::vector mirror(const tc::Group &group) { +template +std::vector> mirror(const tc::Group &group) { std::vector> mirrors; for (int p = 0; p < group.ngens; ++p) { @@ -51,33 +110,41 @@ std::vector mirror(const tc::Group &group) { mirrors.push_back(vp); } - std::vector res; - for (const auto &vec : mirrors) { - glm::vec4 rvec{}; + std::vector> res; + for (const auto &v : mirrors) { + vec rv{}; // ortho proj - for (int i = 0; i < std::min(vec.size(), (size_t) 4); ++i) { - rvec[i] = vec[i]; + for (int i = 0; i < std::min(v.size(), (size_t) N); ++i) { + rv[i] = v[i]; } - res.push_back(rvec); + res.push_back(rv); } return res; } -glm::vec4 project(const glm::vec4 &vec, const glm::vec4 &target) { - return glm::dot(vec, target) / glm::dot(target, target) * target; +template +vec stereo(vec v) { + vec r; + for (int i = 0; i < N; ++i) { + r[i] = v[i] / (1-v[N]); + } + return r; } -glm::vec4 reflect(const glm::vec4 &vec, const glm::vec4 axis) { - return vec - 2.f * project(vec, axis); +template +V project(const V &vec, const V &target) { + return dot(vec, target) / dot(target, target) * target; } -glm::vec4 reflect_scaled(const glm::vec4 &vec, const glm::vec4 axis) { - return vec - 2.f * glm::length(axis) * project(vec, axis); +template +V reflect(const V &a, const V &axis) { + return a - 2.f * project(a, axis); } -glm::vec4 gram_schmidt_last(std::vector vecs) { +template +V gram_schmidt_last(std::vector vecs) { int N = vecs.size(); for (int i = 0; i < N; ++i) { for (int j = 0; j < i; ++j) { @@ -85,22 +152,24 @@ glm::vec4 gram_schmidt_last(std::vector vecs) { } } - return glm::normalize(vecs[N - 1]); + return normalized(vecs[N - 1]); } -glm::vec4 barycentric(std::vector basis, std::vector coords) { - glm::vec4 res{}; +template +V barycentric(std::vector basis, std::vector coords) { + V res{}; int N = std::min(basis.size(), coords.size()); for (int i = 0; i < N; ++i) { - res += basis[i] * coords[i]; + res = res + (basis[i] * coords[i]); } - return glm::normalize(res); + return normalized(res); } -std::vector plane_intersections(std::vector normals) { +template +std::vector plane_intersections(std::vector normals) { int N = normals.size(); - std::vector results(N); + std::vector results(N); for (int i = 0; i < N; ++i) { std::rotate(normals.begin(), normals.begin() + 1, normals.end()); diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 81099fe..05d990e 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -89,10 +89,12 @@ std::vector>> poly_parts(const tc::Group &group) { std::vector>> parts; auto g_gens = gens(group); for (const auto &sg_gens : Combos(g_gens, N - 1)) { - parts.push_back( - tile(triangulate(group, sg_gens), group, g_gens, sg_gens) - ); + const auto &base = triangulate(group, sg_gens); + const auto &all = tile(base, group, g_gens, sg_gens); +// const auto &all = recontext(base, group, g_gens, sg_gens); + parts.push_back(all); } + parts.erase(parts.end() - 1, parts.end()); return parts; } @@ -118,17 +120,21 @@ public: "shaders/diffuse.fs.glsl"); }; -std::vector points(const tc::Group &group) { +std::vector points(const tc::Group &group) { auto cosets = group.solve(); - auto mirrors = mirror(group); + auto mirrors = mirror<5>(group); auto corners = plane_intersections(mirrors); + auto start = barycentric(corners, {1.00f, 0.2f, 0.1f, 0.05f, 0.025f}); // auto start = barycentric(corners, {1.0f, 1.0f, 1.0f, 1.0f}); - auto start = barycentric(corners, {1.00f, 0.2f, 0.1f, 0.05f}); // auto start = barycentric(corners, {0.05f, 0.1f, 0.2f, 1.00f}); - return cosets.path.walk(start, mirrors, reflect); + auto higher = cosets.path.walk(start, mirrors, reflect); + std::vector res(higher.size()); + std::transform(higher.begin(), higher.end(), res.begin(), stereo<4>); + + return res; } void run(GLFWwindow *window) { @@ -151,7 +157,7 @@ void run(GLFWwindow *window) { .stage(sh.slice) .stage(sh.diffuse); - auto group = tc::group::F4(); + auto group = tc::schlafli({5, 3, 3, 2}); auto wire_data = merge(poly_parts<2>(group)); const auto slice_dark = glm::vec3(.5, .3, .7); @@ -179,7 +185,7 @@ void run(GLFWwindow *window) { slices.vao.ipointer(0, slices.ibo, 4, GL_UNSIGNED_INT); slices.vao.pointer(1, slices.vbo, 3, GL_FLOAT); - auto vbo = cgl::Buffer(points(group)); + auto vbo = cgl::Buffer(points(group)); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vbo); auto ubo = cgl::Buffer(); @@ -200,7 +206,7 @@ void run(GLFWwindow *window) { glProgramUniform3f(sh.solid, 2, 0.3, 0.3, 0.3); proj_pipe.bound([&]() { - wires.draw_direct(); +// wires.draw_direct(); }); slice_pipe.bound([&]() {