libpromeki main
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
point.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <cmath>
11#include <type_traits>
13#include <promeki/core/string.h>
15#include <promeki/core/error.h>
16#include <promeki/core/logger.h>
17#include <promeki/core/array.h>
18
20
41template <typename T, size_t NumValues> class Point {
42 public:
49 static Error fromString(const String &val, Point &d) {
50 StringList parts = val.split(",");
51 if(parts.size() != NumValues) return Error::Invalid;
52 for(size_t i = 0; i < NumValues; ++i) {
53 Error err;
54 d[i] = static_cast<T>(parts[i].trim().toDouble(&err));
55 if(err.isError()) return Error::Invalid;
56 }
57 return Error::Ok;
58 }
59
66 static Point fromString(const String &str, Error *err = nullptr) {
68 Error e = fromString(str, d);
69 if(err != nullptr) *err = e;
70 return e.isOk() ? d : Point();
71 }
72
74 Point() : d{} {}
75
78
80 template<typename... Args> Point(Args... args) : d{static_cast<T>(args)...} {}
81
83 Point(const String &str) : d(fromString(str)) { }
84
86 virtual ~Point() { }
87
89 operator String() const {
90 return toString();
91 }
92
94 operator const Array<T, NumValues>&() const {
95 return d;
96 }
97
99 bool operator==(const Array<T, NumValues> &val) const {
100 return d == val;
101 }
102
104 bool operator!=(const Array<T, NumValues> &val) const {
105 return d != val;
106 }
107
110 d += val;
111 return *this;
112 }
113
116 d -= val;
117 return *this;
118 }
119
122 d *= val;
123 return *this;
124 }
125
128 d /= val;
129 return *this;
130 }
131
133 template<size_t N = NumValues, typename std::enable_if_t<N >= 1, int> = 0> const T &x() const {
134 return d[0];
135 }
136
138 template<size_t N = NumValues, typename std::enable_if_t<N >= 1, int> = 0> T &x() {
139 return d[0];
140 }
141
143 template<size_t N = NumValues, typename std::enable_if_t<N >= 1, int> = 0> void setX(const T &val) {
144 d[0] = val;
145 return;
146 }
147
149 template<size_t N = NumValues, typename std::enable_if_t<N >= 2, int> = 0> const T &y() const {
150 return d[1];
151 }
152
154 template<size_t N = NumValues, typename std::enable_if_t<N >= 2, int> = 0> T &y() {
155 return d[1];
156 }
157
159 template<size_t N = NumValues, typename std::enable_if_t<N >= 2, int> = 0> void setY(const T &val) {
160 d[1] = val;
161 return;
162 }
163
165 template<size_t N = NumValues, typename std::enable_if_t<N >= 3, int> = 0> const T &z() const {
166 return d[2];
167 }
168
170 template<size_t N = NumValues, typename std::enable_if_t<N >= 3, int> = 0> T &z() {
171 return d[2];
172 }
173
175 template<size_t N = NumValues, typename std::enable_if_t<N >= 3, int> = 0> void setZ(const T &val) {
176 d[2] = val;
177 return;
178 }
179
181 String toString() const {
182 String result;
183 for(size_t i = 0; i < NumValues; ++i) {
184 if(i > 0) result += ", ";
185 if constexpr (std::is_floating_point_v<T>) {
186 result += String::number(static_cast<double>(d[i]));
187 } else {
188 result += String::dec(static_cast<int64_t>(d[i]));
189 }
190 }
191 return result;
192 }
193
199 template <typename U> double distanceTo(const Point<U, NumValues>& other) const {
200 double sum = 0;
201 for(size_t i = 0; i < NumValues; ++i) {
202 double diff = static_cast<double>(d[i]) - static_cast<double>(other.d[i]);
203 sum += diff * diff;
204 }
205 return std::sqrt(sum);
206 }
207
214 Point<T, NumValues> lerp(const Point<T, NumValues> &other, double t) const { return d.lerp(other, t); }
215
222 template <typename U> Point<T, NumValues> clamp(
224 const Point<U, NumValues>& maxVal) const {
225 Point<T, NumValues> result;
226 for(size_t i = 0; i < NumValues; ++i) {
227 T val = d[i];
228 if (val < static_cast<T>(minVal.d[i])) val = static_cast<T>(minVal.d[i]);
229 if (val > static_cast<T>(maxVal.d[i])) val = static_cast<T>(maxVal.d[i]);
230 result.d[i] = val;
231 }
232 return result;
233 }
234
242 for (size_t i = 0; i < NumValues; ++i) {
243 if (d[i] < min.d[i] || d[i] > max.d[i]) {
244 return false;
245 }
246 }
247 return true;
248 }
249
252 return Point(lh + rh);
253 }
254
257 return Point(lh - rh);
258 }
259
262 return Point(lh * rh);
263 }
264
267 return Point(lh / rh);
268 }
269
270 private:
272};
273
292
294
Lightweight error code wrapper for the promeki library.
Definition error.h:39
@ Ok
No error.
Definition error.h:51
@ Invalid
Invalid value or argument (EINVAL).
Definition error.h:66
Dynamic array container wrapping std::vector.
Definition list.h:40
size_t size() const noexcept
Returns the number of elements in the list.
Definition list.h:301
N-dimensional point with arithmetic, interpolation, and serialization.
Definition point.h:41
friend Point operator-(const Array< T, NumValues > &lh, const Array< T, NumValues > &rh)
Returns the component-wise difference of two Arrays as a Point.
Definition point.h:256
static Point fromString(const String &str, Error *err=nullptr)
Parses a comma-separated string into a Point.
Definition point.h:66
static Error fromString(const String &val, Point &d)
Parses a comma-separated string into a Point.
Definition point.h:49
friend Point operator/(const Array< T, NumValues > &lh, const Array< T, NumValues > &rh)
Returns the component-wise quotient of two Arrays as a Point.
Definition point.h:266
bool operator!=(const Array< T, NumValues > &val) const
Returns true if this Point does not equal the given Array.
Definition point.h:104
Point & operator-=(const Array< T, NumValues > &val)
Subtracts the given Array component-wise from this Point.
Definition point.h:115
Point & operator/=(const Array< T, NumValues > &val)
Divides this Point component-wise by the given Array.
Definition point.h:127
Point(const String &str)
Constructs a Point by parsing a comma-separated string.
Definition point.h:83
virtual ~Point()
Destructor.
Definition point.h:86
Point()
Default constructor. Initializes all values to zero.
Definition point.h:74
Point< T, NumValues > clamp(const Point< U, NumValues > &minVal, const Point< U, NumValues > &maxVal) const
Clamps each component of the Point to the given min and max bounds.
Definition point.h:222
Point(const Array< T, NumValues > &val)
Constructs a Point from an Array.
Definition point.h:77
friend Point operator*(const Array< T, NumValues > &lh, const Array< T, NumValues > &rh)
Returns the component-wise product of two Arrays as a Point.
Definition point.h:261
Point(Args... args)
Constructs a Point from individual component values.
Definition point.h:80
Point & operator+=(const Array< T, NumValues > &val)
Adds the given Array component-wise to this Point.
Definition point.h:109
bool operator==(const Array< T, NumValues > &val) const
Returns true if this Point equals the given Array.
Definition point.h:99
Point & operator*=(const Array< T, NumValues > &val)
Multiplies this Point component-wise by the given Array.
Definition point.h:121
bool isWithinBounds(const Point< T, NumValues > &min, const Point< T, NumValues > &max) const
Returns true if all components are within the given min and max bounds (inclusive).
Definition point.h:241
friend Point operator+(const Array< T, NumValues > &lh, const Array< T, NumValues > &rh)
Returns the component-wise sum of two Arrays as a Point.
Definition point.h:251
Manages a list of strings.
Definition stringlist.h:21
Encoding-aware string class with copy-on-write semantics.
Definition string.h:35
static String number(int8_t value, int base=10, int padding=0, char padchar=' ', bool addPrefix=false)
Converts a numeric value to its String representation.
static String dec(const T &val, int padding=0, char padchar=' ')
Formats a value as a decimal string with optional padding.
Definition string.h:167
#define PROMEKI_NAMESPACE_BEGIN
Starts a promeki namespace block.
Definition namespace.h:14
#define PROMEKI_NAMESPACE_END
Ends a promeki namespace block.
Definition namespace.h:19