我有2个2D点,​​它们被卡在一个数组中:int square[4]。这四个数字被解释为水平线平行于X轴而垂直线平行于Y轴的矩形的定义。然后,数组的元素分别定义:

  • 左边缘的X坐标
  • 底边的Y坐标
  • 右边缘的X坐标
  • 上边缘的Y坐标

  • 我已经在enum中定义了一个缠绕顺序:
    enum WindingOrder {
        BOTTOM = 0,
        RIGHT,
        TOP,
        LEFT
    };
    

    我的代码的最小,完整,可验证的示例是,给我第二个输出数组:int output[4]和一个输入WindingOrder edge。我需要填充output,如下所示:
    switch(edge) {
    case BOTTOM:
        output[0] = square[0]; output[1] = square[1]; output[2] = square[2]; output[3] = square[1];
        break;
    case RIGHT:
        output[0] = square[2]; output[1] = square[1]; output[2] = square[2]; output[3] = square[3];
        break;
    case TOP:
        output[0] = square[2]; output[1] = square[3]; output[2] = square[0]; output[3] = square[3];
        break;
    case LEFT:
        output[0] = square[0]; output[1] = square[3]; output[2] = square[0]; output[3] = square[1];
        break;
    }
    

    我并没有嫁给特定的WindingOrder安排,也不关心ouptut中的点顺序,因此,如果更改这些点使其可求解,我会失望的。我想知道的是,我是否可以构造square索引以在output循环中分配给for,而无需if/case/ternary语句(换句话说,使用按位运算)?

    所以我想给定int i = 0WindingOrder edge对它们进行按位运算以找到:
    do {
        output[i] = array[???];
    } while(++i <= LEFT);
    

    编辑:

    我收到了很多静态数组答案(我认为这是解决此问题的最佳方法,因此我给了+1)。但是作为一个逻辑问题,我很好奇,可以动态地执行给定边的元素的次数很少。因此,例如,在给定任意edgei的情况下,应如何编写此函数的主体:

    最佳答案

    是否可以重新定义WindingOrder的值集?如果可能的话,这是我的解决方案,它尝试在WindingOrder的值集中编码选择索引,然后只要对input[]索引进行迭代,就只需通过移位和屏蔽来解码出output[]的选择索引。

    [感谢 chqrlie 提供的代码库]:

        #include <iostream>
    
    enum WindingOrder {
        // the RIGHT most 4-bits indicate the selection index from input[] to output[0]
        // the LEFT most 4-bits indicate the selection index from input[] to output[3]
        BOTTOM = 0x1210,
        RIGHT = 0x3212,
        TOP = 0x3230,
        LEFT = 0x3010
    };
    
    void BitwiseWind(int const *input, int *output, unsigned short edge)
    {
        for (size_t i = 0; i < 4; i++)
            output[i] = input[(edge >> (i*4)) & 0x000F];    // decode
    }
    
    int main() {
        enum WindingOrder edges[4] = { BOTTOM, RIGHT, TOP, LEFT };
        int rect[4] = { 1, 3, 4, 5 };
        int output[4];
    
        for (int i = 0; i < 4; i++) {
            BitwiseWind(rect, output, edges[i]);
            std::cout << output[0] << output[1] << output[2] << output[3] << std::endl;
        }
        return 0;
    }
    

    通用的getIndex(int i,enum WindingOrder edge)将是:
    int getIndex(int i,enum WindingOrder edge)
    {
       return ((edge >> (i*4)) & 0x000F);
    }
    

    我没有数过它使用了多少指令,但是我相信它很少。而且非常容易想象它是如何工作的。 :)

    10-08 14:09