2026-07-23 05:27:51 +00:00
|
|
|
|
#pragma once
|
2026-07-23 08:19:24 +00:00
|
|
|
|
#include <Eigen/Core>
|
2026-07-23 05:27:51 +00:00
|
|
|
|
#include <cmath>
|
|
|
|
|
|
#include <limits>
|
2026-07-23 09:58:38 +00:00
|
|
|
|
#include <vector>
|
2026-07-23 05:27:51 +00:00
|
|
|
|
|
|
|
|
|
|
namespace vde::foundation {
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 分层容差管理类
|
|
|
|
|
|
*
|
|
|
|
|
|
* 提供四级容差(绝对、相对、角度、吸附),支持全局实例和局部作用域覆盖。
|
|
|
|
|
|
* 用于数值比较、几何判定和点合并时的精度控制。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 四级容差含义:
|
|
|
|
|
|
* - **绝对容差 (absolute)**: 对接近零的值使用,直接比较差值的绝对值
|
|
|
|
|
|
* - **相对容差 (relative)**: 对大值使用,比较差值 / max(|a|, |b|)
|
|
|
|
|
|
* - **角度容差 (angular)**: 角度/方向比较时的阈值(弧度)
|
|
|
|
|
|
* - **吸附容差 (snapping)**: 点合并/对齐时的容差,通常比判定容差宽松
|
|
|
|
|
|
*
|
|
|
|
|
|
* 预设精度等级:
|
|
|
|
|
|
* - Modeling(): 1e-6 — 通用建模精度
|
|
|
|
|
|
* - Fitting(): 1e-3 — 近似拟合
|
|
|
|
|
|
* - Intersection(): 1e-8 — 精确求交
|
|
|
|
|
|
* - Snapping(): 1e-4 — 点吸附
|
|
|
|
|
|
*
|
|
|
|
|
|
* @ingroup foundation
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
class Tolerance {
|
|
|
|
|
|
public:
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 构造容差对象
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param absolute 绝对容差,默认 1e-6
|
|
|
|
|
|
* @param relative 相对容差,默认 1e-8
|
|
|
|
|
|
* @param angular 角度容差(弧度),默认 1e-8
|
|
|
|
|
|
* @param snapping 吸附容差,默认 1e-4
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
Tolerance(double absolute = 1e-6, double relative = 1e-8,
|
|
|
|
|
|
double angular = 1e-8, double snapping = 1e-4)
|
|
|
|
|
|
: absolute_(absolute), relative_(relative),
|
|
|
|
|
|
angular_(angular), snapping_(snapping) {}
|
|
|
|
|
|
|
2026-07-23 09:58:38 +00:00
|
|
|
|
// ── 判定 ──
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 判断两点是否相等(基于绝对容差)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 使用欧氏距离与绝对容差比较。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param a 第一个点(Eigen 矩阵)
|
|
|
|
|
|
* @param b 第二个点(Eigen 矩阵)
|
|
|
|
|
|
* @return true 若两点的欧氏距离 < absolute_
|
|
|
|
|
|
*/
|
2026-07-23 08:19:24 +00:00
|
|
|
|
bool points_equal(const Eigen::MatrixXd& a, const Eigen::MatrixXd& b) const {
|
2026-07-23 05:27:51 +00:00
|
|
|
|
return (a - b).norm() < absolute_;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 判断值是否接近零
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param value 测试值
|
|
|
|
|
|
* @return true 若 |value| < absolute_
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
template <typename T>
|
|
|
|
|
|
bool is_zero(T value) const {
|
|
|
|
|
|
return std::abs(value) < absolute_;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 混合容差相等判断
|
|
|
|
|
|
*
|
|
|
|
|
|
* 综合使用绝对和相对容差:
|
|
|
|
|
|
* |a - b| < absolute + relative * max(|a|, |b|)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @tparam T 数值类型
|
|
|
|
|
|
* @param a 第一个值
|
|
|
|
|
|
* @param b 第二个值
|
|
|
|
|
|
* @return true 若两值在容差范围内相等
|
|
|
|
|
|
*
|
|
|
|
|
|
* @code{.cpp}
|
|
|
|
|
|
* Tolerance tol(1e-6, 1e-8);
|
|
|
|
|
|
* tol.equals(1.0000001, 1.0); // true
|
|
|
|
|
|
* tol.equals(1000.0001, 1000.0); // true (相对项起作用)
|
|
|
|
|
|
* @endcode
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
template <typename T>
|
|
|
|
|
|
bool equals(T a, T b) const {
|
|
|
|
|
|
return std::abs(a - b) < absolute_ + relative_ * std::max(std::abs(a), std::abs(b));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/// 获取绝对容差
|
2026-07-23 08:19:24 +00:00
|
|
|
|
double absolute() const { return absolute_; }
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/// 获取相对容差
|
2026-07-23 08:19:24 +00:00
|
|
|
|
double relative() const { return relative_; }
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/// 获取角度容差
|
2026-07-23 08:19:24 +00:00
|
|
|
|
double angular() const { return angular_; }
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/// 获取吸附容差
|
2026-07-23 08:19:24 +00:00
|
|
|
|
double snapping() const { return snapping_; }
|
2026-07-23 05:27:51 +00:00
|
|
|
|
|
2026-07-23 09:58:38 +00:00
|
|
|
|
// ── 分层容差:继承并收紧 ──
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 收紧容差
|
|
|
|
|
|
*
|
|
|
|
|
|
* 所有容差乘以 factor(< 1),用于在子操作中提高精度要求。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param factor 收紧因子(默认 0.1)
|
|
|
|
|
|
* @return 收紧后的新容差对象
|
|
|
|
|
|
*
|
|
|
|
|
|
* @code{.cpp}
|
|
|
|
|
|
* auto rough = Tolerance(Tolerance::Fitting());
|
|
|
|
|
|
* auto precise = rough.tighten(0.01); // 拟合 → 建模级
|
|
|
|
|
|
* @endcode
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
Tolerance tighten(double factor = 0.1) const {
|
|
|
|
|
|
return Tolerance(absolute_ * factor, relative_ * factor, angular_ * factor, snapping_ * factor);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 放宽容差
|
|
|
|
|
|
*
|
|
|
|
|
|
* 所有容差乘以 factor(> 1),用于在上层操作中降低精度要求。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param factor 放宽因子(默认 10.0)
|
|
|
|
|
|
* @return 放宽后的新容差对象
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
Tolerance relax(double factor = 10.0) const {
|
|
|
|
|
|
return Tolerance(absolute_ * factor, relative_ * factor, angular_ * factor, snapping_ * factor);
|
|
|
|
|
|
}
|
2026-07-23 05:27:51 +00:00
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 合并两个容差,取更严格的(更小的)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param a 第一个容差
|
|
|
|
|
|
* @param b 第二个容差
|
|
|
|
|
|
* @return 每项取 min 的新容差
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
static Tolerance min(const Tolerance& a, const Tolerance& b) {
|
|
|
|
|
|
return Tolerance(std::min(a.absolute_, b.absolute_),
|
|
|
|
|
|
std::min(a.relative_, b.relative_),
|
|
|
|
|
|
std::min(a.angular_, b.angular_),
|
|
|
|
|
|
std::min(a.snapping_, b.snapping_));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── 全局实例 ──
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取全局容差实例
|
|
|
|
|
|
*
|
|
|
|
|
|
* 线程局部存储,默认值为建模精度 (1e-6)。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return 全局容差的引用
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
static Tolerance& global() { return global_; }
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置全局容差
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param tol 新的全局容差
|
|
|
|
|
|
*
|
|
|
|
|
|
* @note 推荐使用 ToleranceScope 进行临时修改,确保自动恢复
|
|
|
|
|
|
*/
|
2026-07-23 05:27:51 +00:00
|
|
|
|
static void set_global(const Tolerance& tol) { global_ = tol; }
|
|
|
|
|
|
|
2026-07-23 09:58:38 +00:00
|
|
|
|
// ── 默认建模容差等级 ──
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/// 建模级精度 (1e-6):通用几何建模
|
|
|
|
|
|
static constexpr double Modeling() { return 1e-6; }
|
|
|
|
|
|
/// 拟合级精度 (1e-3):曲面拟合、近似计算
|
|
|
|
|
|
static constexpr double Fitting() { return 1e-3; }
|
|
|
|
|
|
/// 求交级精度 (1e-8):精确求交、布尔运算
|
|
|
|
|
|
static constexpr double Intersection() { return 1e-8; }
|
|
|
|
|
|
/// 吸附级精度 (1e-4):点合并、顶点焊接
|
|
|
|
|
|
static constexpr double Snapping() { return 1e-4; }
|
2026-07-23 09:58:38 +00:00
|
|
|
|
|
2026-07-23 05:27:51 +00:00
|
|
|
|
private:
|
|
|
|
|
|
double absolute_;
|
|
|
|
|
|
double relative_;
|
|
|
|
|
|
double angular_;
|
|
|
|
|
|
double snapping_;
|
|
|
|
|
|
static Tolerance global_;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 局部容差作用域(RAII)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 构造时设置新的全局容差,析构时自动恢复为之前的值。
|
|
|
|
|
|
* 用于在特定代码块内临时修改容差。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @code{.cpp}
|
|
|
|
|
|
* void precise_operation() {
|
|
|
|
|
|
* ToleranceScope scope(Tolerance::Intersection());
|
|
|
|
|
|
* // 在此作用域内使用求交级精度
|
|
|
|
|
|
* // ... 布尔运算 ...
|
|
|
|
|
|
* } // scope 析构,自动恢复
|
|
|
|
|
|
* @endcode
|
|
|
|
|
|
*
|
|
|
|
|
|
* @ingroup foundation
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
class ToleranceScope {
|
|
|
|
|
|
public:
|
2026-07-24 11:04:04 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 进入新的容差作用域
|
|
|
|
|
|
*
|
|
|
|
|
|
* 保存当前全局容差并设置新值。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param tol 此作用域内使用的容差
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
explicit ToleranceScope(const Tolerance& tol) : previous_(Tolerance::global()) {
|
|
|
|
|
|
Tolerance::set_global(tol);
|
|
|
|
|
|
}
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 退出容差作用域,恢复之前的全局容差
|
|
|
|
|
|
*/
|
2026-07-23 09:58:38 +00:00
|
|
|
|
~ToleranceScope() { Tolerance::set_global(previous_); }
|
2026-07-24 11:04:04 +00:00
|
|
|
|
|
2026-07-23 09:58:38 +00:00
|
|
|
|
private:
|
|
|
|
|
|
Tolerance previous_;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-07-23 05:27:51 +00:00
|
|
|
|
} // namespace vde::foundation
|