简化一段代码——矢量旋转一圈
Simplifying a code snippet - vector rotation in a circle
给定以下代码模式,其中我试图在整数 int x
和 int y
上以 45 度的增量声明矢量方向,位于原点的圆圈内
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
我正在寻找一种优雅的方式来使这个紧凑。我知道有 宇宙飞船运算符 <=>
,但我需要限制自己使用 C++17.
我尝试过的东西
- 用
m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));
嵌套三元运算符,但这看起来很奇怪
- 我尝试将
x == 0
案例放入 x < 1
案例中,并将后者转换为其他案例,但这并不足以简化代码
- 用绝对值比较
x
和y
,但我很快就迷路了
- 真的没有别的了,我不知道还能尝试什么
类似
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
有一个封闭的形式:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
或更短
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;
给定以下代码模式,其中我试图在整数 int x
和 int y
上以 45 度的增量声明矢量方向,位于原点的圆圈内
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
我正在寻找一种优雅的方式来使这个紧凑。我知道有 宇宙飞船运算符 <=>
,但我需要限制自己使用 C++17.
我尝试过的东西
- 用
m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));
嵌套三元运算符,但这看起来很奇怪 - 我尝试将
x == 0
案例放入x < 1
案例中,并将后者转换为其他案例,但这并不足以简化代码 - 用绝对值比较
x
和y
,但我很快就迷路了 - 真的没有别的了,我不知道还能尝试什么
类似
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
有一个封闭的形式:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
或更短
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;