12 #ifndef MATH_H_6014714286
13 #define MATH_H_6014714286
15 #include <Carna/Carna.h>
18 #include <type_traits>
20 #include <Eigen/Dense>
23 #error MIN macro defined, define NOMINMAX first!
27 #error MAX macro defined, define NOMINMAX first!
63 template<
typename T >
64 T
clamp( T val, T my_min, T my_max )
66 return std::min( std::max( val, my_min ), my_max );
72 template<
typename T >
83 return deg * 3.1415926f / 180.f;
91 return 180.f * rad / 3.1415926f;
97 template<
typename T >
100 return static_cast< T
>( 0 );
127 template<
typename T >
140 template<
typename VectorElementType,
int rows,
int cols >
146 typedef VectorElementType
type;
154 template<
typename T >
164 template<
typename VectorElementType,
int dimension >
165 VectorElementType
length2(
const Eigen::Matrix< VectorElementType, dimension, 1 >& x )
167 return x.squaredNorm();
173 template<
typename InputType >
174 bool isEqual(
const InputType& x,
const InputType& y )
177 const InputType difference = x - y;
178 const ScalarType distance2 =
length2( InputType( difference ) );
179 const ScalarType _epsilon = epsilon< ScalarType >();
180 return distance2 <= _epsilon;
188 inline bool isEqual(
const bool& x,
const bool& y )
193 typedef Eigen::Matrix< float, 4, 4, Eigen::ColMajor >
Matrix4f;
194 typedef Eigen::Matrix< float, 3, 3, Eigen::ColMajor >
Matrix3f;
198 typedef Eigen::Matrix< signed int, 3, 1 >
Vector3i;
208 result.setIdentity();
218 result.setIdentity();
225 template<
typename MatrixType >
242 inline Matrix4f
basis4f(
const Vector4f& x,
const Vector4f& y,
const Vector4f& z,
const Vector4f& t =
Vector4f( 0, 0, 0, 0 ) )
249 for(
unsigned int i = 0; i < 3; ++i )
259 inline Matrix4f
basis4f(
const Vector3f& x,
const Vector3f& y,
const Vector3f& z,
const Vector3f& t =
Vector3f( 0, 0, 0 ) )
261 const Vector4f x4( x.x(), x.y(), x.z(), 0 );
262 const Vector4f y4( y.x(), y.y(), y.z(), 0 );
263 const Vector4f z4( z.x(), z.y(), z.z(), 0 );
264 const Vector4f t4( t.x(), t.y(), t.z(), 0 );
265 return basis4f( x4, y4, z4, t4 );
274 result.setIdentity();
283 template<
typename Vector >
295 result.setIdentity();
304 template<
typename VectorElementType >
305 inline Matrix4f
scaling4f(
const Eigen::Matrix< VectorElementType, 3, 1 >& v )
314 return scaling4f( uniformScaleFactor, uniformScaleFactor, uniformScaleFactor );
322 inline Matrix4f
rotation4f(
float x,
float y,
float z,
float radians )
324 const float c = std::cos( radians );
325 const float s = std::sin( radians );
328 result.setIdentity();
330 result( 0, 0 ) = x * x * ( 1 - c ) + c;
331 result( 1, 0 ) = y * x * ( 1 - c ) + z * s;
332 result( 2, 0 ) = x * z * ( 1 - c ) - y * s;
334 result( 0, 1 ) = x * y * ( 1 - c ) - z * s;
335 result( 1, 1 ) = y * y * ( 1 - c ) + c;
336 result( 2, 1 ) = y * z * ( 1 - c ) + x * s;
338 result( 0, 2 ) = x * z * ( 1 - c ) + y * s;
339 result( 1, 2 ) = y * z * ( 1 - c ) - x * s;
340 result( 2, 2 ) = z * z * ( 1 - c ) + c;
347 template<
typename Vector >
350 return rotation4f( v.x(), v.y(), v.z(), radians );
357 inline Matrix3f
rotation3f(
float x,
float y,
float z,
float radians )
359 return rotation4f( x, y, z, radians ).block< 3, 3 >( 0, 0 );
370 if( std::abs( in.x() - in.y() ) > 1e-4f )
376 if( std::abs( out.x() ) > std::abs( out.y() ) )
386 if( std::abs( in.x() - in.z() ) > 1e-4f )
392 if( std::abs( out.x() ) > std::abs( out.z() ) )
402 if( std::abs( in.y() - in.z() ) > 1e-4f )
408 if( std::abs( out.y() ) > std::abs( out.z() ) )
419 out =
Vector3f( -in.x(), in.y(), 0 );
433 template<
typename VectorElementType,
int rows,
typename WType >
434 Eigen::Matrix< VectorElementType, 4, 1 >
vector4(
const Eigen::Matrix< VectorElementType, rows, 1 >& v, WType w )
436 static_assert( rows >= 3,
"math::vector4 requires input vector with 3 rows or more." );
437 return Eigen::Matrix< VectorElementType, 4, 1 >( v.x(), v.y(), v.z(),
static_cast< VectorElementType
>( w ) );
444 template<
typename VectorElementType,
int rows >
445 Eigen::Matrix< VectorElementType, 3, 1 >
vector3(
const Eigen::Matrix< VectorElementType, rows, 1 >& v )
447 static_assert( rows >= 3,
"math::vector3 requires input vector with 3 rows or more." );
448 return Eigen::Matrix< VectorElementType, 3, 1 >( v.x(), v.y(), v.z() );
456 inline Matrix4f
plane4f(
const Vector3f& normal,
float distance )
459 const Vector3f tangent (
orthogonal3f( normal ).normalized() );
460 const Vector3f bitangent( normal.cross( tangent ).normalized() );
461 const Vector3f translation( normal * distance );
471 inline Matrix4f
plane4f(
const Vector3f& normal,
const Vector3f& support )
474 const float distance = normal.dot( support );
475 return plane4f( normal, distance );
484 return m( 0, 3 ) * m( 0, 3 ) + m( 1, 3 ) * m( 1, 3 ) + m( 2, 3 ) * m( 2, 3 );
490 template<
typename Matrix >
493 const std::size_t length = m.rows() * m.cols();
494 typename Matrix::Scalar maxAbs = 0;
495 for( std::size_t i = 0; i < length; ++i )
497 maxAbs = std::max( maxAbs, std::abs( m.data()[ i ] ) );
516 inline Matrix4f
frustum4f(
float left,
float right,
float bottom,
float top,
float zNear,
float zFar )
521 result( 0, 0 ) = +2 * zNear / ( right - left );
522 result( 1, 1 ) = +2 * zNear / ( top - bottom );
523 result( 0, 2 ) = ( right + left ) / ( right - left );
524 result( 1, 2 ) = ( top + bottom ) / ( top - bottom );
525 result( 2, 2 ) = -( zFar + zNear ) / ( zFar - zNear );
527 result( 2, 3 ) = -2 * zFar * zNear / ( zFar - zNear );
547 inline Matrix4f
frustum4f(
float fovRadiansHorizontal,
float heightOverWidth,
float zNear,
float zFar )
549 const float halfProjPlaneWidth = zNear * std::tan( fovRadiansHorizontal );
550 const float halfProjPlaneHeight = halfProjPlaneWidth * heightOverWidth;
551 return frustum4f( -halfProjPlaneWidth, +halfProjPlaneWidth, -halfProjPlaneHeight, +halfProjPlaneHeight, zNear, zFar );
557 inline Matrix4f
ortho4f(
float left,
float right,
float bottom,
float top,
float zNear,
float zFar )
562 result( 0, 0 ) = 2 / ( right - left );
563 result( 1, 1 ) = 2 / ( top - bottom );
564 result( 2, 2 ) = -2 / ( zFar - zNear );
565 result( 0, 3 ) = -( right + left ) / ( right - left );
566 result( 1, 3 ) = -( top + bottom ) / ( bottom - top );
567 result( 2, 3 ) = -( zFar + zNear ) / ( zFar - zNear );
577 template<
typename ScalarType >
580 CARNA_ASSERT( !std::numeric_limits< ScalarType >::is_signed || x >= 0 );
581 return static_cast< unsigned int >( x +
static_cast< ScalarType
>( 0.5 ) );
589 template<
typename MatrixElementType,
int cols,
int rows >
590 Eigen::Matrix< unsigned int, cols, rows >
round_ui(
const Eigen::Matrix< MatrixElementType, cols, rows >& m )
592 Eigen::Matrix< unsigned int, cols, rows > result;
593 for(
int i = 0; i < cols; ++i )
594 for(
int j = 0; j < rows; ++j )
596 result( i, j ) =
round_ui( m( i, j ) );
605 template<
typename ScalarType >
609 static_assert( std::is_integral< ScalarType >::value,
"Only integral data types allowed." );
610 return x + s * ( x % 2 );
620 template<
typename MatrixElementType,
int cols,
int rows >
621 Eigen::Matrix< MatrixElementType, cols, rows >
makeEven(
const Eigen::Matrix< MatrixElementType, cols, rows >& m,
int s )
623 Eigen::Matrix< unsigned int, cols, rows > result;
624 for(
int i = 0; i < cols; ++i )
625 for(
int j = 0; j < rows; ++j )
627 result( i, j ) =
makeEven( m( i, j ), s );
635 template<
typename T >
644 Statistics( T mean, T variance ) : mean( mean ), variance( variance )
651 Statistics( std::size_t size,
const std::function< T( std::size_t ) > values )
662 for( std::size_t idx = 0; idx < size; ++idx )
664 sum += values( idx );
671 for( std::size_t idx = 0; idx < size; ++idx )
673 sum +=
sq( mean - values( idx ) );
675 variance = sum / ( size - 1 );
694 return std::sqrt( variance );
701 template<
typename ResultType,
typename SupportType >
702 ResultType
mix(
const SupportType& a,
const SupportType& b,
float t )
704 return a * ( 1 - t ) + b * t;
714 #define CARNA_FOR_VECTOR3UI_EX( vecName, vecLimit, vecStart ) \
715 Carna::base::math::Vector3ui vecName; \
716 for( vecName.z() = vecStart.x(); vecName.z() < vecLimit.z(); ++vecName.z() ) \
717 for( vecName.y() = vecStart.y(); vecName.y() < vecLimit.y(); ++vecName.y() ) \
718 for( vecName.x() = vecStart.z(); vecName.x() < vecLimit.x(); ++vecName.x() )
728 #define CARNA_FOR_VECTOR3UI( vecName, vecLimit ) \
729 CARNA_FOR_VECTOR3UI_EX( vecName, vecLimit, Carna::base::math::Vector3ui( 0, 0, 0 ) )
741 #endif // MATH_H_6014714286
Eigen::Matrix< VectorElementType, 3, 1 > vector3(const Eigen::Matrix< VectorElementType, rows, 1 > &v)
Creates 3-dimensional vector from 4-dimensional (or higher) with same component type by dropping the ...
Holds mean and variance of an characteristic.
Eigen::Matrix< float, 2, 1 > Vector2f
Defines vector.
unsigned int round_ui(ScalarType x)
Rounds x to the closest . Either the data type of must be unsigned or .
ScalarType makeEven(ScalarType x, int s)
Returns if is even and if is odd, where . The data type of must be integral. ...
T length2(const T &x)
Retrieves the squared length of vector and scalar types. General case assumes scalar type...
float epsilon< float >()
Defines the maximum difference of two single-precision floating point objects treated as equal...
Matrix4f scaling4f(float x, float y, float z)
Creates scaling matrix for homogeneous coordinates.
Eigen::Matrix< float, 4, 1 > Vector4f
Defines vector.
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
ResultType mix(const SupportType &a, const SupportType &b, float t)
Interpolates between and by t linearly.
Matrix4f basis4f(const Vector4f &x, const Vector4f &y, const Vector4f &z, const Vector4f &t=Vector4f(0, 0, 0, 0))
Creates basis embedded into a homogenous coordinates matrix.
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Matrix4f translation4f(float x, float y, float z)
Returns matrix that translates homogeneous coordinates.
Matrix4f rotation4f(float x, float y, float z, float radians)
Creates rotation matrix for homogeneous coordinates. The rotation is performed around the axis that i...
Statistics(T mean, T variance)
Initializes with mean and variance.
Matrix4f frustum4f(float left, float right, float bottom, float top, float zNear, float zFar)
Returns the projection matrix that is described by the specified frustum.
Matrix3f rotation3f(float x, float y, float z, float radians)
Creates rotation matrix for homogeneous coordinates, but returns only the upper left sub-matrix...
Vector3f orthogonal3f(const Vector3f &in)
Constructs vector that is orthogonal to in. The result is undefined if the squared length of in equa...
T epsilon()
Defines the maximum difference of two objects treated as equal.
Eigen::Matrix< float, 4, 4, Eigen::ColMajor > Matrix4f
Defines matrix.
double epsilon< double >()
Defines the maximum difference of two double-precision floating point objects treated as equal...
float rad2deg(float rad)
Converts radians to degrees.
Matrix4f identity4f()
Returns identity matrix.
T variance
Holds the variance.
T sq(T x)
Computes and returns .
Statistics(std::size_t size, const std::function< T(std::size_t) > values)
Computes statistics from size samples queried from values.
Matrix4f ortho4f(float left, float right, float bottom, float top, float zNear, float zFar)
Returns the projection matrix that is described by the specified box.
T type
Since T is assumed to be scalar type, it's element type is also T.
Matrix4f plane4f(const Vector3f &normal, float distance)
Creates matrix that transforms from the tangent space of a plane with particular normal vector and or...
Statistics< T > & operator=(const Statistics< T > &other)
Copies from other.
MatrixType zeros()
Returns matrix with zeros in all components.
Defines Carna::base::CarnaException, Carna::base::AssertionFailure.
bool isEqual(const InputType &x, const InputType &y)
Tells whether two objects are equal respectively to epsilon.
Eigen::Matrix< VectorElementType, 4, 1 > vector4(const Eigen::Matrix< VectorElementType, rows, 1 > &v, WType w)
Creates 4-dimensional vector from 3-dimensional (or higher) with same component type, and a scalar that is appended as the fourth component.
Eigen::Matrix< unsigned int, 2, 1 > Vector2ui
Defines vector.
#define CARNA_ASSERT(expression)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
Matrix3f identity3f()
Returns identity matrix.
VectorElementType type
The vector element type is known implicitly for each vector type.
T clamp(T val, T my_min, T my_max)
Returns val my_min my_max .
float deg2rad(float deg)
Converts degrees to radians.
Retrieves element types of vectors and scalars. General case assumes a scalar type.
T standardDeviation() const
Computes the standard deviation.
Matrix::Scalar maxAbsElement(const Matrix &m)
Returns where $m$ is m.
Eigen::Matrix< signed int, 3, 1 > Vector3i
Defines vector.
float translationDistance2(const Matrix4f &m)
Returns the squared length of the translation component of the homogeneous coordinates transformation...
Eigen::Matrix< float, 3, 3, Eigen::ColMajor > Matrix3f
Defines matrix.