#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; } float dot(int n, const glm::vec4 &a, const glm::vec4 &b) { float sum = 0; for (int i = 0; i < n; ++i) { sum += a[i] * b[i]; } return sum; } float dot(int n, const std::vector &a, const std::vector &b) { float sum = 0; for (int i = 0; i < n; ++i) { sum += a[i] * b[i]; } return sum; } std::vector mirror(const tc::Group &group) { std::vector> mirrors; for (int p = 0; p < group.ngens; ++p) { std::vector vp; for (int m = 0; m < p; ++m) { auto &vq = mirrors[m]; vp.push_back((cos(M_PI / group.get(p, m)) - dot(m, vp, vq)) / vq[m]); } vp.push_back(std::sqrt(1 - dot(p, vp, vp))); for (const auto &v : mirrors) { if (dot(p, vp, vp) > 0) { for (auto &e : vp) { e *= -1; } break; } } mirrors.push_back(vp); } std::vector res; for (const auto &vec : mirrors) { glm::vec4 rvec{}; // ortho proj for (int i = 0; i < std::min(vec.size(), (size_t) 4); ++i) { rvec[i] = vec[i]; } res.push_back(rvec); } return res; } glm::vec4 project(const glm::vec4 &vec, const glm::vec4 &target) { return glm::dot(vec, target) / glm::dot(target, target) * target; } glm::vec4 reflect(const glm::vec4 &vec, const glm::vec4 axis) { return vec - 2.f * project(vec, axis); } glm::vec4 gram_schmidt_last(std::vector vecs) { int N = vecs.size(); for (int i = 0; i < N; ++i) { for (int j = 0; j < i; ++j) { vecs[i] -= project(vecs[i], vecs[j]); } } return glm::normalize(vecs[N - 1]); } glm::vec4 barycentric(std::vector basis, std::vector coords) { glm::vec4 res{}; int N = std::min(basis.size(), coords.size()); for (int i = 0; i < N; ++i) { res += basis[i] * coords[i]; } return glm::normalize(res); } std::vector plane_intersections(std::vector normals) { int N = normals.size(); std::vector results(N); for (int i = 0; i < N; ++i) { std::rotate(normals.begin(), normals.begin() + 1, normals.end()); results[i] = gram_schmidt_last(normals); } return results; }