MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMesh/MRVector3.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMacros.h"
4#include "MRMeshFwd.h"
5#include "MRConstants.h"
6#include <algorithm>
7#include <cmath>
8#if MR_HAS_REQUIRES
9#include <concepts>
10#endif
11
12namespace MR
13{
14
17template <typename T>
18struct Vector3
19{
20 using ValueType = T;
23 static constexpr int elements = 3;
24
25 T x, y, z;
26
27 constexpr Vector3() noexcept : x( 0 ), y( 0 ), z( 0 ) { }
28 explicit Vector3( NoInit ) noexcept { }
29 constexpr Vector3( T x, T y, T z ) noexcept : x( x ), y( y ), z( z ) { }
30 explicit constexpr Vector3( const Vector2<T> & v ) noexcept : x( v.x ), y( v.y ), z( 0 ) { }
31
32 static constexpr Vector3 diagonal( T a ) noexcept { return Vector3( a, a, a ); }
33 static constexpr Vector3 plusX() noexcept { return Vector3( 1, 0, 0 ); }
34 static constexpr Vector3 plusY() noexcept { return Vector3( 0, 1, 0 ); }
35 static constexpr Vector3 plusZ() noexcept { return Vector3( 0, 0, 1 ); }
36 static constexpr Vector3 minusX() noexcept { return Vector3( -1, 0, 0 ); }
37 static constexpr Vector3 minusY() noexcept { return Vector3( 0, -1, 0 ); }
38 static constexpr Vector3 minusZ() noexcept { return Vector3( 0, 0, -1 ); }
39
40 template <typename U>
41 constexpr explicit Vector3( const Vector3<U> & v ) noexcept : x( T( v.x ) ), y( T( v.y ) ), z( T( v.z ) ) { }
42
43 constexpr const T & operator []( int e ) const noexcept { return *( &x + e ); }
44 constexpr T & operator []( int e ) noexcept { return *( &x + e ); }
45
46 T lengthSq() const { return x * x + y * y + z * z; }
47 auto length() const
48 {
49 // Calling `sqrt` this way to hopefully support boost.multiprecision numbers.
50 // Returning `auto` to not break on integral types.
51 using std::sqrt;
52 return sqrt( lengthSq() );
53 }
54
55 [[nodiscard]] Vector3 normalized() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
56 {
57 auto len = length();
58 if ( len <= 0 )
59 return {};
60 return ( 1 / len ) * (*this);
61 }
62
64 Vector3 furthestBasisVector() const MR_REQUIRES_IF_SUPPORTED( !std::is_same_v<T, bool> );
65
68 std::pair<Vector3, Vector3> perpendicular() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> );
69
71 Vector3 transformed( const AffineXf3<T>* xf ) const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
72 {
73 return xf ? ( *xf )( *this ) : *this;
74 }
75
77 void unsignZeroValues() MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
78 {
79 for ( auto i = 0; i < elements; ++i )
80 if ( (*this)[i] == 0.f && std::signbit( (*this)[i] ) )
81 (*this)[i] = 0.f;
82 }
83
84 [[nodiscard]] bool isFinite() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
85 {
86 return std::isfinite( x ) && std::isfinite( y ) && std::isfinite( z );
87 }
88};
89
92
93template <typename T>
94inline Vector3<T> & operator +=( Vector3<T> & a, const Vector3<T> & b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
95
96template <typename T>
97inline Vector3<T> & operator -=( Vector3<T> & a, const Vector3<T> & b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
98
99template <typename T>
100inline Vector3<T> & operator *=( Vector3<T> & a, T b ) { a.x *= b; a.y *= b; a.z *= b; return a; }
101
102template <typename T>
103inline Vector3<T> & operator /=( Vector3<T> & a, T b )
104{
105 if constexpr ( std::is_integral_v<T> )
106 { a.x /= b; a.y /= b; a.z /= b; return a; }
107 else
108 return a *= ( 1 / b );
109}
110
111template <typename T>
112inline Vector3<T> operator -( const Vector3<T> & a ) { return Vector3<T>( -a.x, -a.y, -a.z ); }
113
114template <typename T>
115inline const Vector3<T> & operator +( const Vector3<T> & a ) { return a; }
116
118template <typename T>
119inline T distanceSq( const Vector3<T> & a, const Vector3<T> & b )
120{
121 return ( a - b ).lengthSq();
122}
123
125template <typename T>
126inline T distance( const Vector3<T> & a, const Vector3<T> & b )
127{
128 return ( a - b ).length();
129}
130
132template <typename T>
133inline Vector3<T> cross( const Vector3<T> & a, const Vector3<T> & b )
134{
135 return {
136 a.y * b.z - a.z * b.y,
137 a.z * b.x - a.x * b.z,
138 a.x * b.y - a.y * b.x
139 };
140}
141
143template <typename T>
144inline T dot( const Vector3<T> & a, const Vector3<T> & b )
145{
146 return a.x * b.x + a.y * b.y + a.z * b.z;
147}
148
150template <typename T>
151inline T sqr( const Vector3<T> & a )
152{
153 return a.lengthSq();
154}
155
157template <typename T>
158inline T mixed( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c )
159{
160 return dot( a, cross( b, c ) );
161}
162
164template <typename T>
165inline Vector3<T> mult( const Vector3<T>& a, const Vector3<T>& b )
166{
167 return { a.x * b.x,a.y * b.y,a.z * b.z };
168}
169
171template <typename T>
172inline Vector3<T> div( const Vector3<T>& a, const Vector3<T>& b )
173{
174 return { a.x / b.x, a.y / b.y, a.z / b.z };
175}
176
177
180template <typename T>
181inline T angle( const Vector3<T> & a, const Vector3<T> & b )
182{
183 return std::atan2( cross( a, b ).length(), dot( a, b ) );
184 // this version is slower and less precise
185 //return std::acos( std::clamp( dot( a.normalized(), b.normalized() ), T(-1), T(1) ) );
186}
187
188template <typename T>
189inline Vector3<T> Vector3<T>::furthestBasisVector() const MR_REQUIRES_IF_SUPPORTED( !std::is_same_v<T, bool> )
190{
191 using std::abs; // This should allow boost.multiprecision numbers here.
192 if ( abs( x ) < abs( y ) )
193 return ( abs( x ) < abs( z ) ) ? Vector3( 1, 0, 0 ) : Vector3( 0, 0, 1 );
194 else
195 return ( abs( y ) < abs( z ) ) ? Vector3( 0, 1, 0 ) : Vector3( 0, 0, 1 );
196}
197
198template <typename T>
199inline std::pair<Vector3<T>, Vector3<T>> Vector3<T>::perpendicular() const MR_REQUIRES_IF_SUPPORTED( std::floating_point<T> )
200{
201 std::pair<Vector3<T>, Vector3<T>> res;
202 auto c1 = furthestBasisVector();
203 res.first = cross( *this, c1 ).normalized();
204 res.second = cross( *this, res.first ).normalized();
205 return res;
206}
207
208template <typename T>
209[[nodiscard]] inline bool operator ==( const Vector3<T> & a, const Vector3<T> & b )
210 { return a.x == b.x && a.y == b.y && a.z == b.z; }
211
212template <typename T>
213[[nodiscard]] inline bool operator !=( const Vector3<T> & a, const Vector3<T> & b )
214 { return !( a == b ); }
215
216template <typename T>
217[[nodiscard]] inline constexpr Vector3<T> operator +( const Vector3<T> & a, const Vector3<T> & b )
218 { return { T( a.x + b.x ), T( a.y + b.y ), T( a.z + b.z ) }; }
219
220template <typename T>
221[[nodiscard]] inline Vector3<T> operator -( const Vector3<T> & a, const Vector3<T> & b )
222 { return { T( a.x - b.x ), T( a.y - b.y ), T( a.z - b.z ) }; }
223
224template <typename T>
225[[nodiscard]] inline Vector3<T> operator *( T a, const Vector3<T> & b )
226 { return { T( a * b.x ), T( a * b.y ), T( a * b.z ) }; }
227
228template <typename T>
229[[nodiscard]] inline Vector3<T> operator *( const Vector3<T> & b, T a )
230 { return { T( a * b.x ), T( a * b.y ), T( a * b.z ) }; }
231
232template <typename T>
233[[nodiscard]] inline Vector3<T> operator /( Vector3<T> b, T a )
234 { b /= a; return b; }
235
237template <typename T>
238Vector3<T> unitVector3( T azimuth, T altitude )
239{
240 const auto zenithAngle = T( PI2 ) - altitude;
241 return
242 {
243 std::sin( zenithAngle ) * std::cos( azimuth ),
244 std::sin( zenithAngle ) * std::sin( azimuth ),
245 std::cos( zenithAngle )
246 };
247}
248
249template <typename T>
250inline auto begin( const Vector3<T> & v ) { return &v[0]; }
251template <typename T>
252inline auto begin( Vector3<T> & v ) { return &v[0]; }
253
254template <typename T>
255inline auto end( const Vector3<T> & v ) { return &v[3]; }
256template <typename T>
257inline auto end( Vector3<T> & v ) { return &v[3]; }
258
260
261} // namespace MR
constexpr A & operator/=(A &a, B b)
Definition MRImGuiVectorOperators.h:115
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:29
length
Definition MRObjectDimensionsEnum.h:14
BitSet operator-(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:357
MR_BIND_IGNORE auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:295
MRMESH_API bool operator==(const BitSet &a, const BitSet &b)
compare that two bit sets have the same set bits (they can be equal even if sizes are distinct but la...
MR_BIND_IGNORE bool operator!=(const SetBitIteratorT< T > &a, const SetBitIteratorT< T > &b)
Definition MRMesh/MRBitSet.h:291
MR_BIND_IGNORE auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:297
MRMESH_API TransformedMesh & operator+=(TransformedMesh &a, const TransformedMesh &b)
union operation on two meshes
Color operator/(const Color &b, float a)
Definition MRMesh/MRColor.h:128
Color operator*(float a, const Color &b)
Definition MRMesh/MRColor.h:118
MRMESH_API TransformedMesh & operator-=(TransformedMesh &a, const TransformedMesh &b)
difference operation on two meshes
MRMESH_API TransformedMesh & operator*=(TransformedMesh &a, const TransformedMesh &b)
intersection operation on two meshes
MRMESH_CLASS Vector3
Definition MRMesh/MRMeshFwd.h:170
Color operator+(const Color &a, const Color &b)
Definition MRMesh/MRColor.h:108
Definition MRMesh/MRAffineXf.h:14
Definition MRMesh/MRMatrix3.h:13
Definition MRMesh/MRMeshFwd.h:89
Definition MRSymMatrix3.h:15
Definition MRVector2.h:18
Definition MRMesh/MRVector3.h:19
static constexpr Vector3 plusX() noexcept
Definition MRMesh/MRVector3.h:33
Vector3 transformed(const AffineXf3< T > *xf) const
returns this vector transformed by xf if it is
Definition MRMesh/MRVector3.h:71
Vector3< T > unitVector3(T azimuth, T altitude)
returns a point on unit sphere given two angles
Definition MRMesh/MRVector3.h:238
T distanceSq(const Vector3< T > &a, const Vector3< T > &b)
squared distance between two points, which is faster to compute than just distance
Definition MRMesh/MRVector3.h:119
Vector3< T > div(const Vector3< T > &a, const Vector3< T > &b)
per component division
Definition MRMesh/MRVector3.h:172
T dot(const Vector3< T > &a, const Vector3< T > &b)
dot product
Definition MRMesh/MRVector3.h:144
T x
Definition MRMesh/MRVector3.h:25
static constexpr Vector3 minusX() noexcept
Definition MRMesh/MRVector3.h:36
static constexpr Vector3 minusY() noexcept
Definition MRMesh/MRVector3.h:37
bool isFinite() const
Definition MRMesh/MRVector3.h:84
T y
Definition MRMesh/MRVector3.h:25
static constexpr int elements
Definition MRMesh/MRVector3.h:23
std::pair< Vector3, Vector3 > perpendicular() const
void unsignZeroValues()
get rid of signed zero values to be sure that equal vectors have identical binary representation
Definition MRMesh/MRVector3.h:77
Vector3(NoInit) noexcept
Definition MRMesh/MRVector3.h:28
T ValueType
Definition MRMesh/MRVector3.h:20
constexpr const T & operator[](int e) const noexcept
Definition MRMesh/MRVector3.h:43
auto length() const
Definition MRMesh/MRVector3.h:47
constexpr Vector3(T x, T y, T z) noexcept
Definition MRMesh/MRVector3.h:29
T distance(const Vector3< T > &a, const Vector3< T > &b)
distance between two points, better use distanceSq for higher performance
Definition MRMesh/MRVector3.h:126
T mixed(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c)
mixed product
Definition MRMesh/MRVector3.h:158
static constexpr Vector3 plusZ() noexcept
Definition MRMesh/MRVector3.h:35
T sqr(const Vector3< T > &a)
squared length
Definition MRMesh/MRVector3.h:151
Vector3 normalized() const
Definition MRMesh/MRVector3.h:55
T angle(const Vector3< T > &a, const Vector3< T > &b)
Definition MRMesh/MRVector3.h:181
constexpr Vector3(const Vector2< T > &v) noexcept
Definition MRMesh/MRVector3.h:30
constexpr Vector3(const Vector3< U > &v) noexcept
Definition MRMesh/MRVector3.h:41
constexpr Vector3() noexcept
Definition MRMesh/MRVector3.h:27
static constexpr Vector3 minusZ() noexcept
Definition MRMesh/MRVector3.h:38
Vector3< T > mult(const Vector3< T > &a, const Vector3< T > &b)
per component multiplication
Definition MRMesh/MRVector3.h:165
T z
Definition MRMesh/MRVector3.h:25
T lengthSq() const
Definition MRMesh/MRVector3.h:46
static constexpr Vector3 plusY() noexcept
Definition MRMesh/MRVector3.h:34
Vector3 furthestBasisVector() const
returns one of 3 basis unit vector that makes the biggest angle with the direction specified by this
static constexpr Vector3 diagonal(T a) noexcept
Definition MRMesh/MRVector3.h:32
Vector3< T > cross(const Vector3< T > &a, const Vector3< T > &b)
cross product
Definition MRMesh/MRVector3.h:133