Browse Source

fix: 'calculate_closest_param' phi error

main
linchforever 3 days ago
parent
commit
16f32e18cc
  1. 34
      primitive_process/interface/primitive_descriptor.h
  2. 32
      primitive_process/interface/subface/geometry/polyline_fillet.hpp
  3. 53
      primitive_process/src/subface/geometry/geometry_data.cpp

34
primitive_process/interface/primitive_descriptor.h

@ -25,13 +25,13 @@ typedef enum {
// double value; // Use 0 to represent an empty body
// } constant_descriptor_t;
// Plane descriptor
typedef struct {
// Plane descriptor
typedef struct {
//vector3d point; // The base point of the plane
//vector3d normal; // The normal of the plane
vector2d local_aabb_min;
vector2d local_aabb_max;
} plane_descriptor_t;
vector2d local_aabb_min;
vector2d local_aabb_max;
} plane_descriptor_t;
// Sphere descriptor
typedef struct {
@ -156,10 +156,10 @@ inline constexpr cylinder_descriptor_t unit_cylinder{
/// @brief 单位正方形 profile
inline const polyline_descriptor_t unit_square_profile = [] {
static const std::vector<vector3d> points = {
//{-0.5, -0.5, 0.0},
//{0.5, -0.5, 0.0},
//{0.5, 0.5, 0.0},
//{-0.5, 0.5, 0.0}
{-0.5, -0.5, 0.0},
{0.5, -0.5, 0.0},
{0.5, 0.5, 0.0},
{-0.5, 0.5, 0.0}
//{-1.5, -1.5, 0.0},
//{1.5, -1.5, 0.0},
@ -170,19 +170,19 @@ inline const polyline_descriptor_t unit_square_profile = [] {
//{2.0, -0.430871, 0.902414 }, // 局部坐标: (-1, -1)
//{2.0, 0.430871, -0.902414} // 局部坐标: (1, -1)
{0.0, 0.430871, -0.902414},
{0.0, -0.430871, 0.902414 },
{2.0, 0.1, -0.6},
{2.0, 0.430871, -0.902414}
//{0.0, 0.430871, -0.902414},
//{0.0, -0.430871, 0.902414 },
//{2.0, 0.1, -0.6},
//{2.0, 0.430871, -0.902414}
//{0.0, 0.430871, -0.902414}, // 局部坐标: (1, 1)
//{1.0, -0.430871, 0.902414 },
//{6.0, 0.430871, -0.902414} // 局部坐标: (1, -1)
};
// static const std::vector<double> bulges = {0.4, -0.8, 1.0, -0.5};
static const std::vector<double> bulges = {0.4, -0.8, 1.0, -0.5};
// static const std::vector<double> bulges = {-0.4, 0.8, 0.0, -0.5}; // polyline ERROR
// static const std::vector<double> bulges = {0.0, 0.0, -0.5, 0.0}; // helixline ERROR
static const std::vector<double> bulges = {0.0, 0.0, 1.0, 0.0}; // helixline ERROR
//static const std::vector<double> bulges = {0.0, 0.0, 1.0, 0.0}; // helixline ERROR
polyline_descriptor_t desc;
desc.point_number = 4;
desc.points = const_cast<vector3d*>(points.data());
@ -195,12 +195,12 @@ inline const polyline_descriptor_t unit_square_profile = [] {
inline const std::vector<vector3d> unit_axis_points = {
{0.0, 0.0, -0.5},
{0.0, 6.0, 6.0 }
{1.0, 0.0, 1.0 }
//{4.0, 0.0, 1.0}
//{4.0, 0.0, -1.0}
};
inline const std::vector<double> unit_axis_bulges = {0.0};
inline const std::vector<double> unit_axis_bulges = {0.0, 0.0};
inline const polyline_descriptor_t unit_polyline_axis = [] {
polyline_descriptor_t desc;

32
primitive_process/interface/subface/geometry/polyline_fillet.hpp

@ -6,25 +6,23 @@ namespace internal
{
struct fillet_config_t {
// 圆角切除量占相邻两段中较短段弦长的比例(默认 5%)
// 越小则圆角越微小,棱角感越强。
double segment_ratio = 0.05;
// 低于此角度(度)的衔接处视为共线,跳过不处理
double min_turn_angle_deg = 0.5;
double segment_ratio = 0.05 ;// 圆角切除量占相邻两段中较短段弦长的比例
double min_turn_angle_deg = 0.5; // 低于此角度(度)的衔接处视为共线,跳过
// 最小圆角半径。
double min_fillet_radius = 0.0;
// 当锐角过尖(turn_angle > max_fillet_angle_deg),
// 即使达到 min_fillet_radius 也无法避免自相交时的处理策略:
// true → 跳过该顶点(保留原始尖角,不插入圆弧)
// false → 用最大允许 trim 插入圆弧(会有轻微自相交,但尽力修复)
bool is_axis = false;
};
// 对 2D profile 多段线的衔接顶点插入微小圆角弧,实现 G1 连续。
//
// 闭合多边形:处理全部 n 个顶点,输出隐式首尾相连。
// 不闭合多段线:仅处理内部顶点 [1, n-2],首尾端点原样保留。
//
// @param profile 原始 profile descriptor(通过 is_closed 区分开闭)
// @param out_points 输出点列表
// @param out_bulges 输出 bulge 列表(与 out_points 等长)
// @param cfg 圆角参数
// 对 2D profile / axis 多段线的衔接顶点插入微小圆角弧,实现 G1 连续。
void insert_polyline_corner_fillets(const polyline_descriptor_t& profile,
std::vector<vector3d>& out_points,
std::vector<double>& out_bulges,
const fillet_config_t& cfg = {});
std::vector<vector3d>& out_points,
std::vector<double>& out_bulges,
const fillet_config_t& cfg = {});
} // namespace internal

53
primitive_process/src/subface/geometry/geometry_data.cpp

@ -374,9 +374,6 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&&
const auto base_vec1 = *iter - *(iter + 1); // 起点 - 圆心
const auto base_vec2 = *(iter + 2) - *(iter + 1); // 切线辅助点 d - 圆心 c
Eigen::Vector2d p_vec;
double cross_bv = base_vec1.x() * base_vec2.y() - base_vec1.y() * base_vec2.x();
bool is_cw = (cross_bv < 0);
if (this->is_axis) {
p_vec = Eigen::Vector2d(p[2], p[0]) - *(iter + 1);
} else {
@ -397,22 +394,12 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&&
const auto local_x = base_vec1.dot(p_vec);
const auto local_y = base_vec2.dot(p_vec);
double phi = std::atan2(local_y, local_x);
// 根据圆弧转向调整 phi
if (!is_cw) {
// CCW: 有效区间 [0, theta]
if (theta > pi + 1e-9) {
if (phi < -EPSILON) phi += two_pi;
} else {
if (phi < -EPSILON) phi = -1.0; // 触发端点回退
}
if (theta > pi + 1e-9) {
if (phi < -EPSILON) { phi += two_pi; }
} else {
// CW: 有效区间 [-theta, 0],翻转后统一用 [0, theta] 处理
phi = -phi; // 将 CW 的 phi 反号,使有效范围变为 [0, theta]
if (theta > pi + 1e-9) {
if (phi < -EPSILON) phi += two_pi;
} else {
if (phi < -EPSILON) phi = -1.0;
// 劣弧:phi 只应在 [0, theta],负值直接视为 gap
if (phi < -EPSILON) {
phi = -1.0; // 强制触发端点回退
}
}
@ -438,7 +425,7 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&&
std::sqrt(off_plane * off_plane + dis_on_plane * dis_on_plane),
1.,
true
};
};
};
// 计算每个线段的最近点
@ -452,10 +439,10 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&&
// 全局最小值:segment 内局部 t ∈ [0,1],加上段索引得到全局 t
const auto iter = std::min_element(closest_params.begin(), closest_params.end());
iter->t += static_cast<double>(std::distance(closest_params.begin(), iter));
return {
return {
line_closest_param_t{std::move(iter->point), iter->t, iter->is_peak_value},
iter->dist * iter->dist_sign
};
};
}
[[nodiscard]] bool polyline_geometry_data::pmc(const Eigen::Ref<const Eigen::Vector2d>& p,
@ -703,30 +690,6 @@ Eigen::Vector3d helixline_geometry_data::calculate_normal(double t) const
// return {f0 / (f0 - f1), true, true};
return {t0 + (t1 - t0) * f0 / (f0 - f1), true, true};
});
// [JUMP_DEBUG] 检测是否存在近似等距的第二候选点
const double best_sq = sq_dist_at(peak_value_param.t);
double second_sq = std::numeric_limits<double>::max();
double second_t = -1.0;
for (int64_t k_ = static_cast<int64_t>(rounded_times_start); k_ <= static_cast<int64_t>(rounded_times_end); ++k_) {
const double t_cand = (theta_p + pi / 2.0 + k_ * pi) * inv_line_theta;
if (t_cand < 0.0 || t_cand > 1.0) continue;
const double sq = sq_dist_at(t_cand);
if (sq > best_sq + 1e-14 && sq < second_sq) {
second_sq = sq;
second_t = t_cand;
}
}
const double gap = std::sqrt(second_sq) - std::sqrt(best_sq);
if (gap < 0.05 && std::sqrt(best_sq) < this->radius * 2.0) { // 仅关注近表面
static std::atomic<int> cnt{0};
if (++cnt <= 100) {
std::cout << "[JUMP_WARN] #" << cnt << " best_t=" << peak_value_param.t << " dist=" << std::sqrt(best_sq)
<< " | second_t=" << second_t << " dist=" << std::sqrt(second_sq) << " gap=" << gap << "\n";
}
}
}
// if we need to refine the guess, just do it!!!

Loading…
Cancel
Save