Home > database >  Simplifying a code snippet - vector rotation in a circle
Simplifying a code snippet - vector rotation in a circle

Time:02-28

Given the following code pattern, wherein I am trying to state a vector direction in increments of 45 degrees over the integers int x and int y, inside of a circle positioned at the origin

// 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;
    }
}

I am looking for an elegant way to make this compact. I know there's the spaceship operator <=>, but I need to restrict myself to C 17.

Things I have tried

  • Nesting ternary operators with m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));, but this looks weird
  • I tried putting the x == 0 case inside x < 1 case and transform the later into else, but that does not simplify enough the code
  • Using absolute values to compare x and y, but I quickly get lost
  • Nothing else really, I don't know what else to try

CodePudding user response:

Something like

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)];

CodePudding user response:

There is a closed form:

// standard sign functions
int xs = x < 0 ? -1 : static_cast<int>(x > 0);
int ys = y < 0 ? -1 : static_cast<int>(y > 0);

return 180 - 45 * (xs   2) * ys   90 * (xs * xs   xs) * (ys * ys - 1);
  • Related