summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-12-01 16:56:14 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2024-12-01 16:56:14 +0000
commitf9e6220bf8b17681cb2f395ab64851a72659a070 (patch)
tree43c975ef33f75f0833f46ce09d7a2d6a60d8d398
parentRemove GeoData::difference for points, use global version (diff)
downloadilt-f9e6220bf8b17681cb2f395ab64851a72659a070.tar.bz2
ilt-f9e6220bf8b17681cb2f395ab64851a72659a070.tar.xz
ilt-f9e6220bf8b17681cb2f395ab64851a72659a070.zip
Move GeoData::Triangle to global lib
-rw-r--r--game/geoData.h89
-rw-r--r--lib/triangle.h108
-rw-r--r--test/test-geoData.cpp2
3 files changed, 117 insertions, 82 deletions
diff --git a/game/geoData.h b/game/geoData.h
index dcc28e0..79924d3 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -4,6 +4,7 @@
#include "config/types.h"
#include "ray.h"
#include "surface.h"
+#include "triangle.h"
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <filesystem>
#include <glm/vec2.hpp>
@@ -52,85 +53,7 @@ public:
mutable FaceHandle _face {};
};
- template<glm::length_t Dim> struct Triangle : public glm::vec<3, glm::vec<Dim, GlobalDistance>> {
- using Point = glm::vec<Dim, GlobalDistance>;
- using base = glm::vec<3, Point>;
- using base::base;
-
- template<IterableCollection Range> Triangle(const GeoData * m, Range range)
- {
- assert(std::distance(range.begin(), range.end()) == 3);
- std::transform(range.begin(), range.end(), &base::operator[](0), [m](auto vh) {
- return m->point(vh);
- });
- }
-
- [[nodiscard]] Point
- operator*(BaryPosition bari) const
- {
- return p(0) + (::difference(p(1), p(0)) * bari.x) + (::difference(p(2), p(0)) * bari.y);
- }
-
- [[nodiscard]] Point
- centroid() const
- {
- return [this]<glm::length_t... axis>(std::integer_sequence<glm::length_t, axis...>) {
- return Point {(p(0)[axis] + p(1)[axis] + p(2)[axis]) / 3 ...};
- }(std::make_integer_sequence<glm::length_t, Dim>());
- }
-
- [[nodiscard]] auto
- area() const
- requires(Dim == 3)
- {
- return glm::length(crossProduct(::difference(p(1), p(0)), ::difference(p(2), p(0)))) / 2.F;
- }
-
- [[nodiscard]] Normal3D
- normal() const
- requires(Dim == 3)
- {
- return crossProduct(::difference(p(1), p(0)), ::difference(p(2), p(0)));
- }
-
- [[nodiscard]] Normal3D
- nnormal() const
- requires(Dim == 3)
- {
- return glm::normalize(normal());
- }
-
- [[nodiscard]] auto
- angle(glm::length_t c) const
- {
- return Arc {P(c), P(c + 2), P(c + 1)}.length();
- }
-
- template<glm::length_t D = Dim>
- [[nodiscard]] auto
- angleAt(const GlobalPosition<D> pos) const
- requires(D <= Dim)
- {
- for (glm::length_t i {}; i < 3; ++i) {
- if (GlobalPosition<D> {p(i)} == pos) {
- return angle(i);
- }
- }
- return 0.F;
- }
-
- [[nodiscard]] inline auto
- p(const glm::length_t i) const
- {
- return base::operator[](i);
- }
-
- [[nodiscard]] inline auto
- P(const glm::length_t i) const
- {
- return base::operator[](i % 3);
- }
- };
+ template<glm::length_t Dim> using Triangle = ::Triangle<Dim, GlobalDistance>;
[[nodiscard]] FaceHandle findPoint(GlobalPosition2D) const;
[[nodiscard]] FaceHandle findPoint(GlobalPosition2D, FaceHandle start) const;
@@ -178,9 +101,13 @@ public:
protected:
template<glm::length_t Dim>
[[nodiscard]] Triangle<Dim>
- triangle(FaceHandle f) const
+ triangle(FaceHandle face) const
{
- return {this, fv_range(f)};
+ Triangle<Dim> triangle;
+ std::ranges::transform(fv_range(face), triangle.begin(), [this](auto vertex) {
+ return point(vertex);
+ });
+ return triangle;
}
[[nodiscard]] static bool triangleContainsPoint(const GlobalPosition2D, const Triangle<2> &);
diff --git a/lib/triangle.h b/lib/triangle.h
new file mode 100644
index 0000000..812bfab
--- /dev/null
+++ b/lib/triangle.h
@@ -0,0 +1,108 @@
+#pragma once
+
+#include "config/types.h"
+#include "maths.h"
+#include <glm/glm.hpp>
+
+template<glm::length_t Dim, Arithmetic T, glm::qualifier Q = glm::defaultp>
+struct Triangle : public glm::vec<3, glm::vec<Dim, T, Q>> {
+ using Point = glm::vec<Dim, T, Q>;
+ using Base = glm::vec<3, glm::vec<Dim, T, Q>>;
+ using Base::Base;
+
+ [[nodiscard]] constexpr Point
+ operator*(BaryPosition bari) const
+ {
+ return p(0) + (sideDifference(1) * bari.x) + (sideDifference(2) * bari.y);
+ }
+
+ [[nodiscard]] constexpr Point
+ centroid() const
+ {
+ return [this]<glm::length_t... Axis>(std::integer_sequence<glm::length_t, Axis...>) {
+ return Point {(p(0)[Axis] + p(1)[Axis] + p(2)[Axis]) / 3 ...};
+ }(std::make_integer_sequence<glm::length_t, Dim>());
+ }
+
+ [[nodiscard]] constexpr auto
+ area() const
+ requires(Dim == 3)
+ {
+ return glm::length(crossProduct(sideDifference(1), sideDifference(2))) / T {2};
+ }
+
+ [[nodiscard]] constexpr Normal3D
+ normal() const
+ requires(Dim == 3)
+ {
+ return crossProduct(sideDifference(1), sideDifference(2));
+ }
+
+ [[nodiscard]] constexpr Normal3D
+ nnormal() const
+ requires(Dim == 3)
+ {
+ return glm::normalize(normal());
+ }
+
+ [[nodiscard]] constexpr auto
+ sideDifference(glm::length_t side) const
+ {
+ return difference(p(side), p(0));
+ }
+
+ [[nodiscard]] constexpr auto
+ angle(glm::length_t corner) const
+ {
+ return Arc {P(corner), P(corner + 2), P(corner + 1)}.length();
+ }
+
+ template<glm::length_t D = Dim>
+ [[nodiscard]] constexpr auto
+ angleAt(const glm::vec<D, T, Q> pos) const
+ requires(D <= Dim)
+ {
+ for (glm::length_t i {}; i < 3; ++i) {
+ if (glm::vec<D, T, Q> {p(i)} == pos) {
+ return angle(i);
+ }
+ }
+ return 0.F;
+ }
+
+ [[nodiscard]] constexpr auto
+ p(const glm::length_t idx) const
+ {
+ return Base::operator[](idx);
+ }
+
+ [[nodiscard]] constexpr auto
+ P(const glm::length_t idx) const
+ {
+ return Base::operator[](idx % 3);
+ }
+
+ [[nodiscard]] constexpr Point *
+ begin()
+ {
+ return &(Base::x);
+ }
+
+ [[nodiscard]] constexpr const Point *
+ begin() const
+ {
+ return &(Base::x);
+ }
+
+ [[nodiscard]] constexpr Point *
+ end()
+ {
+ return begin() + 3;
+ }
+
+ [[nodiscard]] constexpr const Point *
+ end() const
+ {
+ return begin() + 3;
+ }
+};
diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp
index 2f3d215..bd1ff87 100644
--- a/test/test-geoData.cpp
+++ b/test/test-geoData.cpp
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
{
const auto face = face_handle(0);
- BOOST_TEST_CONTEXT(GeoData::Triangle<2>(this, fv_range(face))) {
+ BOOST_TEST_CONTEXT(this->triangle<2>(face)) {
BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner, yllcorner}, face));
BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner + cellsize, yllcorner + cellsize}, face));
BOOST_CHECK(triangleContainsPoint(GlobalPosition2D {xllcorner, yllcorner + cellsize}, face));