You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于位运算的3D坐标点八分象限计数:修正索引匹配问题

修正位运算实现的八分象限计数索引匹配问题

问题背景

我需要实现一个和OctantPopCount功能完全一致,但无if语句的八分象限计数函数。通过位运算实现的octant_count函数功能正常,但象限统计的索引和原函数不匹配——比如全正分量的点在原函数中对应counters[0],但在位运算实现中对应counters[7]。需要修正此索引匹配问题。

原OctantPopCount函数

#include <vector>
#include <array>

struct Point3D {
    double x, y, z;
};

std::array<int, 8> OctantPopCount(const std::vector<Point3D>& points) {
    std::array<int, 8> counters = {0};
    for (const auto& p : points) {
        if (p.x >= 0 && p.y >= 0 && p.z >= 0) {
            counters[0]++;
        } else if (p.x < 0 && p.y >= 0 && p.z >= 0) {
            counters[1]++;
        } else if (p.x < 0 && p.y < 0 && p.z >= 0) {
            counters[2]++;
        } else if (p.x >= 0 && p.y < 0 && p.z >= 0) {
            counters[3]++;
        } else if (p.x >= 0 && p.y >= 0 && p.z < 0) {
            counters[4]++;
        } else if (p.x < 0 && p.y >= 0 && p.z < 0) {
            counters[5]++;
        } else if (p.x < 0 && p.y < 0 && p.z < 0) {
            counters[6]++;
        } else if (p.x >= 0 && p.y < 0 && p.z < 0) {
            counters[7]++;
        }
    }
    return counters;
}

初始位运算实现(索引不匹配)

std::array<int, 8> octant_count(const std::vector<Point3D>& points) {
    std::array<int, 8> counters = {0};
    for (const auto& p : points) {
        // 正分量对应1,负分量对应0,全正组合为111=7,与原函数索引规则不符
        int x_sign = (p.x >= 0) ? 1 : 0;
        int y_sign = (p.y >= 0) ? 1 : 0;
        int z_sign = (p.z >= 0) ? 1 : 0;
        int index = (z_sign << 2) | (y_sign << 1) | x_sign;
        counters[index]++;
    }
    return counters;
}

测试结果对比

测试用例:包含全正点(1,1,1)、全负点(-1,-1,-1)、x负y正z正点(-1,1,1)各1个

  • 原函数返回:[1, 1, 0, 0, 0, 0, 1, 0]
  • 初始位运算实现返回:[0, 0, 0, 0, 0, 0, 1, 1](全正点统计到counters[7],全负点统计到counters[0],x负y正z正点统计到counters[6])

可行的修正方法

  • 索引反转法:在位运算生成初始索引后,用7 - index得到修正后的索引。由于8个象限的索引范围是0-7,反转后正好将全正对应的7转为0,完全对齐原函数的索引规则。
  • 索引映射表法:预先定义一个包含8个元素的映射数组,将位运算生成的索引映射为原函数对应的索引。例如:const int octant_map[] = {7, 6, 5, 4, 3, 2, 1, 0};,后续用octant_map[calculated_index]作为计数器的下标。
  • 符号位逻辑调整法:修改符号位的生成规则,将“正分量对应1”改为“负分量对应1,正分量对应0”。这样全正分量的符号位组合为000,对应索引0,直接匹配原函数的统计规则,无需额外索引转换。

最终修正后的代码

方法1:索引反转法

std::array<int, 8> octant_count(const std::vector<Point3D>& points) {
    std::array<int, 8> counters = {0};
    for (const auto& p : points) {
        int x_sign = (p.x >= 0) ? 1 : 0;
        int y_sign = (p.y >= 0) ? 1 : 0;
        int z_sign = (p.z >= 0) ? 1 : 0;
        int index = (z_sign << 2) | (y_sign << 1) | x_sign;
        // 反转索引对齐原函数规则
        int corrected_index = 7 - index;
        counters[corrected_index]++;
    }
    return counters;
}

方法2:符号位逻辑调整法

std::array<int, 8> octant_count(const std::vector<Point3D>& points) {
    std::array<int, 8> counters = {0};
    for (const auto& p : points) {
        // 负分量标记为1,正分量标记为0,全正组合为000=0,直接匹配原函数索引
        int x_sign = (p.x < 0) ? 1 : 0;
        int y_sign = (p.y < 0) ? 1 : 0;
        int z_sign = (p.z < 0) ? 1 : 0;
        int index = (z_sign << 2) | (y_sign << 1) | x_sign;
        counters[index]++;
    }
    return counters;
}

内容的提问来源于stack exchange,提问作者Sinan Pasic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:18:01