diff --git a/primitive_process/interface/subface/simple/cylinder_face.hpp b/primitive_process/interface/subface/simple/cylinder_face.hpp index 7376fa3..97a721f 100644 --- a/primitive_process/interface/subface/simple/cylinder_face.hpp +++ b/primitive_process/interface/subface/simple/cylinder_face.hpp @@ -34,20 +34,40 @@ template <> struct hasher { size_t operator()(const internal::cylinder_paired_model_matrix &block) const { - const auto& mat = block.data->world_to_local.matrix(); // 3x4 + // 使用 world_to_local 矩阵(4x4 齐次变换) + const auto& mat = block.data->world_to_local.matrix(); // 4x4 + + // 提取线性部分 A (3x3) 和平移部分 b (3x1) Eigen::Matrix3d A = mat.block<3,3>(0,0); - Eigen::Vector3d b = mat.col(3); + Eigen::Vector3d b = mat.block<3,1>(0,3); + + // ✅ 直接使用 A 的前两行作为 R(不需要逆) + // 因为 A 就是 world_to_local 的线性部分,row(0)=x, row(1)=y + Eigen::Matrix R; + R.row(0) = A.row(0); + R.row(1) = A.row(1); - Eigen::Matrix3d B = A.inverse(); - Eigen::Matrix R = B.topRows<2>(); + // ✅ 归一化 R 的行向量(消除缩放影响) + double norm0 = R.row(0).norm(); + double norm1 = R.row(1).norm(); + if (norm0 > 1e-8) R.row(0) /= norm0; + if (norm1 > 1e-8) R.row(1) /= norm1; + // G = R^T * R 编码横截面方向(已归一化,对旋转/缩放鲁棒) Eigen::Matrix3d G = R.transpose() * R; - Eigen::Vector2d zero_proj = R * b; - size_t h = XXH3_64bits(G.data(), sizeof(Eigen::Matrix3d)); - h ^= XXH3_64bits(zero_proj.data(), sizeof(Eigen::Vector2d)); + // ❌ 原始 R*b 依赖局部坐标系旋转 + // ✅ 改为:只使用 ||R*b||^2(旋转不变)或投影长度平方 + Eigen::Vector2d rp = R * b; + double radial_proj_sq = rp.squaredNorm(); // 旋转不变量 + + // 构造哈希键:G (3x3) + radial_proj_sq (1 double) + // 使用紧凑方式避免结构体 + Eigen::Matrix hash_key; + hash_key.head<9>() = Eigen::Map>(G.data()); + hash_key(9) = radial_proj_sq; - return h; + return XXH3_64bits(hash_key.data(), sizeof(double) * 10); } }; diff --git a/primitive_process/interface/subface/simple/plane.hpp b/primitive_process/interface/subface/simple/plane.hpp index 698d806..48db39e 100644 --- a/primitive_process/interface/subface/simple/plane.hpp +++ b/primitive_process/interface/subface/simple/plane.hpp @@ -35,10 +35,30 @@ struct hasher { size_t operator()(const internal::plane_paired_model_matrix &block) const { const auto& mat = block.data->local_to_world.matrix(); - Eigen::Matrix character_col; - character_col.col(0) = mat.col(0); - character_col.col(1) = mat.col(3); - return XXH3_64bits(character_col.data(), sizeof(Eigen::Matrix)); + + Eigen::Vector3d n_vec = mat.col(0); + double tz = mat.col(3).transpose().dot(n_vec); + double norm = n_vec.norm(); + if (norm < 1e-8) { + n_vec = Eigen::Vector3d::UnitZ(); + norm = 1.0; + } else { + n_vec /= norm; + } + double d = -tz / norm; // 平面方程: n·x = d + + // 可选:统一法向方向(例如让 z 分量优先为正) + if (n_vec[2] < -1e-8 || + (std::abs(n_vec[2]) < 1e-8 && (n_vec[1] < -1e-8 || + (std::abs(n_vec[1]) < 1e-8 && n_vec[0] < 0)))) { + n_vec = -n_vec; + d = -d; + } + + Eigen::Vector4d hash_key; + hash_key << n_vec, d; + + return XXH3_64bits(hash_key.data(), sizeof(Eigen::Vector4d)); } };