template <typename P> explicitVec( P const &p ) { for ( int i=0; i<N; ++i ) elem[i]=(T)p[i]; }
//!@name Set & Get value methods
voidZero() { MemClear(elem,N); } //!< Sets the coordinates as zero
voidGet( T * restrict p ) const { MemCopy(p,elem,N); } //!< Puts the coordinate values into the array
voidSet( T const * restrict p ) { MemCopy(elem,p,N); } //!< Sets the coordinates using the values in the given array
voidSet( T v ) { for ( int i=0; i<N; ++i ) elem[i] = v; } //!< Sets all coordinates using the given value
template <int M> voidCopyData( T * restrict p ) { if ( M <= N ) { MemCopy(p,elem,M); } else { MemCopy(p,elem,N); MemClear(p+N,M-N); } }
template <typename S, int M> voidConvertData( S * restrict p ) { if ( M <= N ) { MemConvert(p,elem,M); } else { MemConvert(p,elem,N); MemClear(p+N,M-N); } }
voidNormalize() { *this /= Length(); } //!< Normalizes the vector, such that its length becomes 1.
//!@name General methods
CY_NODISCARD Vec GetNormalized() const { return *this / Length(); } //!< Returns a normalized copy of the vector.
CY_NODISCARD T LengthSquared() const { Vec p=operator*(*this); return p.Sum(); } //!< Returns the square of the length. Effectively, this is the dot product of the vector with itself.
CY_NODISCARD T Length () const { returncy::Sqrt(LengthSquared()); } //!< Returns the length of the vector.
CY_NODISCARD T Sum () const { T v=elem[0]; for ( int i=1; i<N; ++i ) v+=elem[i]; return v; } //!< Returns the sum of its components
CY_NODISCARDboolIsZero () const { for ( int i=0; i<N; ++i ) if ( elem[i] != T(0) ) returnfalse; returntrue; } //!< Returns true if all components are exactly zero
CY_NODISCARD T Min () const { T m = elem[0]; for ( int i=1; i<N; ++i ) if ( m > elem[i] ) m = elem[i]; return m; } //!< Returns the minimum component of the vector.
CY_NODISCARD T Max () const { T m = elem[0]; for ( int i=1; i<N; ++i ) if ( m < elem[i] ) m = elem[i]; return m; } //!< Returns the maximum component of the vector.
CY_NODISCARDintMinComp () const { T m = elem[0]; int ix=0; for ( int i=1; i<N; ++i ) if ( m > elem[i] ) { m = elem[i]; ix = i; } return ix; } //!< Returns the index of the minimum component of the vector.
CY_NODISCARDintMaxComp () const { T m = elem[0]; int ix=0; for ( int i=1; i<N; ++i ) if ( m < elem[i] ) { m = elem[i]; ix = i; } return ix; } //!< Returns the index of the maximum component of the vector.
CY_NODISCARDboolIsFinite () const { for ( int i=0; i<N; ++i ) if ( ! cy::IsFinite(elem[i]) ) returnfalse; returntrue; } //!< Returns true if all components are finite real numbers.
CY_NODISCARDboolIsUnit () const { returnstd::abs(LengthSquared()-T(1)) < T(0.001); } //!< Returns true if the length of the vector is close to 1.
CY_NODISCARD Vec Sqrt () const { Vec v; for ( int i=0; i<N; ++i ) v.elem[i] = cy::Sqrt(elem[i]); return v; } //!< Returns the square root of the vector.
CY_NODISCARD Vec Abs () const { Vec v; for ( int i=0; i<N; ++i ) v.elem[i] = std::abs(elem[i]); return v; } //!< Returns a vector containing the absolute values of all components.
//!@name Limit methods
voidClamp ( T minLimit, T maxLimit ) { ClampMin(minLimit); ClampMax(maxLimit); } //!< Ensures that all components of the vector are within the given limits.
voidClampMin( T v ) { for ( int i=0; i<N; ++i ) elem[i] = (elem[i]<v) ? v : elem[i]; } //!< Ensures that all components of the vector are greater than or equal to the given limit.
voidClampMax( T v ) { for ( int i=0; i<N; ++i ) elem[i] = (elem[i]>v) ? v : elem[i]; } //!< Ensures that all components of the vector are smaller than or equal to the given limit.
voidSetAbs () { for ( int i=0; i<N; i++ ) elem[i] = std::abs(elem[i]); } //!< Converts all negative components to positive values
//!@name Unary operators
CY_NODISCARD Vec operator - () const { Vec r; for ( int i=0; i<N; ++i ) r.elem[i]=-elem[i]; return r; }
voidZero() { MemClear(elem,2); } //!< Sets the coordinates as zero.
voidGet( T * restrict p ) const { ((Vec2*)p)->operator=(*this); } //!< Puts the coordinate values into the array.
voidSet( T const * restrict p ) { operator=(*((Vec2*)p)); } //!< Sets the coordinates using the values in the given array.
voidSet( T v ) { x=v; y=v; } //!< Sets all coordinates using the given value
voidSet( T _x, T _y ) { x=_x; y=_y; } //!< Sets the coordinates using the given values
voidNormalize() { *this /= Length(); } //!< Normalizes the vector, such that its length becomes 1.
//!@name General methods
CY_NODISCARD Vec2 GetNormalized () const { return *this / Length(); } //!< Returns a normalized copy of the vector.
CY_NODISCARD T LengthSquared () const { Vec2 p=operator*(*this); return p.Sum(); } //!< Returns the square of the length. Effectively, this is the dot product of the vector with itself.
CY_NODISCARD T Length () const { returncy::Sqrt(LengthSquared()); } //!< Returns the length of the vector.
CY_NODISCARD T Sum () const { return x+y; } //!< Returns the sum of its components
CY_NODISCARDboolIsZero () const { return x==T(0) && y==T(0); } //!< Returns true if all components are exactly zero
CY_NODISCARD T Min () const { returncy::Min(x,y); } //!< Returns the minimum component of the vector.
CY_NODISCARD T Max () const { returncy::Max(x,y); } //!< Returns the maximum component of the vector.
CY_NODISCARDintMinComp () const { return x>y; } //!< Returns the index of the minimum component of the vector.
CY_NODISCARDintMaxComp () const { return x<y; } //!< Returns the index of the maximum component of the vector.
CY_NODISCARDboolIsFinite () const { returncy::IsFinite(x) && cy::IsFinite(y); } //!< Returns true if all components are finite real numbers.
CY_NODISCARDboolIsUnit () const { returnstd::abs(LengthSquared()-T(1)) < T(0.001); } //!< Returns true if the length of the vector is close to 1.
CY_NODISCARD Vec2 Sqrt () const { returnVec2(cy::Sqrt(x),cy::Sqrt(y)); } //!< Returns the square root of the vector.
CY_NODISCARD Vec2 Abs () const { returnVec2(std::abs(x),std::abs(y)); } //!< Returns a vector containing the absolute values of all components.
CY_NODISCARD Vec2 SortAsc () const { Vec2 v; Sort2<true >( v.elem, elem ); return v; } //!< Returns a vector with components sorted in ascending order.
CY_NODISCARD Vec2 SortDesc () const { Vec2 v; Sort2<false>( v.elem, elem ); return v; } //!< Returns a vector with components sorted in descending order.
CY_NODISCARD Vec2 GetPerpendicular() const { returnVec2(-y,x); } //!< Returns a perpendicular vector (rotated by 90 degrees in counter clockwise direction).
//!@name Limit methods
voidClamp ( T minLimit, T maxLimit ) { ClampMin(minLimit); ClampMax(maxLimit); } //!< Ensures that all components of the vector are within the given limits.
voidClampMin( T v ) { x=(x<v)?v:x; y=(y<v)?v:y; } //!< Ensures that all components of the vector are greater than or equal to the given limit.
voidClampMax( T v ) { x=(x>v)?v:x; y=(y>v)?v:y; } //!< Ensures that all components of the vector are smaller than or equal to the given limit.
voidSetAbs () { x=std::abs(x); y=std::abs(y); } //!< Converts all negative components to positive values
voidZero() { MemClear(elem,3); } //!< Sets the coordinates as zero.
voidGet( T * restrict p ) const { ((Vec3*)p)->operator=(*this); } //!< Puts the coordinate values into the array.
voidSet( T const * restrict p ) { operator=(*((Vec3*)p)); } //!< Sets the coordinates using the values in the given array.
voidSet( T v ) { x=v; y=v; z=v; } //!< Sets all coordinates using the given value.
voidSet( T _x, T _y, T _z ) { x= _x; y= _y; z=_z; } //!< Sets the coordinates using the given values.
voidSet( Vec2<T> const &p, T _z ) { x=p.x; y=p.y; z=_z; } //!< Sets the coordinates using the given values.
voidNormalize() { *this /= Length(); } //!< Normalizes the vector, such that its length becomes 1.
//!@name General methods
CY_NODISCARD Vec3 GetNormalized () const { return *this / Length(); } //!< Returns a normalized copy of the vector.
CY_NODISCARD T LengthSquared () const { Vec3 p=operator*(*this); return p.Sum(); } //!< Returns the square of the length. Effectively, this is the dot product of the vector with itself.
CY_NODISCARD T Length () const { returncy::Sqrt(LengthSquared()); } //!< Returns the length of the vector.
CY_NODISCARD T Sum () const { return x+y+z; } //!< Returns the sum of its components.
CY_NODISCARDboolIsZero () const { return x==T(0) && y==T(0) && z==T(0); } //!< Returns true if all components are exactly zero.
CY_NODISCARD T Min () const { returncy::Min(x,y,z); } //!< Returns the minimum component of the vector.
CY_NODISCARD T Max () const { returncy::Max(x,y,z); } //!< Returns the maximum component of the vector.
CY_NODISCARDintMinComp () const { int yx=y<x; int zx=z<x; int zy=z<y; return (yx|zx)+(zx&zy); } //!< Returns the index of the minimum component of the vector.
CY_NODISCARDintMaxComp () const { int xy=x<y; int xz=x<z; int yz=y<z; return (xy|xz)+(xz&yz); } //!< Returns the index of the maximum component of the vector.
CY_NODISCARDboolIsFinite () const { returncy::IsFinite(x) && cy::IsFinite(y) && cy::IsFinite(z); } //!< Returns true if all components are finite real numbers.
CY_NODISCARDboolIsUnit () const { returnstd::abs(LengthSquared()-T(1)) < T(0.001); } //!< Returns true if the length of the vector is close to 1.
CY_NODISCARD Vec3 Sqrt () const { returnVec3(cy::Sqrt(x),cy::Sqrt(y),cy::Sqrt(z)); } //!< Returns the square root of the vector.
CY_NODISCARD Vec3 Abs () const { returnVec3(std::abs(x),std::abs(y),std::abs(z)); } //!< Returns a vector containing the absolute values of all components.
CY_NODISCARD Vec3 SortAsc () const { Vec3 v; Sort3<true >( v.elem, elem ); return v; } //!< Returns a vector with components sorted in ascending order.
CY_NODISCARD Vec3 SortDesc () const { Vec3 v; Sort3<false>( v.elem, elem ); return v; } //!< Returns a vector with components sorted in descending order.
voidGetOrthonormals ( Vec3 &v0, Vec3 &v1 ) const//!< Returns two orthogonal vectors to this vector, forming an orthonormal basis
{
if ( z >= y ) {
T const a = T(1)/(1 + z);
T const b = -x*y*a;
v0.Set( 1 - x*x*a, b, -x );
v1.Set( b, 1 - y*y*a, -y );
} else {
T const a = T(1)/(1 + y);
T const b = -x*z*a;
v0.Set( b, -z, 1 - z*z*a );
v1.Set( 1 - x*x*a, -x, b );
}
}
//!@name Limit methods
voidClamp ( T minLimit, T maxLimit ) { ClampMin(minLimit); ClampMax(maxLimit); } //!< Ensures that all components of the vector are within the given limits.
voidClampMin( T v ) { x=(x<v)?v:x; y=(y<v)?v:y; z=(z<v)?v:z; } //!< Ensures that all components of the vector are greater than or equal to the given limit.
voidClampMax( T v ) { x=(x>v)?v:x; y=(y>v)?v:y; z=(z>v)?v:z; } //!< Ensures that all components of the vector are smaller than or equal to the given limit.
voidSetAbs () { x=std::abs(x); y=std::abs(y); z=std::abs(z); } //!< Converts all negative components to positive values
voidZero() { MemClear(elem,4); } //!< Sets the coordinates as zero
voidGet( T * restrict p ) const { ((Vec4*)p)->operator=(*this); } //!< Puts the coordinate values into the array
voidSet( T const * restrict p ) { operator=(*((Vec4*)p)); } //!< Sets the coordinates using the values in the given array
voidSet( T v ) { x=v; y=v; z=v; w=v; } //!< Sets all coordinates using the given value
voidSet( T _x, T _y, T _z, T _w=1 ) { x= _x; y= _y; z= _z; w=_w; } //!< Sets the coordinates using the given values
voidSet( Vec2<T> const &p, T _z, T _w=1 ) { x=p.x; y=p.y; z= _z; w=_w; } //!< Sets the coordinates using the given values
voidSet( Vec3<T> const &p, T _w=1 ) { x=p.x; y=p.y; z=p.z; w=_w; } //!< Sets the coordinates using the given values
voidNormalize() { *this /= Length(); } //!< Normalizes the vector, such that its length becomes 1.
//!@name General methods
CY_NODISCARD Vec4 GetNormalized() const { return *this / Length(); } //!< Returns a normalized copy of the vector.
CY_NODISCARD T LengthSquared() const { Vec4 p=operator*(*this); return p.Sum(); } //!< Returns the square of the length. Effectively, this is the dot product of the vector with itself.
CY_NODISCARD T Length () const { returncy::Sqrt(LengthSquared()); } //!< Returns the length of the vector.
CY_NODISCARD T Sum () const { return x+y+z+w; } //!< Returns the sum of its components
CY_NODISCARDboolIsZero () const { return x==T(0) && y==T(0) && z==T(0) && w==T(0); } //!< Returns true if all components are exactly zero
CY_NODISCARD T Min () const { returncy::Min(x,y,z,w); } //!< Returns the minimum component of the vector.
CY_NODISCARD T Max () const { returncy::Max(x,y,z,w); } //!< Returns the maximum component of the vector.
CY_NODISCARDintMinComp () const { int xy=x>y; int zw=(z>w)+2; return elem[xy]<elem[zw]?xy:zw; } //!< Returns the index of the minimum component of the vector.
CY_NODISCARDintMaxComp () const { int xy=x<y; int zw=(z<w)+2; return elem[xy]>elem[zw]?xy:zw; } //!< Returns the index of the maximum component of the vector.
CY_NODISCARDboolIsFinite () const { returncy::IsFinite(x) && cy::IsFinite(y) && cy::IsFinite(z) && cy::IsFinite(w); } //!< Returns true if all components are finite real numbers.
CY_NODISCARDboolIsUnit () const { returnstd::abs(LengthSquared()-T(1)) < T(0.001); } //!< Returns true if the length of the vector is close to 1.
CY_NODISCARD Vec4 Sqrt () const { returnVec4(cy::Sqrt(x),cy::Sqrt(y),cy::Sqrt(z),cy::Sqrt(w)); } //!< Returns the square root of the vector.
CY_NODISCARD Vec4 Abs () const { returnVec4(std::abs(x),std::abs(y),std::abs(z),std::abs(w)); } //!< Returns a vector containing the absolute values of all components.
CY_NODISCARD Vec4 SortAsc () const { Vec4 v; Sort4<true >( v.elem, elem ); return v; } //!< Returns a vector with components sorted in ascending order.
CY_NODISCARD Vec4 SortDesc () const { Vec4 v; Sort4<false>( v.elem, elem ); return v; } //!< Returns a vector with components sorted in descending order.
//!@name Limit methods
voidClamp ( T minLimit, T maxLimit ) { ClampMin(minLimit); ClampMax(maxLimit); } //!< Ensures that all components of the vector are within the given limits.
voidClampMin( T v ) { x=(x<v)?v:x; y=(y<v)?v:y; z=(z<v)?v:z; w=(w<v)?v:w; } //!< Ensures that all components of the vector are greater than or equal to the given limit.
voidClampMax( T v ) { x=(x>v)?v:x; y=(y>v)?v:y; z=(z>v)?v:z; w=(w>v)?v:w; } //!< Ensures that all components of the vector are smaller than or equal to the given limit.
voidSetAbs () { x=std::abs(x); y=std::abs(y); z=std::abs(z); w=std::abs(w); } //!< Converts all negative components to positive values