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
124
125
126
127
128
129
130
|
#pragma once
#include <cmath>
#include <format>
#include "../macros.hpp"
class Vector2D {
public:
Vector2D(double, double);
Vector2D();
~Vector2D();
double x = 0;
double y = 0;
// returns the scale
double normalize();
Vector2D operator+(const Vector2D& a) const {
return Vector2D(this->x + a.x, this->y + a.y);
}
Vector2D operator-(const Vector2D& a) const {
return Vector2D(this->x - a.x, this->y - a.y);
}
Vector2D operator-() const {
return Vector2D(-this->x, -this->y);
}
Vector2D operator*(const double& a) const {
return Vector2D(this->x * a, this->y * a);
}
Vector2D operator/(const double& a) const {
return Vector2D(this->x / a, this->y / a);
}
bool operator==(const Vector2D& a) const {
return a.x == x && a.y == y;
}
bool operator!=(const Vector2D& a) const {
return a.x != x || a.y != y;
}
Vector2D operator*(const Vector2D& a) const {
return Vector2D(this->x * a.x, this->y * a.y);
}
Vector2D operator/(const Vector2D& a) const {
return Vector2D(this->x / a.x, this->y / a.y);
}
bool operator>(const Vector2D& a) const {
return this->x > a.x && this->y > a.y;
}
bool operator<(const Vector2D& a) const {
return this->x < a.x && this->y < a.y;
}
Vector2D& operator+=(const Vector2D& a) {
this->x += a.x;
this->y += a.y;
return *this;
}
Vector2D& operator-=(const Vector2D& a) {
this->x -= a.x;
this->y -= a.y;
return *this;
}
Vector2D& operator*=(const Vector2D& a) {
this->x *= a.x;
this->y *= a.y;
return *this;
}
Vector2D& operator/=(const Vector2D& a) {
this->x /= a.x;
this->y /= a.y;
return *this;
}
Vector2D& operator*=(const double& a) {
this->x *= a;
this->y *= a;
return *this;
}
Vector2D& operator/=(const double& a) {
this->x /= a;
this->y /= a;
return *this;
}
double distance(const Vector2D& other) const;
double size() const;
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()) const;
Vector2D floor() const;
Vector2D round() const;
bool inTriangle(const Vector2D& p1, const Vector2D& p2, const Vector2D& p3) const;
};
/**
format specification
- 'j', as json array
- 'X', same as std::format("{}x{}", vec.x, vec.y)
- number, floating point precision, use `0` to format as integer
*/
template <typename CharT>
struct std::formatter<Vector2D, CharT> : std::formatter<CharT> {
bool formatJson = false;
bool formatX = false;
std::string precision = "";
FORMAT_PARSE(FORMAT_FLAG('j', formatJson) //
FORMAT_FLAG('X', formatX) //
FORMAT_NUMBER(precision),
Vector2D)
template <typename FormatContext>
auto format(const Vector2D& vec, FormatContext& ctx) const {
std::string formatString = precision.empty() ? "{}" : std::format("{{:.{}f}}", precision);
if (formatJson)
formatString = std::format("[{0}, {0}]", formatString);
else if (formatX)
formatString = std::format("{0}x{0}", formatString);
else
formatString = std::format("[Vector2D: x: {0}, y: {0}]", formatString);
try {
string buf = std::vformat(formatString, std::make_format_args(vec.x, vec.y));
return std::format_to(ctx.out(), "{}", buf);
} catch (std::format_error& e) { return std::format_to(ctx.out(), "[{}, {}]", vec.x, vec.y); }
}
};
|