Files
ViewDesignEngine/include/vde/core/triangle.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

110 lines
3.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/core/point.h"
#include <array>
namespace vde::core {
/**
* @brief 三维三角形
*
* 由三个顶点定义的平面三角形面片。
* 支持面积、法线、质心、重心坐标包含测试。
*
* @tparam T 标量类型(通常为 double
*
* @ingroup core
*/
template <typename T>
class Triangle {
public:
/// 默认构造:三个顶点均在原点(退化三角形)
Triangle() = default;
/**
* @brief 从三个顶点构造三角形
*
* @param v0 第一个顶点
* @param v1 第二个顶点
* @param v2 第三个顶点
*/
Triangle(const Point3D& v0, const Point3D& v1, const Point3D& v2)
: v_{v0, v1, v2} {}
/**
* @brief 获取第 i 个顶点
*
* @param i 顶点索引(0, 1, 2
* @return 顶点引用
*/
[[nodiscard]] const Point3D& v(int i) const { return v_[i]; }
/// 获取所有顶点数组
[[nodiscard]] const std::array<Point3D, 3>& vertices() const { return v_; }
/**
* @brief 三角形单位法向量
*
* 使用 (v1 - v0) × (v2 - v0) 的归一化结果。
* 依右手定则方向。
*
* @return 单位法向量
*
* @note 若三角形退化(面积为零),返回零向量
*/
[[nodiscard]] Vector3D normal() const {
return (v_[1] - v_[0]).cross(v_[2] - v_[0]).normalized();
}
/**
* @brief 三角形面积
* @return 0.5 * ||(v1 - v0) × (v2 - v0)||
*/
[[nodiscard]] T area() const {
return (v_[1] - v_[0]).cross(v_[2] - v_[0]).norm() * 0.5;
}
/**
* @brief 三角形质心(几何中心)
* @return (v0 + v1 + v2) / 3
*/
[[nodiscard]] Point3D centroid() const {
return (v_[0] + v_[1] + v_[2]) / 3.0;
}
/**
* @brief 重心坐标包含测试
*
* 将点 p 正交投影到三角形平面上,计算重心坐标并判断是否在三角形内。
*
* @param p 测试点(三维空间中的任意点)
* @return true 若投影点在三角形内部或边界上
*
* @note 该测试等效于三维点在三角形上的包含测试(先投影再测试)
*
* @code{.cpp}
* Triangle3D tri({0,0,0}, {1,0,0}, {0,1,0});
* bool in1 = tri.contains(Point3D(0.2, 0.2, 0)); // true
* bool in2 = tri.contains(Point3D(0.2, 0.2, 5)); // true (投影后判断)
* @endcode
*/
[[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<Point3D, 3> v_{};
};
/// 双精度三维三角形
using Triangle3D = Triangle<double>;
/// 单精度三维三角形
using Triangle3f = Triangle<float>;
} // namespace vde::core