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

vsg 1.1.8 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 bvec2 = t_vec2<int8_t>; // signed 8 bit integer 2D vector
142 using svec2 = t_vec2<int16_t>; // signed 16 bit integer 2D vector
143 using ivec2 = t_vec2<int32_t>; // signed 32 bit integer 2D vector
144 using ubvec2 = t_vec2<uint8_t>; // unsigned 8 bit integer 2D vector
145 using usvec2 = t_vec2<uint16_t>; // unsigned 16 bit integer 2D vector
146 using uivec2 = t_vec2<uint32_t>; // unsigned 32 bit integer 2D vector
147
148 VSG_type_name(vsg::vec2);
149 VSG_type_name(vsg::dvec2);
150 VSG_type_name(vsg::bvec2);
151 VSG_type_name(vsg::svec2);
152 VSG_type_name(vsg::ivec2);
153 VSG_type_name(vsg::ubvec2);
154 VSG_type_name(vsg::usvec2);
155 VSG_type_name(vsg::uivec2);
156
157 template<typename T>
158 constexpr bool operator==(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
159 {
160 return lhs[0] == rhs[0] && lhs[1] == rhs[1];
161 }
162
163 template<typename T>
164 constexpr bool operator!=(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
165 {
166 return lhs[0] != rhs[0] || lhs[1] != rhs[1];
167 }
168
169 template<typename T>
170 constexpr bool operator<(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
171 {
172 if (lhs[0] < rhs[0]) return true;
173 if (lhs[0] > rhs[0]) return false;
174 return lhs[1] < rhs[1];
175 }
176
177 template<typename T>
178 constexpr t_vec2<T> operator-(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
179 {
180 return t_vec2<T>(lhs[0] - rhs[0], lhs[1] - rhs[1]);
181 }
182
183 template<typename T>
184 constexpr t_vec2<T> operator-(const t_vec2<T>& v)
185 {
186 return t_vec2<T>(-v[0], -v[1]);
187 }
188
189 template<typename T>
190 constexpr t_vec2<T> operator+(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
191 {
192 return t_vec2<T>(lhs[0] + rhs[0], lhs[1] + rhs[1]);
193 }
194
195 template<typename T>
196 constexpr t_vec2<T> operator*(const t_vec2<T>& lhs, T rhs)
197 {
198 return t_vec2<T>(lhs[0] * rhs, lhs[1] * rhs);
199 }
200
201 template<typename T>
202 constexpr t_vec2<T> operator*(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
203 {
204 return t_vec2<T>(lhs[0] * rhs[0], lhs[1] * rhs[1]);
205 }
206
207 template<typename T>
208 constexpr t_vec2<T> operator/(const t_vec2<T>& lhs, T rhs)
209 {
210 if constexpr (std::is_floating_point_v<T>)
211 {
212 T inv = static_cast<T>(1.0) / rhs;
213 return t_vec2<T>(lhs[0] * inv, lhs[1] * inv);
214 }
215 else
216 {
217 return t_vec2<T>(lhs[0] / rhs, lhs[1] / rhs);
218 }
219 }
220
221 template<typename T>
222 constexpr T length(const t_vec2<T>& v)
223 {
224 return std::sqrt(v[0] * v[0] + v[1] * v[1]);
225 }
226
227 template<typename T>
228 constexpr T length2(const t_vec2<T>& v)
229 {
230 return v[0] * v[0] + v[1] * v[1];
231 }
232
233 template<typename T>
234 constexpr t_vec2<T> normalize(const t_vec2<T>& v)
235 {
236 return v / length(v);
237 }
238
239 template<typename T>
240 constexpr T dot(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
241 {
242 return lhs[0] * rhs[0] + lhs[1] * rhs[1];
243 }
244
247 template<typename T>
248 constexpr T cross(const t_vec2<T>& lhs, const t_vec2<T>& rhs)
249 {
250 return (lhs[0] * rhs[1] - rhs[0] * lhs[1]);
251 }
252
253 template<typename T>
254 constexpr t_vec2<T> mix(const t_vec2<T>& start, const t_vec2<T>& end, T r)
255 {
256 T one_minus_r = 1 - r;
257 return t_vec2<T>(start[0] * one_minus_r + end[0] * r,
258 start[1] * one_minus_r + end[1] * r);
259 }
260
261} // namespace vsg
262
263#if defined(__clang__)
264# pragma clang diagnostic pop
265#endif
266#if defined(__GNUC__)
267# pragma GCC diagnostic pop
268#endif
vsg::t_vec2
t_vec2 template class that represents a 2D vector
Definition vec2.h:38