dl
dl_align.h
浏览该文件的文档.
1
12#pragma once
13
14#include <array>
15#include <string_view>
16
17#include "base/dl_concept.h"
18#include "io/dl_log.h"
19#include "base/dl_string.h"
20
22namespace dl::Align
23{
24enum class Direction : int
25{
26 BACK = -1,
27 ZERO = 0,
28 FRONT = 1,
29 FARTHEST = std::numeric_limits<int>::lowest()
30};
31
33
37
41
45
46enum class Dir4
47{
48 RIGHT = 0,
52};
53
66
70constexpr Dir8 GetDir8(const PointU& p0, const PointU& p1)
71{
72 // 用“绝对距离 + 符号”判断,而不是 p0.x + 1 == p1.x:
73 // PointU 是无符号,加法在哨兵坐标 (unsigned)-1 上会回绕,
74 // 把相距极远的两个点误判成相邻。
75 const unsigned dx_abs = (p1.x > p0.x) ? (p1.x - p0.x) : (p0.x - p1.x);
76 const unsigned dy_abs = (p1.y > p0.y) ? (p1.y - p0.y) : (p0.y - p1.y);
77 if (dx_abs > 1 || dy_abs > 1)
78 return Dir8::NONE; // 同一格或不相邻
79
80 const int dx = (p1.x > p0.x) ? 1 : ((p1.x < p0.x) ? -1 : 0);
81 const int dy = (p1.y > p0.y) ? 1 : ((p1.y < p0.y) ? -1 : 0);
82
83 // 查表:行 = dy+1(上/中/下),列 = dx+1(左/中/右)
84 constexpr Dir8 DIR8_XY[3][3] = {
88 };
89 return DIR8_XY[dy + 1][dx + 1];
90}
91
93constexpr Dir8 GetDir8R(Dir8 dir)
94{
95 switch (dir)
96 {
97 case Dir8::RIGHT:
98 return Dir8::LEFT;
99 case Dir8::RB:
100 return Dir8::LT;
101 case Dir8::BOTTOM:
102 return Dir8::TOP;
103 case Dir8::LB:
104 return Dir8::RT;
105 case Dir8::LEFT:
106 return Dir8::RIGHT;
107 case Dir8::LT:
108 return Dir8::RB;
109 case Dir8::TOP:
110 return Dir8::BOTTOM;
111 case Dir8::RT:
112 return Dir8::LB;
113 default:
114 break;
115 }
116 return Dir8::NONE;
117}
118
119constexpr int Dir8ToMir2(Dir8 dir)
120{
121 return ((int)dir + 2) % 8;
122}
123
124enum class LTRB
125{
126 LEFT = 0,
127 TOP = 1,
128 RIGHT = 2,
130};
131
132enum class Corner
133{
134 LT = 0,
135 RT = 1,
136 RB = 2,
137 LB = 3,
138};
139
141constexpr int MASK_J = 1;
142constexpr int MASK_L = 2;
143constexpr int MASK_7 = 4;
144constexpr int MASK_Γ = 8;
145
146template<typename T, typename F>
147int GetMask(const std::array<T, 4>& arr, F func)
148{
149 int ret = 0;
150 if (func(arr[0]))
151 ret |= MASK_J;
152 if (func(arr[1]))
153 ret |= MASK_L;
154 if (func(arr[2]))
155 ret |= MASK_7;
156 if (func(arr[3]))
157 ret |= MASK_Γ;
158 return ret;
159}
160
161constexpr size_t Mask2Index(int mask)
162{
163 switch (mask)
164 {
165 case 0:
166 return 6;
167 case MASK_J:
168 return 3;
169 case MASK_L:
170 return 4;
171 case MASK_J | MASK_L:
172 return 11;
173 case MASK_7:
174 return 8;
175 case MASK_J | MASK_7:
176 return 7;
177 case MASK_L | MASK_7:
178 return 14;
179 case MASK_J | MASK_L | MASK_7:
180 return 12;
181 case MASK_Γ:
182 return 9;
183 case MASK_J | MASK_Γ:
184 return 13;
185 case MASK_L | MASK_Γ:
186 return 5;
187 case MASK_J | MASK_L | MASK_Γ:
188 return 10;
189 case MASK_7 | MASK_Γ:
190 return 1;
191 case MASK_J | MASK_7 | MASK_Γ:
192 return 2;
193 case MASK_L | MASK_7 | MASK_Γ:
194 return 0;
195 case MASK_J | MASK_L | MASK_7 | MASK_Γ:
196 return 15;
197 default:
198 break;
199 }
200 return -1;
201}
202
207template<IsSigned T, std::size_t N>
208constexpr Array<T, N> Size2Anchor(const Array<T, N>& size, const Array<Direction, N>& dir)
209{
210 Array<T, N> ret;
211 for (std::size_t i = 0; i < N; ++i)
212 {
213 ret[i] = (size[i] / static_cast<T>(2)) * ((int)dir[i] + 1);
214 }
215 return ret;
216}
217
222template<IsSigned T, std::size_t N>
224 const Array<T, N>& size,
225 const Array<T, N>& size_self,
226 const Array<Direction, N>& dir)
227{
228 Array<T, N> ret;
229 for (std::size_t i = 0; i < N; ++i)
230 {
231 ret[i] = ((size[i] - size_self[i]) / static_cast<T>(2)) * ((int)dir[i] + 1);
232 }
233 return ret;
234}
235
238template<IsSigned T, std::size_t N>
239constexpr Array<T, N> Dir2Offset(const Array<T, N>& size, Dir4 dir)
240{
241 switch (dir)
242 {
244 return {};
246 return {size.h, 0};
248 return { -size.w, -size.h };
250 return { size.h, 0 };
251 default:
252 break;
253 }
254 return {};
255}
256
258inline float Dir2Rotate(Dir4 dir)
259{
260 switch (dir)
261 {
262 case Dir4::RIGHT: return 0.0f;
263 case Dir4::BOTTOM: return Math::PIF(1, 2);
264 case Dir4::LEFT: return Math::PIF(2, 2);
265 case Dir4::TOP: return Math::PIF(3, 2);
266 }
267 return 0.0f;
268}
269
270
276Direction2 Anchor2Direction(std::string_view anchor);
277
284Point Anchor2Point(const Size& size, std::string_view anchor);
285Position Anchor2Position(const Position& size, std::string_view anchor);
286
287//-----------------------获取Rect斜角方位-----------------------------
288template<typename T>
289constexpr Array<T, 2> GetLT(const Array<T, 4>& rect)
290{
291 return { rect[(size_t)LTRB::LEFT], rect[(size_t)LTRB::TOP] };
292}
293template<typename T>
294constexpr Array<T, 2> GetRT(const Array<T, 4>& rect)
295{
296 return { rect[(size_t)LTRB::RIGHT], rect[(size_t)LTRB::TOP] };
297}
298template<typename T>
299constexpr Array<T, 2> GetRB(const Array<T, 4>& rect)
300{
301 return { rect[(size_t)LTRB::RIGHT], rect[(size_t)LTRB::BOTTOM] };
302}
303template<typename T>
304constexpr Array<T, 2> GetLB(const Array<T, 4>& rect)
305{
306 return { rect[(size_t)LTRB::LEFT], rect[(size_t)LTRB::BOTTOM] };
307}
308//-----------------------获取Rect水平垂直方位-----------------------------
309template<typename T>
310constexpr T& GetLeft(Array<T, 4>& rect)
311{
312 return rect[(size_t)LTRB::LEFT];
313}
314template<typename T>
315constexpr T& GetTop(Array<T, 4>& rect)
316{
317 return rect[(size_t)LTRB::TOP];
318}
319template<typename T>
320constexpr T& GetRight(Array<T, 4>& rect)
321{
322 return rect[(size_t)LTRB::RIGHT];
323}
324template<typename T>
325constexpr T& GetBottom(Array<T, 4>& rect)
326{
327 return rect[(size_t)LTRB::BOTTOM];
328}
329
330//-------------------------------隐藏含义获取--------------------------------
335template<typename T>
336constexpr T GetHeight(const Array<T, 4>& rect)
337{
338 return rect[3] - rect[1];
339}
340
345template<typename T>
346constexpr T GetWidth(const Array<T, 4>& rect)
347{
348 return rect[2] - rect[0];
349}
350
355template<typename T>
356constexpr Array<T, 2> GetSize(const Array<T, 4>& rect)
357{
358 return { GetWidth(rect), GetHeight(rect) };
359}
360
364template<typename T>
365constexpr void Shrink(Array<T, 4>& rect, const T& v)
366{
367 rect[0] += v;
368 rect[1] += v;
369 rect[2] -= v;
370 rect[3] -= v;
371}
372template<typename T>
373constexpr Array<T, 4> Shrink(const Array<T, 4>& rect, const T& v)
374{
375 Array<T, 4> ret = rect;
376 Shrink(ret, v);
377 return ret;
378}
379
380
385template<typename T>
386constexpr void OffsetRect(Array<T, 4>& rect, const Array<T, 2>& offset)
387{
388 rect.left += offset.x;
389 rect.right += offset.x;
390 rect.top += offset.y;
391 rect.bottom += offset.y;
392}
393
394}
用于模板限定,更好的报错信息
日志系统
字符串相关
方向、对齐定义
constexpr void OffsetRect(Array< T, 4 > &rect, const Array< T, 2 > &offset)
偏移矩形
constexpr T & GetBottom(Array< T, 4 > &rect)
Point Anchor2Point(const Size &size, std::string_view anchor)
锚点(字符串)返回 偏移
constexpr Dir8 GetDir8R(Dir8 dir)
获取相反方向
Position Anchor2Position(const Position &size, std::string_view anchor)
int GetMask(const std::array< T, 4 > &arr, F func)
LTRB
左上右下(2个点,rect用)
constexpr T & GetTop(Array< T, 4 > &rect)
constexpr Direction2 LB
Array< Direction, 2 > Direction2
constexpr Array< T, 2 > GetRT(const Array< T, 4 > &rect)
constexpr Array< T, 2 > GetRB(const Array< T, 4 > &rect)
constexpr Dir8 GetDir8(const PointU &p0, const PointU &p1)
constexpr T & GetLeft(Array< T, 4 > &rect)
constexpr Direction2 CB
constexpr Array< T, 2 > GetLB(const Array< T, 4 > &rect)
constexpr Array< T, 2 > GetSize(const Array< T, 4 > &rect)
计算返回 矩形 宽和高
constexpr T & GetRight(Array< T, 4 > &rect)
constexpr Direction2 RC
Direction2 Anchor2Direction(std::string_view anchor)
锚点(字符串)返回 对齐
constexpr int MASK_L
constexpr Array< T, 2 > GetLT(const Array< T, 4 > &rect)
constexpr Direction2 CT
constexpr Array< T, N > Dir2Offset(const Array< T, N > &size, Dir4 dir)
根据大小和朝向,计算偏移
constexpr void Shrink(Array< T, 4 > &rect, const T &v)
拓展矩形
constexpr Direction2 RT
constexpr T GetWidth(const Array< T, 4 > &rect)
计算返回 矩形 右下角坐标x 减去 左上角坐标x
constexpr int Dir8ToMir2(Dir8 dir)
constexpr Direction2 CC
constexpr size_t Mask2Index(int mask)
float Dir2Rotate(Dir4 dir)
方向对应的旋转角度(弧度)
constexpr Array< T, N > Size2Anchor(const Array< T, N > &size, const Array< Direction, N > &dir)
根据大小和对齐,计算锚点
constexpr Direction2 LT
constexpr Direction2 RB
Corner
斜角位置(4个点,quad用)
constexpr int MASK_Γ
constexpr Direction2 LC
constexpr T GetHeight(const Array< T, 4 > &rect)
计算返回 矩形 右下角坐标y 减去 左上角坐标y
constexpr int MASK_7
constexpr int MASK_J
平滑地图 四方向掩码
constexpr float PIF(unsigned n=1, unsigned d=1)
Position2 Position
Point2U PointU
PointU Size
Point2 Point