181 lines
4.5 KiB
Markdown
181 lines
4.5 KiB
Markdown
# 数据结构设计
|
||
|
||
## 目录
|
||
|
||
1. [基础数学类型](#1-基础数学类型)
|
||
2. [半边数据结构](#2-半边数据结构)
|
||
3. [NURBS 数据结构](#3-nurbs-数据结构)
|
||
4. [BVH 数据结构](#4-bvh-数据结构)
|
||
5. [公差系统](#5-公差系统)
|
||
|
||
---
|
||
|
||
## 1. 基础数学类型
|
||
|
||
### 1.1 点与向量
|
||
|
||
```cpp
|
||
// 基于 Eigen 的类型别名
|
||
template <typename T, size_t Dim>
|
||
using Point = Eigen::Matrix<T, Dim, 1>;
|
||
|
||
template <typename T, size_t Dim>
|
||
using Vector = Eigen::Matrix<T, Dim, 1>;
|
||
|
||
using Point2D = Point<double, 2>;
|
||
using Point3D = Point<double, 3>;
|
||
using Vector2D = Vector<double, 2>;
|
||
using Vector3D = Vector<double, 3>;
|
||
using Matrix4D = Eigen::Matrix<double, 4, 4>;
|
||
```
|
||
|
||
### 1.2 直线、射线与线段
|
||
|
||
```cpp
|
||
// 无限直线
|
||
class Line3D {
|
||
Point3D origin_;
|
||
Vector3D direction_; // 已归一化
|
||
};
|
||
|
||
// 单向射线(t ≥ 0)
|
||
class Ray3D {
|
||
Point3D origin_;
|
||
Vector3D direction_; // 已归一化
|
||
};
|
||
|
||
// 有限线段
|
||
class Segment3D {
|
||
Point3D p0_, p1_;
|
||
};
|
||
```
|
||
|
||
### 1.3 包围盒
|
||
|
||
```cpp
|
||
class AABB3D {
|
||
Point3D min_, max_;
|
||
// 核心方法:expand(), center(), extent(), surface_area(),
|
||
// volume(), contains(), intersects()
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 半边数据结构
|
||
|
||
半边是网格核心数据结构,支持高效的拓扑遍历:
|
||
|
||
```
|
||
prev(e) next(e)
|
||
●─────────────●─────────────●
|
||
◄──── e ────
|
||
vert(e) face(e) vert(next(e))
|
||
```
|
||
|
||
### 2.1 数据布局
|
||
|
||
```cpp
|
||
class HalfedgeMesh {
|
||
std::vector<Point3D> vertices_; // 顶点坐标
|
||
std::vector<Halfedge> halfedges_; // 半边数组
|
||
std::vector<Face> faces_; // 面数组
|
||
// 惰性计算缓存
|
||
std::vector<Vector3D> face_normals_;
|
||
std::vector<Vector3D> vertex_normals_;
|
||
bool normals_dirty_ = true;
|
||
};
|
||
|
||
struct Halfedge {
|
||
int vertex_index; // 半边指向的顶点
|
||
int face_index; // 半边所属的面(-1 = 边界)
|
||
int next_index; // 下一条半边
|
||
int prev_index; // 上一条半边
|
||
int opposite_index; // 对侧半边
|
||
};
|
||
|
||
struct Face {
|
||
int halfedge_index; // 该面的起始半边
|
||
int valence; // 边数(三角形=3,四边形=4)
|
||
};
|
||
```
|
||
|
||
### 2.2 拓扑遍历模式
|
||
|
||
- **遍历面的边**:`for (he = face.he; ; he = he.next)`
|
||
- **遍历顶点邻接面**:`do { he = he.next.opposite; } while (he != start)`
|
||
- **遍历顶点一环邻域**:沿半边链遍历相邻顶点
|
||
|
||
---
|
||
|
||
## 3. NURBS 数据结构
|
||
|
||
### 3.1 NURBS 曲线
|
||
|
||
```cpp
|
||
class NurbsCurve {
|
||
int degree_; // 阶数
|
||
std::vector<Point3D> control_points_; // 控制点
|
||
std::vector<double> knots_; // 节点向量
|
||
std::vector<double> weights_; // 权重
|
||
std::pair<double, double> domain_; // 有效参数域 [u_p, u_n+1]
|
||
};
|
||
```
|
||
|
||
### 3.2 NURBS 曲面
|
||
|
||
```cpp
|
||
class NurbsSurface {
|
||
int degree_u_, degree_v_;
|
||
std::vector<std::vector<Point3D>> control_points_; // u×v 网格
|
||
std::vector<double> knots_u_, knots_v_;
|
||
std::vector<std::vector<double>> weights_;
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
## 4. BVH 数据结构
|
||
|
||
```cpp
|
||
class BVH {
|
||
struct Node {
|
||
AABB3D bounds; // 包围盒
|
||
int left_child; // 左子节点索引(-1 = 无)
|
||
int right_child; // 右子节点索引(-1 = 无)
|
||
int first_primitive; // 叶节点:起始图元索引
|
||
int primitive_count; // 叶节点:图元数量
|
||
bool is_leaf() const;
|
||
};
|
||
|
||
std::vector<Node> nodes_; // 扁平数组(缓存友好)
|
||
std::vector<Triangle3D> primitives_; // 图元数组
|
||
BVHSplitStrategy strategy_; // 分割策略:Middle / Equal / SAH
|
||
};
|
||
```
|
||
|
||
**设计要点**:节点存储在连续数组中(而非树形指针),利用 CPU 缓存局部性,大幅加速遍历。
|
||
|
||
---
|
||
|
||
## 5. 公差系统
|
||
|
||
```cpp
|
||
class Tolerance {
|
||
double absolute_; // 绝对公差(默认 1e-6)
|
||
double relative_; // 相对公差(默认 1e-8)
|
||
double angular_; // 角度公差(默认 1e-8 rad)
|
||
double snapping_; // 吸附距离(默认 1e-4)
|
||
|
||
public:
|
||
// 两点是否重合
|
||
bool points_equal(const Point3D& a, const Point3D& b) const;
|
||
// 值是否为零
|
||
bool is_zero(double value) const;
|
||
// 全局单例
|
||
static Tolerance& global();
|
||
};
|
||
```
|
||
|
||
**设计要点**:全局 + 局部两级公差管理。全局公差作为默认值,各个算法可以创建局部实例覆盖。
|