#ifndef DIRECTION_H_AB66A90E #define DIRECTION_H_AB66A90E #include #include #include #include "vector.h" enum class Direction { up, up_right, right, down_right, down, down_left, left, up_left }; inline Direction directionFromString(std::string_view str) { if (str == "up") return Direction::up; if (str == "up_right") return Direction::up_right; if (str == "right") return Direction::right; if (str == "down_right") return Direction::down_right; if (str == "down") return Direction::down; if (str == "down_left") return Direction::down_left; if (str == "left") return Direction::left; if (str == "up_left") return Direction::up_left; throw std::invalid_argument("Invalid direction: " + std::string(str)); } inline vec2i unitVecInDirection(Direction dir) { switch (dir) { case Direction::up: return { 0, -1 }; case Direction::up_right: return { 1, -1 }; case Direction::right: return { 1, 0 }; case Direction::down_right: return { 1, 1 }; case Direction::down: return { 0, 1 }; case Direction::down_left: return { -1, 1 }; case Direction::left: return { -1, 0 }; case Direction::up_left: return { -1, -1 }; } } inline bool dirHasDir(Direction value, Direction inner) { switch (inner) { case Direction::up: return value == Direction::up_left || value == Direction::up || value == Direction::up_right; case Direction::down: return value == Direction::down_left || value == Direction::down || value == Direction::down_right; case Direction::left: return value == Direction::up_left || value == Direction::left || value == Direction::down_left; case Direction::right: return value == Direction::up_right || value == Direction::right || value == Direction::down_right; default: return value == inner; } } inline Direction oppositeDirection(Direction value) { switch (value) { case Direction::up: return Direction::down; case Direction::up_right: return Direction::down_left; case Direction::right: return Direction::left; case Direction::down_right: return Direction::up_left; case Direction::down: return Direction::up; case Direction::down_left: return Direction::up_right; case Direction::left: return Direction::right; case Direction::up_left: return Direction::down_right; } } inline Direction directionMirroredVertically(Direction value) { switch (value) { case Direction::up: return Direction::down; case Direction::up_right: return Direction::down_right; case Direction::right: return Direction::right; case Direction::down_right: return Direction::up_right; case Direction::down: return Direction::up; case Direction::down_left: return Direction::up_left; case Direction::left: return Direction::left; case Direction::up_left: return Direction::down_left; } } inline Direction directionFacingPoint(vec2i point) { double theta = atan2(-point.y(), point.x()); theta /= M_PI; if (theta < -7.0/8.0) { return Direction::left; } else if (theta < -5.0/8.0) { return Direction::down_left; } else if (theta < -3.0/8.0) { return Direction::down; } else if (theta < -1.0/8.0) { return Direction::down_right; } else if (theta < 1.0/8.0) { return Direction::right; } else if (theta < 3.0/8.0) { return Direction::up_right; } else if (theta < 5.0/8.0) { return Direction::up; } else if (theta < 7.0/8.0) { return Direction::up_left; } else { return Direction::left; } } inline Direction cardinalDirectionFacingPoint(vec2i point) { double theta = atan2(-point.y(), point.x()); theta /= M_PI; if (theta < -3.0/4.0) { return Direction::left; } else if (theta < -1.0/4.0) { return Direction::down; } else if (theta < 1.0/4.0) { return Direction::right; } else if (theta < 3.0/4.0) { return Direction::up; } else { return Direction::left; } } inline bool isCardinalDirection(Direction dir) { return (dir == Direction::left || dir == Direction::right || dir == Direction::up || dir == Direction::down); } #endif /* end of include guard: DIRECTION_H_AB66A90E */