Trax3 3.1.0
trax track library
Loading...
Searching...
No Matches
Vector2D.h
1// trax track library
2// AD 2013
3//
4// "let me entertain you"
5//
6// Robbie Williams
7//
8// Copyright (c) 2025 Trend Redaktions- und Verlagsgesellschaft mbH
9// Copyright (c) 2019 Marc-Michael Horstmann
10//
11// Permission is hereby granted to any person obtaining a copy of this software
12// and associated source code (the "Software"), to use, view, and study the
13// Software for personal or internal business purposes, subject to the following
14// conditions:
15//
16// 1. Redistribution, modification, sublicensing, or commercial use of the
17// Software is NOT permitted without prior written consent from the copyright
18// holder.
19//
20// 2. The Software is provided "AS IS", without warranty of any kind, express
21// or implied.
22//
23// 3. All copies of the Software must retain this license notice.
24//
25// For further information, please contact: horstmann.marc@trendverlag.de
26
27#pragma once
28
29#include <cassert>
30#include <cmath>
31#include <stdexcept>
32#include <utility>
33
34
35namespace spat{
36
37 template<typename> struct Position2D;
38 template<typename> struct Vector;
39
44 template<typename Valtype>
45 struct Vector2D
46 {
47 typedef Valtype value_type;
48
49 Valtype dx;
50 Valtype dy;
51
52
54 enum class specials{
55 null= -1,
56 ex = 0,
57 ey = 1
58 };
59
60
68 constexpr Vector2D() noexcept = default;
69 constexpr Vector2D( Valtype dx, Valtype dy ) noexcept;
70 explicit constexpr Vector2D( specials s ) noexcept;
71 explicit Vector2D( const Position2D<Valtype>& p ) noexcept = delete;
72 explicit constexpr Vector2D( const Vector<Valtype>& v ) noexcept;
73 template<typename Valtype2>
74 explicit Vector2D( const Valtype2* pVal ) noexcept;
76
77
81 template<typename Valtype2>
82 Vector2D& operator=( const Vector<Valtype2>& vector ) noexcept;
84
85
89 const Valtype& operator[]( size_t index ) const;
90
91 Valtype& operator[]( size_t index );
93
94
97 Vector2D& Init( specials s = specials::ex ) noexcept;
98
99
101 constexpr bool Is( specials s ) const noexcept;
102
103
106 constexpr Valtype Length() const noexcept;
107
108
111 auto Normalize() noexcept -> decltype(Valtype{}/Valtype{});
112
113
115 template<typename Valtype2>
116 Vector2D& Rotate( Valtype2 angle ) noexcept;
117
118
122 constexpr Vector2D ParallelProjection( const Vector2D& normal ) const noexcept;
123
124
128 constexpr Vector2D OrthogonalProjection( const Vector2D& normal ) const noexcept;
129
130
137 constexpr bool Equals( const Vector2D& v, Valtype epsilon = 0 ) const noexcept;
138 };
139
142 template<typename Valtype>
143 constexpr Vector2D<Valtype> Null2D{Valtype{0},Valtype{0}};
144
145 template<typename Valtype>
146 constexpr Vector2D<Valtype> Ex2D{Valtype{1},Valtype{0}};
147
148 template<typename Valtype>
149 constexpr Vector2D<Valtype> Ey2D{Valtype{0},Valtype{1}};
151
152
154 template<typename Valtype,typename Valtype2>
156
158 template<typename Valtype,typename Valtype2>
159 const Vector2D<Valtype>& spatial_cast( const Vector2D<Valtype2>& from ) noexcept;
160
161
166 template<typename Valtype> constexpr
167 Vector2D<Valtype> operator+( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept;
168 template<typename Valtype>
170 template<typename Valtype> constexpr
171 Vector2D<Valtype> operator+( const Vector2D<Valtype>& v ) noexcept;
172 template<typename Valtype> constexpr
173 Vector2D<Valtype> operator-( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept;
174 template<typename Valtype>
176 template<typename Valtype> constexpr
177 Vector2D<Valtype> operator-( const Vector2D<Valtype>& v ) noexcept;
178 template<typename Valtype,typename Valtype2> constexpr
179 auto operator*( const Vector2D<Valtype>& v1, const Vector2D<Valtype2>& v2 ) noexcept -> decltype(Valtype{}*Valtype2{});
180 template<typename Valtype,typename Valtype2> constexpr
181 auto operator*( const Vector2D<Valtype>& v, Valtype2 f ) noexcept -> Vector2D<decltype(Valtype{}*Valtype2{})>;
182 template<typename Valtype,typename Valtype2> constexpr
183 auto operator*( Valtype f, const Vector2D<Valtype2>& v ) noexcept -> Vector2D<decltype(Valtype{}*Valtype2{})>;
184 template<typename Valtype,typename Valtype2>
185 Vector2D<Valtype>& operator*=( Vector2D<Valtype>& v, const Valtype2& f ) noexcept;
186 template<typename Valtype>
188 template<typename Valtype> constexpr
189 Valtype operator%( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept;
190 template<typename Valtype>
192 template<typename Valtype,typename Valtype2> constexpr
193 auto operator/( const Vector2D<Valtype>&, const Vector2D<Valtype2>& ) = delete;
194 template<typename Valtype,typename Valtype2> constexpr
195 auto operator/( const Vector2D<Valtype>& v, Valtype2 f ) noexcept -> Vector2D<decltype(Valtype{}/Valtype2{})>;
196 template<typename Valtype,typename Valtype2> constexpr
197 auto operator/( const Valtype& f, const Vector2D<Valtype2>& v ) = delete;
198 template<typename Valtype,typename Valtype2>
199 Vector2D<Valtype>& operator/=( Vector2D<Valtype>& v, Valtype2 f ) noexcept;
200 template<typename Valtype> constexpr
201 bool operator==( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept;
202 template<typename Valtype> constexpr
203 bool operator!=( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept;
205
208 template<typename Valtype>
209 auto Normalize( const Vector2D<Valtype>& v ) noexcept -> std::pair<Valtype,Vector2D<decltype(Valtype{}/Valtype{})>>;
210
211 template<typename Valtype>
212 constexpr size_t size( const Vector2D<Valtype> ) noexcept {
213 return 2;
214 }
215
216template<typename Valtype> constexpr
217inline Vector2D<Valtype>::Vector2D( Valtype dx, Valtype dy ) noexcept
218 : dx{dx}, dy{dy}
219{}
220
221template<typename Valtype> constexpr
223 : dx{s == specials::ex ? Valtype{1} : Valtype{0}},
224 dy{s == specials::ey ? Valtype{1} : Valtype{0}}
225{}
226
227template<typename Valtype> constexpr
229 : dx{v.dx}, dy{v.dy}
230{}
231
232template<typename Valtype>
233template<typename Valtype2>
234inline Vector2D<Valtype>::Vector2D( const Valtype2* pVal ) noexcept
235 : dx{ Valtype{pVal[0]} },
236 dy{ Valtype{pVal[1]} }
237{}
238
239template<typename Valtype>
240template<typename Valtype2>
241inline Vector2D<Valtype>& Vector2D<Valtype>::operator=( const Vector<Valtype2>& v ) noexcept{
242 dx = Valtype{v.dx};
243 dy = Valtype{v.dy};
244 return *this;
245}
246
247template<typename Valtype>
248inline const Valtype& Vector2D<Valtype>::operator[]( size_t index ) const{
249 if( index < 2 )
250 return (&dx)[index];
251
252 throw std::out_of_range( "invalid Vector2D subscript" );
253}
254
255template<typename Valtype>
256inline Valtype& Vector2D<Valtype>::operator[]( size_t index ){
257 if( index < 2 )
258 return (&dx)[index];
259
260 throw std::out_of_range( "invalid Vector2D subscript" );
261}
262
263template<typename Valtype>
265 dx = s == specials::ex ? Valtype{1} : Valtype{0};
266 dy = s == specials::ey ? Valtype{1} : Valtype{0};
267 return *this;
268}
269
270template<typename Valtype>
271constexpr bool Vector2D<Valtype>::Is( specials s ) const noexcept{
272 switch(s){
273 case specials::null:
274 return *this == Null2D<Valtype>;
275 case specials::ex:
276 return *this == Ex2D<Valtype>;
277 case specials::ey:
278 return *this == Ey2D<Valtype>;
279 default:
280 assert( false );
281 }
282
283 return false;
284}
285
286template<typename Valtype> constexpr
287inline Valtype Vector2D<Valtype>::Length() const noexcept{
288 return sqrt( dx*dx + dy*dy );
289}
290
291template<typename Valtype>
292inline auto Vector2D<Valtype>::Normalize() noexcept -> decltype(Valtype{}/Valtype{}){
293 decltype(Valtype{}/Valtype{}) L = Length() / Valtype{1};
294 if( !L ){
295 Init();
296 return decltype(Valtype{}/Valtype{}){0};
297 }
298 *this /= L;
299 return L;
300}
301
302template<typename Valtype>
303template<typename Valtype2>
304Vector2D<Valtype>& Vector2D<Valtype>::Rotate( Valtype2 angle ) noexcept{
305 *this = cos( angle ) * *this + sin( angle ) * Vector2D<Valtype>{ -dy, dx };
306 return *this;
307}
308
309template<typename Valtype> constexpr
311 Valtype nl2 = normal * normal;
312 if( nl2 == 0 )
313 return Null2D<Valtype>;
314
315 return (*this * normal) / nl2 * normal;
316}
317
318template<typename Valtype> constexpr
320 return *this - ParallelProjection( normal );
321}
322
323template<typename Valtype>
324constexpr bool Vector2D<Valtype>::Equals( const Vector2D<Valtype>& v, Valtype epsilon_ ) const noexcept{
325 const Vector2D<Valtype> d{*this - v};
326 return d*d <= epsilon_*epsilon_;
327}
328
329template<typename Valtype,typename Valtype2>
331 static_assert( sizeof(Valtype) == sizeof(Valtype2), "Can not spatial_cast with different memory layout" );
332 return reinterpret_cast<Vector2D<Valtype>&>(from);
333}
334
335template<typename Valtype,typename Valtype2>
336inline const Vector2D<Valtype>& spatial_cast( const Vector2D<Valtype2>& from ) noexcept{
337 static_assert( sizeof(Valtype) == sizeof(Valtype2), "Can not spatial_cast with different memory layout" );
338 return reinterpret_cast<const Vector2D<Valtype>&>(from);
339}
340
341template<typename Valtype> constexpr
342inline Vector2D<Valtype> operator+( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept{
343 return { v1.dx + v2.dx,
344 v1.dy + v2.dy };
345}
346
347template<typename Valtype>
349 v1.dx += v2.dx;
350 v1.dy += v2.dy;
351 return v1;
352}
353
354template<typename Valtype> constexpr
355inline Vector2D<Valtype> operator+( const Vector2D<Valtype>& v ) noexcept{
356 return { +v.dx, +v.dy };
357}
358
359template<typename Valtype> constexpr
360inline Vector2D<Valtype> operator-( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept{
361 return { v1.dx - v2.dx,
362 v1.dy - v2.dy };
363}
364
365template<typename Valtype>
367 v1.dx -= v2.dx;
368 v1.dy -= v2.dy;
369 return v1;
370}
371
372template<typename Valtype> constexpr
373inline Vector2D<Valtype> operator-( const Vector2D<Valtype>& v ) noexcept{
374 return { -v.dx, -v.dy };
375}
376
377template<typename Valtype,typename Valtype2> constexpr
378inline auto operator*( const Vector2D<Valtype>& v1, const Vector2D<Valtype2>& v2 ) noexcept -> decltype(Valtype{}*Valtype2{}){
379 return v1.dx*v2.dx + v1.dy*v2.dy;
380}
381
382template<typename Valtype,typename Valtype2> constexpr
383inline auto operator*( const Vector2D<Valtype>& v, Valtype2 f ) noexcept -> Vector2D<decltype(Valtype{}*Valtype2{})>{
384 static_assert( !std::is_integral<Valtype>::value, "Possible data loss on integral values, proper implementation provided for int only!" );
385 return { v.dx * f,
386 v.dy * f };
387}
388
389template<typename Valtype> constexpr
390inline Vector2D<int> operator*( const Vector2D<int>& v, Valtype f ) noexcept {
391 return { static_cast<int>(static_cast<Valtype>(v.dx) * f),
392 static_cast<int>(static_cast<Valtype>(v.dy) * f) };
393}
394
395template<typename Valtype,typename Valtype2> constexpr
396inline auto operator*( Valtype f, const Vector2D<Valtype2>& v ) noexcept -> Vector2D<decltype(Valtype{}*Valtype2{})>{
397 static_assert( !std::is_integral<Valtype2>::value, "Possible data loss on integral values, proper implementation provided for int only!" );
398 return v * f;
399}
400
401template<typename Valtype> constexpr
402inline Vector2D<int> operator*( Valtype f, const Vector2D<int>& v ) noexcept{
403 return v * f;
404}
405
406template<typename Valtype,typename Valtype2>
407inline Vector2D<Valtype>& operator*=( Vector2D<Valtype>& v, const Valtype2& f ) noexcept{
408 static_assert( !std::is_integral<Valtype>::value, "Possible data loss on integral values, proper implementation provided for int only!" );
409 v.dx *= f;
410 v.dy *= f;
411 return v;
412}
413
414template<typename Valtype>
415inline Vector2D<int>& operator*=( Vector2D<int>& v, Valtype f ) noexcept{
416 v.dx = static_cast<int>(static_cast<Valtype>(v.dx) * f);
417 v.dy = static_cast<int>(static_cast<Valtype>(v.dy) * f);
418 return v;
419}
420
421template<typename Valtype> constexpr
422inline Valtype operator%( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept{
423 return v1.dx * v2.dy - v1.dy * v2.dx;
424}
425
426template<typename Valtype,typename Valtype2> constexpr
427inline auto operator/( const Vector2D<Valtype>& v, Valtype2 f ) noexcept -> Vector2D<decltype(Valtype{}/Valtype2{})>{
428 static_assert( !std::is_integral<Valtype>::value, "Possible data loss on integral values, proper implementation provided for int only!" );
429 return { v.dx / f,
430 v.dy / f };
431}
432
433template<typename Valtype> constexpr
434inline Vector2D<int> operator/( const Vector2D<int>& v, Valtype f ) noexcept{
435 return { static_cast<int>(static_cast<Valtype>(v.dx) / f),
436 static_cast<int>(static_cast<Valtype>(v.dy) / f) };
437}
438
439template<typename Valtype,typename Valtype2>
440inline Vector2D<Valtype>& operator/=( Vector2D<Valtype>& v, Valtype2 f ) noexcept{
441 static_assert( !std::is_integral<Valtype>::value, "Possible data loss on integral values, proper implementation provided for int only!" );
442 v.dx /= f;
443 v.dy /= f;
444 return v;
445}
446
447template<typename Valtype>
448inline Vector2D<int>& operator/=( Vector2D<int>& v, Valtype f ) noexcept{
449 v.dx = static_cast<int>(static_cast<Valtype>(v.dx) / f);
450 v.dy = static_cast<int>(static_cast<Valtype>(v.dy) / f);
451 return v;
452}
453
454template<typename Valtype> constexpr
455inline bool operator==( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept{
456 return v1.dx == v2.dx && v1.dy == v2.dy;
457}
458
459template<typename Valtype> constexpr
460inline bool operator!=( const Vector2D<Valtype>& v1, const Vector2D<Valtype>& v2 ) noexcept{
461 return !(v1 == v2);
462}
463
464template<typename Valtype>
465auto Normalize( const Vector2D<Valtype>& v ) noexcept -> std::pair<Valtype,Vector2D<decltype(Valtype{}/Valtype{})>> {
466 Vector2D<decltype(Valtype{}/Valtype{})> V{ v.dx / Valtype{1},
467 v.dy / Valtype{1} };
468 return std::make_pair( V.Normalize() * Valtype{1}, V );
469}
470
471} // namespace spat
constexpr Interval< Valtype > operator+(const Interval< Valtype > &i1, const Interval< Valtype > &i2) noexcept
Interval operator.
Definition Interval.h:591
constexpr Interval< Valtype > operator-(const Interval< Valtype > &i1, Valtype l) noexcept
Interval operator.
Definition Interval.h:613
constexpr Value< Dimension< 0, 0, 0 > > cos(Value< Dimension< 0, 0, 0 > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:698
constexpr Value< Dimension< 0, 0, 0 > > sin(Value< Dimension< 0, 0, 0 > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:694
The namespace provides classes and methods for spatial computations.
Definition Box.h:32
Position< Valtype2 > operator*(const Frame< Valtype1, ValtypeT1 > &frame, const Position< Valtype2 > &p) noexcept
Frame operator.
Definition Frame.h:1089
Position< Valtype > & operator%=(const Position< Valtype > &, const Position< Valtype > &)=delete
Position operator.
Position< Valtype > & operator+=(Position< Valtype > &, const Position< Valtype > &)=delete
Position operator.
constexpr Position< Valtype > operator%(const Position< Valtype > &, const Position< Valtype > &)=delete
Position operator.
Position< Valtype > & operator-=(Position< Valtype > &, const Position< Valtype > &)=delete
Position operator.
Frame< Valtype2, ValtypeT2 > & operator*=(Frame< Valtype1, ValtypeT1 > &frame, const Frame< Valtype2, ValtypeT2 > &f) noexcept
right side multiplication of f to frame.
Definition Frame.h:1131
Frame< Valtype, ValtypeT > & spatial_cast(Frame< Valtype2, ValtypeT2 > &from) noexcept
Cast to Frame with different underlying value types.
Definition Frame.h:1062
constexpr Valtype operator/(const Position< Valtype > &, const Position< Valtype > &)=delete
Position operator.
Implements a 2D - position in cartesian coordinates.
Definition Position2D.h:45
Implements a 2D - vector in cartesian coordinates.
Definition Vector2D.h:46
specials
Identifiers for special vectors.
Definition Vector2D.h:54
@ null
Vector with all parameters zeroed.
Definition Vector2D.h:55
@ ex
Unit vector in x-direction.
Definition Vector2D.h:56
@ ey
Unit vector in y-direction.
Definition Vector2D.h:57
constexpr Vector2D ParallelProjection(const Vector2D &normal) const noexcept
Part of this tVector wich is parallel to normal.
Definition Vector2D.h:310
constexpr Vector2D() noexcept=default
Does not initialize the members.
auto Normalize() noexcept -> decltype(dim::Value< Dimension< 1, 0, 0 > >{}/dim::Value< Dimension< 1, 0, 0 > >{})
Definition Vector2D.h:292
Valtype dy
cartesian y component.
Definition Vector2D.h:50
constexpr Vector2D OrthogonalProjection(const Vector2D &normal) const noexcept
Calculate part of this tVector wich is orthogonal to normal.
Definition Vector2D.h:319
constexpr bool Equals(const Vector2D &v, Valtype epsilon=0) const noexcept
Comparison within some range. The area within two vectors regarded as equal is a sphere with radius e...
Definition Vector2D.h:324
Vector2D & Rotate(Valtype2 angle) noexcept
Rotate this vector with angle in radiants.
Vector2D & Init(specials s=specials::ex) noexcept
Definition Vector2D.h:264
constexpr dim::Value< Dimension< 1, 0, 0 > > Length() const noexcept
Definition Vector2D.h:287
Valtype dx
cartesian x component.
Definition Vector2D.h:49
constexpr bool Is(specials s) const noexcept
Definition Vector2D.h:271
Implements a 3D - vector in cartesian coordinates.
Definition Vector.h:48