header_utils
Loading...
Searching...
No Matches
direction.h
1
4
5#pragma once
6
7#include "geometry_common.h"
8
9#include <numbers>
10
11namespace ghassanpl::geometry
12{
18
19 enum class direction
20 {
21 none = -1,
22
23 right = 0,
24 right_down,
25 down,
26 left_down,
27 left,
28 left_up,
29 up,
30 right_up,
31
32 east = 0,
33 south_east,
34 south,
35 south_west,
36 west,
37 north_west,
38 north,
39 north_east
40 };
41
42 static constexpr auto direction_count = 8;
43
44 using direction_set = enum_flags<direction, uint8_t>;
45
46 namespace detail
47 {
48 static constexpr const int direction_value[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
49 }
50
51 constexpr direction operator+(direction dir, int d) { return (direction)((int(dir) + d) % 8); }
52 constexpr direction operator-(direction dir, int d) { return (direction)((int(dir) + (8 + (d % 8))) % 8); }
53
54 constexpr direction& operator++(direction& dir) { return dir = dir + 1; }
55 constexpr direction& operator--(direction& dir) { return dir = dir + 7; }
56
57 constexpr direction operator++(direction& dir, int) { auto res = dir; ++dir; return res; }
58 constexpr direction operator--(direction& dir, int) { auto res = dir; --dir; return res; }
59
60 constexpr direction opposite(direction dir) { return dir + 4; }
61 constexpr direction next_cardinal(direction dir) { return direction(int(dir) & (~1)) + 2; }
62 constexpr direction prev_cardinal(direction dir) { return direction(int(dir + 1) & (~1)) + 6; }
63
64 constexpr inline direction_set all_cardinal_directions{ direction::left, direction::right, direction::up, direction::down };
65 constexpr inline direction_set all_diagonal_directions{ direction::left_up, direction::right_up, direction::right_down, direction::left_down };
66 constexpr inline direction_set all_directions{ direction::left, direction::right, direction::up, direction::down, direction::left_up, direction::right_up, direction::right_down, direction::left_down };
67
68 namespace names
69 {
70 namespace compass
71 {
72 constexpr inline const char* cardinal_directions[] = { "east", "south", "west", "north" };
73 constexpr inline const char* diagonal_directions[] = { "south east", "south west", "north west", "north east" };
74 constexpr inline const char* all_directions[] = { "east", "south east", "south", "south west", "west", "north west", "north", "north east" };
75 }
76
77 constexpr inline const char* cardinal_directions[] = { "right", "down", "left", "up" };
78 constexpr inline const char* diagonal_directions[] = { "right down", "left down", "left up", "right up" };
79 constexpr inline const char* all_directions[] = { "right", "right down", "down", "left down", "left", "left up", "up", "right up" };
80 }
81
82 constexpr const char* to_name(direction dir) { return names::all_directions[int(dir)]; }
83 constexpr const char* to_compass_name(direction dir) { return names::compass::all_directions[int(dir)]; }
84
85 constexpr bool is_valid(direction dir) { return int(dir) >= 0 && int(dir) <= 7; }
86 constexpr bool is_cardinal(direction dir) { return (int(dir) & 1) == 0; }
87 constexpr bool is_diagonal(direction dir) { return (int(dir) & 1) != 0; }
88
90 constexpr direction_set to_cardinal_set(direction dir)
91 {
92 if (is_cardinal(dir)) return { dir };
93 return { next_cardinal(dir), prev_cardinal(dir) };
94 }
95
97 constexpr int horizontal(direction dir) { return detail::direction_value[(int)dir]; }
98
100 constexpr int vertical(direction dir) { return detail::direction_value[int(dir + 6)]; }
101
102 constexpr degrees to_angle(direction val)
103 {
104 return degrees{ (float(val) * 45.0f) };
105 }
106
110
111 constexpr glm::ivec2 to_ivec(direction val) { return { horizontal(val), vertical(val) }; }
112 constexpr glm::vec2 to_vec(direction val) { const glm::vec2 d = to_ivec(val); return is_diagonal(val) ? d * std::numbers::sqrt2_v<float> : d; }
113
114 constexpr align to_alignment(direction val)
115 {
116 switch (val)
117 {
118 case direction::right: return align::middle_right;
119 case direction::right_down: return align::bottom_right;
120 case direction::down: return align::bottom_center;
121 case direction::left_down: return align::bottom_left;
122 case direction::left: return align::middle_left;
123 case direction::left_up: return align::top_left;
124 case direction::up: return align::top_center;
125 case direction::right_up: return align::top_right;
126 default: return align::center;
127 }
128 }
129
130 constexpr direction to_direction(align val)
131 {
132 switch (val)
133 {
134 case align::middle_right: return direction::right;
135 case align::bottom_right: return direction::right_down;
136 case align::bottom_center: return direction::down;
137 case align::bottom_left: return direction::left_down;
138 case align::middle_left: return direction::left;
139 case align::top_left: return direction::left_up;
140 case align::top_center: return direction::up;
141 case align::top_right: return direction::right_up;
142 default: return direction::none;
143 }
144 }
145
146 constexpr direction to_direction(degrees angle)
147 {
148 return direction(int(cem::fmod(angle.get() + (45.0 / 2.0), 360.0) / 45.0) % 8);
149 }
150
151 constexpr direction to_direction(glm::vec2 val)
152 {
153 return to_direction(geometry::angles::ensure_positive(degrees{ glm::degrees(glm::atan(val.y, val.x)) }));
154 }
155
156 constexpr direction to_direction(glm::ivec2 vec)
157 {
158 constexpr const int vec_value[] = { 5, 6, 7, 4, -1, 0, 3, 2, 1 };
159 return (direction)vec_value[glm::sign(vec.x) + glm::sign(vec.y) * 3 + 4];
160 }
161
163}
align
Represents an alignment in both axes (horizontal and veritcal).
Definition align.h:52
@ top_center
Top center.
Definition align.h:56
@ bottom_center
Bottom center.
Definition align.h:70
@ bottom_left
Bottom left.
Definition align.h:68
@ top_left
Top left.
Definition align.h:54
@ middle_left
Middle left.
Definition align.h:61
@ bottom_right
Bottom right.
Definition align.h:72
@ top_right
Top right.
Definition align.h:58
@ middle_right
Middle right.
Definition align.h:65
constexpr direction_set to_cardinal_set(direction dir)
Turns a diagonal direction into a set of cardinals (e.g. to_cardinal_set(north_west) -> direction_set...
Definition direction.h:90
constexpr int horizontal(direction dir)
Returns the horizontal offset (-1, 0, or 1) of dir.
Definition direction.h:97
constexpr int vertical(direction dir)
Returns the vertical offset (-1, 0, or 1) of dir.
Definition direction.h:100