Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid if / else if chain when classifying a heading into 8 directions?

I have the following code:

if (this->_car.getAbsoluteAngle() <= 30 || this->_car.getAbsoluteAngle() >= 330)   this->_car.edir = Car::EDirection::RIGHT; else if (this->_car.getAbsoluteAngle() > 30 && this->_car.getAbsoluteAngle() <= 60)   this->_car.edir = Car::EDirection::UP_RIGHT; else if (this->_car.getAbsoluteAngle() > 60 && this->_car.getAbsoluteAngle() <= 120)   this->_car.edir = Car::EDirection::UP; else if (this->_car.getAbsoluteAngle() > 120 && this->_car.getAbsoluteAngle() <= 150)   this->_car.edir = Car::EDirection::UP_LEFT; else if (this->_car.getAbsoluteAngle() > 150 && this->_car.getAbsoluteAngle() <= 210)   this->_car.edir = Car::EDirection::LEFT; else if (this->_car.getAbsoluteAngle() > 210 && this->_car.getAbsoluteAngle() <= 240)   this->_car.edir = Car::EDirection::DOWN_LEFT; else if (this->_car.getAbsoluteAngle() > 240 && this->_car.getAbsoluteAngle() <= 300)   this->_car.edir = Car::EDirection::DOWN; else if (this->_car.getAbsoluteAngle() > 300 && this->_car.getAbsoluteAngle() <= 330)   this->_car.edir = Car::EDirection::DOWN_RIGHT; 

I want to avoid the ifs chain; it's really ugly. Is there a another, possibly cleaner, way of writing this?

like image 445
Oraekia Avatar asked May 25 '17 15:05

Oraekia


People also ask

How do I avoid if else?

Avoid using nested if-else statements. Keep the code linear and straightforward. Utilize creating functions/methods. Compare it when we try to use an if-else statement that is nested and that does not utilize the power of the return statement, We get this (Code 1.4).

Why is my IF ELSE statement not working?

If you are getting an error about the else it is because you've told the interpreter that the ; was the end of your if statement so when it finds the else a few lines later it starts complaining. A few examples of where not to put a semicolon: if (age < 18); if ( 9 > 10 ); if ("Yogi Bear". length < 3); if ("Jon".

How does nested if differ from if statements if else statements?

Overview. If else statements are used for decision making, by specifying which block of code is to be executed when a certain condition is met. Nested if else statements are just if else statements inside other if else statements to provide better decision making.

How does the IF ELSE statement within Method fact work?

IF-ELSE-IF: if the condition is true, then the block of code inside the IF statement is executed. After that, the ELSE-IF block is checked. If the condition associated with this is true, then the block of statements inside this ELSE-IF block is executed. Otherwise, the statement inside the ELSE block is executed.


2 Answers

#include <iostream>  enum Direction { UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT };  Direction GetDirectionForAngle(int angle) {     const Direction slices[] = { RIGHT, UP_RIGHT, UP, UP, UP_LEFT, LEFT, LEFT, DOWN_LEFT, DOWN, DOWN, DOWN_RIGHT, RIGHT };     return slices[(((angle % 360) + 360) % 360) / 30]; }  int main() {     // This is just a test case that covers all the possible directions     for (int i = 15; i < 360; i += 30)         std::cout << GetDirectionForAngle(i) << ' ';      return 0; } 

This is how I would do it. (As per my previous comment).

like image 193
Borgleader Avatar answered Oct 07 '22 14:10

Borgleader


You can use map::lower_bound and store the upper-bound of each angle in a map.

Working example below:

#include <cassert> #include <map>  enum Direction {     RIGHT,     UP_RIGHT,     UP,     UP_LEFT,     LEFT,     DOWN_LEFT,     DOWN,     DOWN_RIGHT };  using AngleDirMap = std::map<int, Direction>;  AngleDirMap map = {     { 30, RIGHT },     { 60, UP_RIGHT },     { 120, UP },     { 150, UP_LEFT },     { 210, LEFT },     { 240, DOWN_LEFT },     { 300, DOWN },     { 330, DOWN_RIGHT },     { 360, RIGHT } };  Direction direction(int angle) {     assert(angle >= 0 && angle <= 360);      auto it = map.lower_bound(angle);     return it->second; }  int main() {     Direction d;      d = direction(45);     assert(d == UP_RIGHT);      d = direction(30);     assert(d == RIGHT);      d = direction(360);     assert(d == RIGHT);      return 0; } 
like image 41
Steve Lorimer Avatar answered Oct 07 '22 14:10

Steve Lorimer