v0.1.0: 初始工程骨架 — 7模块 40头文件 32源文件 17文档 Apache-2.0

This commit is contained in:
ViewDesignEngine
2026-07-23 05:27:51 +00:00
commit 02d0520aa5
133 changed files with 5350 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
#pragma once
#include "vde/core/point.h"
#include <algorithm>
#include <limits>
namespace vde::core {
template <typename T>
class AABB {
public:
AABB() : min_(Point3D::Constant(std::numeric_limits<T>::max())),
max_(Point3D::Constant(std::numeric_limits<T>::lowest())) {}
AABB(const Point3D& min, const Point3D& max) : min_(min), max_(max) {}
void expand(const Point3D& p) {
min_ = min_.cwiseMin(p);
max_ = max_.cwiseMax(p);
}
void expand(const AABB& other) {
min_ = min_.cwiseMin(other.min_);
max_ = max_.cwiseMax(other.max_);
}
[[nodiscard]] Point3D center() const { return (min_ + max_) * 0.5; }
[[nodiscard]] Vector3D extent() const { return max_ - min_; }
[[nodiscard]] T surface_area() const {
Vector3D e = extent();
return 2.0 * (e.x() * e.y() + e.y() * e.z() + e.z() * e.x());
}
[[nodiscard]] T volume() const {
Vector3D e = extent();
return e.x() * e.y() * e.z();
}
[[nodiscard]] bool contains(const Point3D& p) const {
return (p.array() >= min_.array()).all() && (p.array() <= max_.array()).all();
}
[[nodiscard]] bool intersects(const AABB& other) const {
return (min_.array() <= other.max_.array()).all()
&& (max_.array() >= other.min_.array()).all();
}
[[nodiscard]] const Point3D& min() const { return min_; }
[[nodiscard]] const Point3D& max() const { return max_; }
private:
Point3D min_, max_;
};
using AABB3D = AABB<double>;
using AABB3f = AABB<float>;
} // namespace vde::core
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "vde/core/point.h"
#include <vector>
namespace vde::core {
/// 2D convex hull — Graham scan, O(n log n)
std::vector<Point2D> convex_hull_2d(const std::vector<Point2D>& points);
/// 3D convex hull — QuickHull
/// Returns triangles of the hull (counter-clockwise when viewed from outside)
std::vector<std::array<Point3D, 3>> convex_hull_3d(const std::vector<Point3D>& points);
} // namespace vde::core
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "vde/core/point.h"
#include "vde/core/line.h"
#include "vde/core/plane.h"
#include "vde/core/triangle.h"
namespace vde::core {
double distance(const Point3D& a, const Point3D& b);
double distance(const Point3D& p, const Line3D<double>& line);
double distance(const Point3D& p, const Segment3D<double>& seg);
double distance(const Point3D& p, const Plane<double>& plane);
double distance(const Point3D& p, const Triangle<double>& tri);
Point3D closest_point(const Point3D& p, const Triangle<double>& tri);
Point3D closest_point(const Point3D& p, const Segment3D<double>& seg);
} // namespace vde::core
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include "vde/core/point.h"
namespace vde::core {
template <typename T>
class Line3D {
public:
Line3D() = default;
Line3D(const Point3D& origin, const Vector3D& direction)
: origin_(origin), direction_(direction.normalized()) {}
[[nodiscard]] const Point3D& origin() const { return origin_; }
[[nodiscard]] const Vector3D& direction() const { return direction_; }
[[nodiscard]] Point3D point_at(T t) const { return origin_ + direction_ * t; }
private:
Point3D origin_{0,0,0};
Vector3D direction_{1,0,0};
};
template <typename T>
class Segment3D {
public:
Segment3D() = default;
Segment3D(const Point3D& p0, const Point3D& p1) : p0_(p0), p1_(p1) {}
[[nodiscard]] const Point3D& p0() const { return p0_; }
[[nodiscard]] const Point3D& p1() const { return p1_; }
[[nodiscard]] Vector3D direction() const { return p1_ - p0_; }
[[nodiscard]] T length() const { return direction().norm(); }
private:
Point3D p0_{0,0,0}, p1_{0,0,0};
};
using Line3Dd = Line3D<double>;
using Segment3Dd = Segment3D<double>;
} // namespace vde::core
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include "vde/core/point.h"
namespace vde::core {
template <typename T>
class Plane {
public:
Plane() = default;
Plane(const Point3D& point, const Vector3D& normal)
: normal_(normal.normalized()), d_(-normal_.dot(point)) {}
Plane(const Point3D& a, const Point3D& b, const Point3D& c)
: Plane(a, (b - a).cross(c - a)) {}
[[nodiscard]] const Vector3D& normal() const { return normal_; }
[[nodiscard]] T d() const { return d_; }
[[nodiscard]] T signed_distance(const Point3D& p) const { return normal_.dot(p) + d_; }
[[nodiscard]] T distance(const Point3D& p) const { return std::abs(signed_distance(p)); }
[[nodiscard]] Point3D project(const Point3D& p) const {
return p - normal_ * signed_distance(p);
}
private:
Vector3D normal_{0,0,1};
T d_{0};
};
using Plane3D = Plane<double>;
} // namespace vde::core
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "vde/foundation/math_types.h"
#include "vde/foundation/tolerance.h"
namespace vde::core {
template <typename T, size_t Dim>
using Point = foundation::Point<T, Dim>;
using Point2D = foundation::Point2D;
using Point3D = foundation::Point3D;
using Point2f = foundation::Point2f;
using Point3f = foundation::Point3f;
template <typename T, size_t Dim>
using Vector = foundation::Vector<T, Dim>;
using Vector2D = foundation::Vector2D;
using Vector3D = foundation::Vector3D;
} // namespace vde::core
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "vde/core/point.h"
#include <vector>
namespace vde::core {
class Polygon2D {
public:
Polygon2D() = default;
explicit Polygon2D(std::vector<Point2D> vertices) : vertices_(std::move(vertices)) {}
[[nodiscard]] const std::vector<Point2D>& vertices() const { return vertices_; }
[[nodiscard]] size_t size() const { return vertices_.size(); }
[[nodiscard]] bool empty() const { return vertices_.empty(); }
/// Signed area (positive = CCW)
[[nodiscard]] double signed_area() const;
/// Absolute area
[[nodiscard]] double area() const { return std::abs(signed_area()); }
/// Point-in-polygon test (ray casting)
[[nodiscard]] bool contains(const Point2D& p) const;
/// Is the polygon counter-clockwise?
[[nodiscard]] bool is_ccw() const { return signed_area() > 0; }
private:
std::vector<Point2D> vertices_;
};
} // namespace vde::core
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "vde/core/point.h"
#include <Eigen/Geometry>
namespace vde::core {
using Transform3D = Eigen::Transform<double, 3, Eigen::Affine>;
inline Transform3D translate(const Vector3D& v) {
return Transform3D(Eigen::Translation<double, 3>(v));
}
inline Transform3D translate(double x, double y, double z) {
return translate(Vector3D(x, y, z));
}
inline Transform3D rotate(const Vector3D& axis, double angle_rad) {
return Transform3D(Eigen::AngleAxis<double>(angle_rad, axis.normalized()));
}
inline Transform3D rotate_x(double rad) { return rotate(Vector3D::UnitX(), rad); }
inline Transform3D rotate_y(double rad) { return rotate(Vector3D::UnitY(), rad); }
inline Transform3D rotate_z(double rad) { return rotate(Vector3D::UnitZ(), rad); }
inline Transform3D scale(double sx, double sy, double sz) {
return Transform3D(Eigen::Scaling(sx, sy, sz));
}
inline Transform3D scale(double s) { return scale(s, s, s); }
} // namespace vde::core
+42
View File
@@ -0,0 +1,42 @@
#pragma once
#include "vde/core/point.h"
#include <array>
namespace vde::core {
template <typename T>
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<Point3D, 3>& 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<Point3D, 3> v_{};
};
using Triangle3D = Triangle<double>;
using Triangle3f = Triangle<float>;
} // namespace vde::core