1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#ifndef DIRECTION_H_AB66A90E
#define DIRECTION_H_AB66A90E
#include <cmath>
#include <string>
#include <stdexcept>
#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;
}
}
#endif /* end of include guard: DIRECTION_H_AB66A90E */
|