Carna Version 3.3.3
Loading...
Searching...
No Matches
math.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 - 2015 Leonid Kostrykin
3 *
4 * Chair of Medical Engineering (mediTEC)
5 * RWTH Aachen University
6 * Pauwelsstr. 20
7 * 52074 Aachen
8 * Germany
9 *
10 */
11
12#ifndef MATH_H_6014714286
13#define MATH_H_6014714286
14
15#include <Carna/Carna.h>
17#include <algorithm>
18#include <type_traits>
19#include <cmath>
20#include <Eigen/Dense>
21
22#ifdef min
23#error MIN macro defined, define NOMINMAX first!
24#endif
25
26#ifdef max
27#error MAX macro defined, define NOMINMAX first!
28#endif
29
32#ifndef NOMINMAX
33#define NOMINMAX
34#endif
46namespace Carna
47{
48
49namespace base
50{
51
52namespace math
53{
54
63 template< typename T >
64 T clamp( T val, T my_min, T my_max )
65 {
66 return std::min( std::max( val, my_min ), my_max );
67 }
68
72 template< typename T >
73 T sq( T x )
74 {
75 return x * x;
76 }
77
81 inline float deg2rad( float deg )
82 {
83 return deg * 3.1415926f / 180.f;
84 }
85
89 inline float rad2deg( float rad )
90 {
91 return 180.f * rad / 3.1415926f;
92 }
93
97 template< typename T >
99 {
100 return static_cast< T >( 0 );
101 }
102
107 template< >
108 inline float epsilon< float >()
109 {
110 return 1e-4f;
111 }
112
117 template< >
118 inline double epsilon< double >()
119 {
120 return 1e-6;
121 }
122
127 template< typename T >
129 {
133 typedef T type;
134 };
135
140 template< typename VectorElementType, int rows, int cols >
141 struct element_type_of< Eigen::Matrix< VectorElementType, rows, cols > >
142 {
147
148 };
149
154 template< typename T >
155 T length2( const T& x )
156 {
157 return x * x;
158 }
159
164 template< typename VectorElementType, int dimension >
165 VectorElementType length2( const Eigen::Matrix< VectorElementType, dimension, 1 >& x )
166 {
167 return x.squaredNorm();
168 }
169
173 template< typename InputType >
174 bool isEqual( const InputType& x, const InputType& y )
175 {
177 const InputType difference = x - y;
180 return distance2 <= _epsilon;
181 }
182
187 template< >
188 inline bool isEqual( const bool& x, const bool& y )
189 {
190 return x == y;
191 }
192
193 typedef Eigen::Matrix< float, 4, 4, Eigen::ColMajor > Matrix4f;
194 typedef Eigen::Matrix< float, 3, 3, Eigen::ColMajor > Matrix3f;
195 typedef Eigen::Matrix< float, 4, 1 > Vector4f;
196 typedef Eigen::Matrix< float, 3, 1 > Vector3f;
197 typedef Eigen::Matrix< float, 2, 1 > Vector2f;
198 typedef Eigen::Matrix< signed int, 3, 1 > Vector3i;
199 typedef Eigen::Matrix< unsigned int, 3, 1 > Vector3ui;
200 typedef Eigen::Matrix< unsigned int, 2, 1 > Vector2ui;
201
206 {
207 Matrix4f result;
208 result.setIdentity();
209 return result;
210 }
211
216 {
217 Matrix3f result;
218 result.setIdentity();
219 return result;
220 }
221
225 template< typename MatrixType >
227 {
228 MatrixType result;
229 result.setZero();
230 return result;
231 }
232
242 inline Matrix4f basis4f( const Vector4f& x, const Vector4f& y, const Vector4f& z, const Vector4f& t = Vector4f( 0, 0, 0, 0 ) )
243 {
244 Matrix4f result;
245 result.col( 0 ) = x;
246 result.col( 1 ) = y;
247 result.col( 2 ) = z;
248 result.col( 3 ) = t;
249 for( unsigned int i = 0; i < 3; ++i )
250 {
251 result( 3, i ) = 0;
252 }
253 result( 3, 3 ) = 1;
254 return result;
255 }
256
259 inline Matrix4f basis4f( const Vector3f& x, const Vector3f& y, const Vector3f& z, const Vector3f& t = Vector3f( 0, 0, 0 ) )
260 {
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 );
266 }
267
271 inline Matrix4f translation4f( float x, float y, float z )
272 {
273 Matrix4f result;
274 result.setIdentity();
275 result( 0, 3 ) = x;
276 result( 1, 3 ) = y;
277 result( 2, 3 ) = z;
278 return result;
279 }
280
283 template< typename Vector >
284 Matrix4f translation4f( const Vector& v )
285 {
286 return translation4f( v.x(), v.y(), v.z() );
287 }
288
292 inline Matrix4f scaling4f( float x, float y, float z )
293 {
294 Matrix4f result;
295 result.setIdentity();
296 result( 0, 0 ) = x;
297 result( 1, 1 ) = y;
298 result( 2, 2 ) = z;
299 return result;
300 }
301
304 template< typename VectorElementType >
305 inline Matrix4f scaling4f( const Eigen::Matrix< VectorElementType, 3, 1 >& v )
306 {
307 return scaling4f( v.x(), v.y(), v.z() );
308 }
309
316
322 inline Matrix4f rotation4f( float x, float y, float z, float radians )
323 {
324 const float c = std::cos( radians );
325 const float s = std::sin( radians );
326
327 Matrix4f result;
328 result.setIdentity();
329
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;
333
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;
337
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;
341
342 return result;
343 }
344
347 template< typename Vector >
348 Matrix4f rotation4f( const Vector& v, float radians )
349 {
350 return rotation4f( v.x(), v.y(), v.z(), radians );
351 }
352
357 inline Matrix3f rotation3f( float x, float y, float z, float radians )
358 {
359 return rotation4f( x, y, z, radians ).block< 3, 3 >( 0, 0 );
360 }
361
367 inline Vector3f orthogonal3f( const Vector3f& in )
368 {
369 Vector3f out;
370 if( std::abs( in.x() - in.y() ) > 1e-4f )
371 {
372 out.x() = in.y();
373 out.y() = in.x();
374 out.z() = 0;
375
376 if( std::abs( out.x() ) > std::abs( out.y() ) )
377 {
378 out.x() = -out.x();
379 }
380 else
381 {
382 out.y() = -out.y();
383 }
384 }
385 else
386 if( std::abs( in.x() - in.z() ) > 1e-4f )
387 {
388 out.x() = in.z();
389 out.y() = 0;
390 out.z() = in.x();
391
392 if( std::abs( out.x() ) > std::abs( out.z() ) )
393 {
394 out.x() = -out.x();
395 }
396 else
397 {
398 out.z() = -out.z();
399 }
400 }
401 else
402 if( std::abs( in.y() - in.z() ) > 1e-4f )
403 {
404 out.x() = 0;
405 out.y() = in.z();
406 out.z() = in.x();
407
408 if( std::abs( out.y() ) > std::abs( out.z() ) )
409 {
410 out.y() = -out.y();
411 }
412 else
413 {
414 out.z() = -out.z();
415 }
416 }
417 else // all components are equal
418 {
419 out = Vector3f( -in.x(), in.y(), 0 );
420 }
421
425 CARNA_ASSERT( isEqual< float >( in.dot( out ), 0 ) );
426 return out;
427 }
428
433 template< typename VectorElementType, int rows, typename WType >
434 Eigen::Matrix< VectorElementType, 4, 1 > vector4( const Eigen::Matrix< VectorElementType, rows, 1 >& v, WType w )
435 {
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 ) );
438 }
439
444 template< typename VectorElementType, int rows >
445 Eigen::Matrix< VectorElementType, 3, 1 > vector3( const Eigen::Matrix< VectorElementType, rows, 1 >& v )
446 {
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() );
449 }
450
456 inline Matrix4f plane4f( const Vector3f& normal, float distance )
457 {
458 CARNA_ASSERT( isEqual< float >( normal.norm(), 1 ) );
460 const Vector3f bitangent( normal.cross( tangent ).normalized() );
462 return basis4f
463 ( vector4( bitangent, 0 )
464 , vector4( tangent, 0 )
465 , vector4( normal, 0 )
466 , vector4( translation, 1 ) );
467 }
468
472 {
473 CARNA_ASSERT( isEqual< float >( normal.norm(), 1 ) );
474 const float distance = normal.dot( support );
475 return plane4f( normal, distance );
476 }
477
482 inline float translationDistance2( const Matrix4f& m )
483 {
484 return m( 0, 3 ) * m( 0, 3 ) + m( 1, 3 ) * m( 1, 3 ) + m( 2, 3 ) * m( 2, 3 );
485 }
486
490 template< typename Matrix >
491 typename Matrix::Scalar maxAbsElement( const Matrix& m )
492 {
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 )
496 {
497 maxAbs = std::max( maxAbs, std::abs( m.data()[ i ] ) );
498 }
499 return maxAbs;
500 }
501
516 inline Matrix4f frustum4f( float left, float right, float bottom, float top, float zNear, float zFar )
517 {
518 Matrix4f result;
519 result.setZero();
520
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 );
526 result( 3, 2 ) = -1;
527 result( 2, 3 ) = -2 * zFar * zNear / ( zFar - zNear );
528
529 return result;
530 }
531
553
557 inline Matrix4f ortho4f( float left, float right, float bottom, float top, float zNear, float zFar )
558 {
559 Matrix4f result;
560 result.setZero();
561
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 );
568 result( 3, 3 ) = +1;
569
570 return result;
571 }
572
579 template< typename Sampler >
581 {
582 const float val_0yz = func( -1, 0, 0 );
583 const float val_1yz = func( +1, 0, 0 );
584 const float val_x0z = func( 0, -1, 0 );
585 const float val_x1z = func( 0, +1, 0 );
586 const float val_xy0 = func( 0, 0, -1 );
587 const float val_xy1 = func( 0, 0, +1 );
588
590 }
591
596 template< typename ScalarType >
597 unsigned int round_ui( ScalarType x )
598 {
599 CARNA_ASSERT( !std::numeric_limits< ScalarType >::is_signed || x >= 0 );
600 return static_cast< unsigned int >( x + static_cast< ScalarType >( 0.5 ) );
601 }
602
608 template< typename MatrixElementType, int cols, int rows >
609 Eigen::Matrix< unsigned int, cols, rows > round_ui( const Eigen::Matrix< MatrixElementType, cols, rows >& m )
610 {
611 Eigen::Matrix< unsigned int, cols, rows > result;
612 for( int i = 0; i < cols; ++i )
613 for( int j = 0; j < rows; ++j )
614 {
615 result( i, j ) = round_ui( m( i, j ) );
616 }
617 return result;
618 }
619
624 template< typename ScalarType >
626 {
627 CARNA_ASSERT( s == +1 || s == -1 );
628 static_assert( std::is_integral< ScalarType >::value, "Only integral data types allowed." );
629 return x + s * ( x % 2 );
630 }
631
639 template< typename MatrixElementType, int cols, int rows >
640 Eigen::Matrix< MatrixElementType, cols, rows > makeEven( const Eigen::Matrix< MatrixElementType, cols, rows >& m, int s )
641 {
642 Eigen::Matrix< unsigned int, cols, rows > result;
643 for( int i = 0; i < cols; ++i )
644 for( int j = 0; j < rows; ++j )
645 {
646 result( i, j ) = makeEven( m( i, j ), s );
647 }
648 return result;
649 }
650
654 template< typename T >
656 {
659
664 {
665 }
666
670 Statistics( std::size_t size, const std::function< T( std::size_t ) > values )
671 {
672 if( size == 0 )
673 {
674 mean = variance = 0;
675 }
676 else
677 {
678 /* Compute mean.
679 */
680 T sum = 0;
681 for( std::size_t idx = 0; idx < size; ++idx )
682 {
683 sum += values( idx );
684 }
685 mean = sum / size;
686
687 /* Compute variance.
688 */
689 sum = 0;
690 for( std::size_t idx = 0; idx < size; ++idx )
691 {
692 sum += sq( mean - values( idx ) );
693 }
694 variance = sum / ( size - 1 );
695 }
696 }
697
702 {
703 mean = other.mean;
704 variance = other.variance;
705 return *this;
706 }
707
712 {
713 return std::sqrt( variance );
714 }
715 };
716
720 template< typename ResultType, typename SupportType >
721 ResultType mix( const SupportType& a, const SupportType& b, float t )
722 {
723 return a * ( 1 - t ) + b * t;
724 }
725
726
727
733#define CARNA_FOR_VECTOR3UI_EX( vecName, vecLimit, vecStart ) \
734 Carna::base::math::Vector3ui vecName; \
735 for( vecName.z() = vecStart.x(); vecName.z() < vecLimit.z(); ++vecName.z() ) \
736 for( vecName.y() = vecStart.y(); vecName.y() < vecLimit.y(); ++vecName.y() ) \
737 for( vecName.x() = vecStart.z(); vecName.x() < vecLimit.x(); ++vecName.x() )
738
739
740
747#define CARNA_FOR_VECTOR3UI( vecName, vecLimit ) \
748 CARNA_FOR_VECTOR3UI_EX( vecName, vecLimit, Carna::base::math::Vector3ui( 0, 0, 0 ) )
749
750
751
752} // namespace Carna :: base :: math
753
754} // namespace Carna :: base
755
756} // namespace Carna
757
758
759
760#endif // MATH_H_6014714286
Defines Carna::base::CarnaException, Carna::base::AssertionFailure.
#define CARNA_ASSERT(expression)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
Represents an association.
Definition Association.h:45
Maintains an OpenGL texture sampler object. This class realizes the RAII-idiom.
Definition Sampler.h:45
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 ...
Definition math.h:445
Vector3f orthogonal3f(const Vector3f &in)
Constructs vector that is orthogonal to in. The result is undefined if the squared length of in equa...
Definition math.h:367
Eigen::Matrix< float, 2, 1 > Vector2f
Defines vector.
Definition math.h:197
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.
Definition math.h:242
double epsilon< double >()
Defines the maximum difference of two double-precision floating point objects treated as equal.
Definition math.h:118
Eigen::Matrix< float, 4, 1 > Vector4f
Defines vector.
Definition math.h:195
T epsilon()
Defines the maximum difference of two objects treated as equal.
Definition math.h:98
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...
Definition math.h:322
Matrix3f identity3f()
Returns identity matrix.
Definition math.h:215
float epsilon< float >()
Defines the maximum difference of two single-precision floating point objects treated as equal.
Definition math.h:108
Eigen::Matrix< float, 3, 3, Eigen::ColMajor > Matrix3f
Defines matrix.
Definition math.h:194
float rad2deg(float rad)
Converts radians to degrees.
Definition math.h:89
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Definition math.h:196
Matrix3f rotation3f(float x, float y, float z, float radians)
Creates rotation matrix for homogeneous coordinates, but returns only the upper left sub-matrix.
Definition math.h:357
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.
Definition math.h:557
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.
Definition math.h:516
Matrix4f plane4f(const Vector3f &normal, float distance)
Creates matrix that transforms from the tangent space of a plane with particular normal vector and or...
Definition math.h:456
float translationDistance2(const Matrix4f &m)
Returns the squared length of the translation component of the homogeneous coordinates transformation...
Definition math.h:482
base::math::Vector3f computeFastGradient3f(Sampler func)
Computes fast approximation of the gradient at the origin of the scalar field func.
Definition math.h:580
T sq(T x)
Computes and returns .
Definition math.h:73
T clamp(T val, T my_min, T my_max)
Returns val my_min my_max .
Definition math.h:64
MatrixType zeros()
Returns matrix with zeros in all components.
Definition math.h:226
bool isEqual(const InputType &x, const InputType &y)
Tells whether two objects are equal respectively to epsilon.
Definition math.h:174
Eigen::Matrix< unsigned int, 3, 1 > Vector3ui
Defines vector.
Definition math.h:199
Eigen::Matrix< float, 4, 4, Eigen::ColMajor > Matrix4f
Defines matrix.
Definition math.h:193
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,...
Definition math.h:434
Eigen::Matrix< signed int, 3, 1 > Vector3i
Defines vector.
Definition math.h:198
ScalarType makeEven(ScalarType x, int s)
Returns if is even and if is odd, where . The data type of must be integral.
Definition math.h:625
T length2(const T &x)
Retrieves the squared length of vector and scalar types. General case assumes scalar type.
Definition math.h:155
Matrix::Scalar maxAbsElement(const Matrix &m)
Returns where $m$ is m.
Definition math.h:491
Matrix4f identity4f()
Returns identity matrix.
Definition math.h:205
ResultType mix(const SupportType &a, const SupportType &b, float t)
Interpolates between and by t linearly.
Definition math.h:721
float deg2rad(float deg)
Converts degrees to radians.
Definition math.h:81
unsigned int round_ui(ScalarType x)
Rounds x to the closest . Either the data type of must be unsigned or .
Definition math.h:597
Matrix4f scaling4f(float x, float y, float z)
Creates scaling matrix for homogeneous coordinates.
Definition math.h:292
Eigen::Matrix< unsigned int, 2, 1 > Vector2ui
Defines vector.
Definition math.h:200
Matrix4f translation4f(float x, float y, float z)
Returns matrix that translates homogeneous coordinates.
Definition math.h:271
Holds mean and variance of an characteristic.
Definition math.h:656
Statistics< T > & operator=(const Statistics< T > &other)
Copies from other.
Definition math.h:701
Statistics(std::size_t size, const std::function< T(std::size_t) > values)
Computes statistics from size samples queried from values.
Definition math.h:670
T standardDeviation() const
Computes the standard deviation.
Definition math.h:711
T mean
Holds the mean.
Definition math.h:657
Statistics(T mean, T variance)
Initializes with mean and variance.
Definition math.h:663
T variance
Holds the variance.
Definition math.h:658
VectorElementType type
The vector element type is known implicitly for each vector type.
Definition math.h:146
Retrieves element types of vectors and scalars. General case assumes a scalar type.
Definition math.h:129
T type
Since T is assumed to be scalar type, it's element type is also T.
Definition math.h:133