#pragma once #include "vde/core/point.h" #include namespace vde::core { template class Triangle { public: Triangle() = default; Triangle(const Point3D& v0, const Point3D& v1, const Point3D& v2) : v_{v0, v1, v2} {} [[nodiscard]] const Point3D& v(int i) const { return v_[i]; } [[nodiscard]] const std::array& vertices() const { return v_; } [[nodiscard]] Vector3D normal() const { return (v_[1] - v_[0]).cross(v_[2] - v_[0]).normalized(); } [[nodiscard]] T area() const { return (v_[1] - v_[0]).cross(v_[2] - v_[0]).norm() * 0.5; } [[nodiscard]] Point3D centroid() const { return (v_[0] + v_[1] + v_[2]) / 3.0; } [[nodiscard]] bool contains(const Point3D& p) const { Vector3D v0 = v_[2] - v_[0], v1 = v_[1] - v_[0], v2 = p - v_[0]; T d00 = v0.dot(v0), d01 = v0.dot(v1), d11 = v1.dot(v1); T d20 = v2.dot(v0), d21 = v2.dot(v1); T denom = d00 * d11 - d01 * d01; T v = (d11 * d20 - d01 * d21) / denom; T w = (d00 * d21 - d01 * d20) / denom; return v >= 0 && w >= 0 && v + w <= 1; } private: std::array v_{}; }; using Triangle3D = Triangle; using Triangle3f = Triangle; } // namespace vde::core