我有2个2D点,它们被卡在一个数组中:int square[4]
。这四个数字被解释为水平线平行于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 = 0
和WindingOrder edge
对它们进行按位运算以找到:do {
output[i] = array[???];
} while(++i <= LEFT);
编辑:
我收到了很多静态数组答案(我认为这是解决此问题的最佳方法,因此我给了+1)。但是作为一个逻辑问题,我很好奇,可以动态地执行给定边的元素的次数很少。因此,例如,在给定任意
edge
和i
的情况下,应如何编写此函数的主体: 最佳答案
是否可以重新定义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);
}
我没有数过它使用了多少指令,但是我相信它很少。而且非常容易想象它是如何工作的。 :)