vsg: include/vsg/maths/vec2.h Source File

vsg 1.1.9 VulkanSceneGraph library |

Loading...
Searching...
No Matches
vec2.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2018 Robert Osfield
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
13</editor-fold> */
14
15// we can't implement the anonymous union/structs combination without causing warnings, so disable them for just this header
16#if defined(__GNUC__)
17# pragma GCC diagnostic push
18# pragma GCC diagnostic ignored "-Wpedantic"
19#endif
20#if defined(__clang__)
21# pragma clang diagnostic push
22# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
23# pragma clang diagnostic ignored "-Wnested-anon-types"
24#endif
25
26#include <vsg/core/type_name.h>
27
28#include <cmath>
29#include <cstdint>
30#include <type_traits>
31
32namespace vsg
33{
34
36 template<typename T>
37 struct t_vec2
38 {
39 using value_type = T;
40
41 union
42 {
43 value_type value[2];
44 struct
45 {
46 value_type x, y;
47 };
48 struct
49 {
50 value_type r, g;
51 };
52 struct
53 {
54 value_type s, t;
55 };
56 };
57
58 constexpr t_vec2() :
59 value{} {}
60 constexpr t_vec2(const t_vec2& v) :
61 value{v.x, v.y} {}
62 constexpr t_vec2& operator=(const t_vec2&) = default;
63 constexpr t_vec2(value_type in_x, value_type in_y) :
64 value{in_x, in_y} {}
65
66 template<typename R>
67 constexpr explicit t_vec2(const t_vec2<R>& v) :
68 value{static_cast<T>(v.x), static_cast<T>(v.y)} {}
69
70 constexpr std::size_t size() const { return 2; }
71
72 value_type& operator[](std::size_t i) { return value[i]; }
73 value_type operator[](std::size_t i) const { return value[i]; }
74
75 template<typename R>
76 t_vec2& operator=(const t_vec2<R>& rhs)
77 {
78 value[0] = static_cast<value_type>(rhs[0]);
79 value[1] = static_cast<value_type>(rhs[1]);
80 return *this;
81 }
82
83 T* data() { return value; }
84 const T* data() const { return value; }
85
86 void set(value_type in_x, value_type in_y)
87 {
88 x = in_x;
89 y = in_y;
90 }
91
92 inline t_vec2& operator+=(const t_vec2& rhs)
93 {
94 value[0] += rhs.value[0];
95 value[1] += rhs.value[1];
96 return *this;
97 }
98
99 inline t_vec2& operator-=(const t_vec2& rhs)
100 {
101 value[0] -= rhs.value[0];
102 value[1] -= rhs.value[1];
103 return *this;
104 }
105
106 inline t_vec2& operator*=(value_type rhs)
107 {
108 value[0] *= rhs;
109 value[1] *= rhs;
110 return *this;
111 }
112
113 inline t_vec2& operator*=(const t_vec2& rhs)
114 {
115 value[0] *= rhs.value[0];
116 value[1] *= rhs.value[1];
117 return *this;
118 }
119
120 inline t_vec2& operator/=(value_type rhs)
121 {
122 if constexpr (std::is_floating_point_v<value_type>)
123 {
124 value_type inv = static_cast<value_type>(1.0) / rhs;
125 value[0] *= inv;
126 value[1] *= inv;
127 }
128 else
129 {
130 value[0] /= rhs;
131 value[1] /= rhs;
132 }
133 return *this;
134 }
135
136 explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0; }
137 };
138
139 using vec2 = t_vec2<float>; // float 2D vector
140 using dvec2 = t_vec2<double>; // double 2D vector
141 using ldvec2 = t_vec2<long double>; // long double 2D vector
142 using bvec2 = t_vec2<int8_t>; // signed 8 bit integer 2D vector
143 using svec2 = t_vec2<int16_t>; // signed 16 bit integer 2D vector
144 using ivec2 = t_vec2<int32_t>; // signed 32 bit integer 2D vector
145 using ubvec2 = t_vec2<uint8_t>; // unsigned 8 bit integer 2D vector
146 using usvec2 = t_vec2<uint16_t>; // unsigned 16 bit integer 2D vector
147 using uivec2 = t_vec2<uint32_t>; // unsigned 32 bit integer 2D vector
148
149 VSG_type_name(vsg::vec2);
150 VSG_type_name(vsg::dvec2);
151 VSG_type_name(vsg::bvec2);
152 VSG_type_name(vsg::svec2);
153 VSG_type_name(vsg::ivec2);
154 VSG_type_name(vsg::ubvec2);
155 VSG_type_name(vsg::usvec2);
156 VSG_type_name(vsg::uivec2);
157
158 template<typename T>
159 constexpr bool operator==(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
160 {
161 return lhs[0] == rhs[0] && lhs[1] == rhs[1];
162 }
163
164 template<typename T>
165 constexpr bool operator!=(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
166 {
167 return lhs[0] != rhs[0] || lhs[1] != rhs[1];
168 }
169
170 template<typename T>
171 constexpr bool operator<(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
172 {
173 if (lhs[0] < rhs[0]) return true;
174 if (lhs[0] > rhs[0]) return false;
175 return lhs[1] < rhs[1];
176 }
177
178 template<typename T>
179 constexpr t_vec2<T> operator-(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
180 {
181 return t_vec2<T>(lhs[0] - rhs[0], lhs[1] - rhs[1]);
182 }
183
184 template<typename T>
185 constexpr t_vec2<T> operator-(const t_vec2<T>& v)
186 {
187 return t_vec2<T>(-v[0], -v[1]);
188 }
189
190 template<typename T>
191 constexpr t_vec2<T> operator+(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
192 {
193 return t_vec2<T>(lhs[0] + rhs[0], lhs[1] + rhs[1]);
194 }
195
196 template<typename T>
197 constexpr t_vec2<T> operator*(const t_vec2<T>& lhs, T rhs)
198 {
199 return t_vec2<T>(lhs[0] * rhs, lhs[1] * rhs);
200 }
201
202 template<typename T>
203 constexpr t_vec2<T> operator*(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
204 {
205 return t_vec2<T>(lhs[0] * rhs[0], lhs[1] * rhs[1]);
206 }
207
208 template<typename T>
209 constexpr t_vec2<T> operator/(const t_vec2<T>& lhs, T rhs)
210 {
211 if constexpr (std::is_floating_point_v<T>)
212 {
213 T inv = static_cast<T>(1.0) / rhs;
214 return t_vec2<T>(lhs[0] * inv, lhs[1] * inv);
215 }
216 else
217 {
218 return t_vec2<T>(lhs[0] / rhs, lhs[1] / rhs);
219 }
220 }
221
222 template<typename T>
223 constexpr T length(const t_vec2<T>& v)
224 {
225 return std::sqrt(v[0] * v[0] + v[1] * v[1]);
226 }
227
228 template<typename T>
229 constexpr T length2(const t_vec2<T>& v)
230 {
231 return v[0] * v[0] + v[1] * v[1];
232 }
233
234 template<typename T>
235 constexpr t_vec2<T> normalize(const t_vec2<T>& v)
236 {
237 return v / length(v);
238 }
239
240 template<typename T>
241 constexpr T dot(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
242 {
243 return lhs[0] * rhs[0] + lhs[1] * rhs[1];
244 }
245
248 template<typename T>
249 constexpr T cross(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
250 {
251 return (lhs[0] * rhs[1] - rhs[0] * lhs[1]);
252 }
253
254 template<typename T>
255 constexpr t_vec2<T> mix(const t_vec2<T>& start, const t_vec2<T>& end, T r)
256 {
257 T one_minus_r = 1 - r;
258 return t_vec2<T>(start[0] * one_minus_r + end[0] * r,
259 start[1] * one_minus_r + end[1] * r);
260 }
261
262} // namespace vsg
263
264#if defined(__clang__)
265# pragma clang diagnostic pop
266#endif
267#if defined(__GNUC__)
268# pragma GCC diagnostic pop
269#endif
vsg::t_vec2
t_vec2 template class that represents a 2D vector
Definition vec2.h:38