6 #ifndef THEORETICA_TRANSFORM_H
7 #define THEORETICA_TRANSFORM_H
10 #include "../core/error.h"
20 template<
typename Matrix>
21 inline Matrix
identity(
unsigned int rows = 0,
unsigned int cols = 0) {
38 template<
typename Vector,
typename Matrix>
39 inline Matrix&
diagonal(Matrix& res,
const Vector& v) {
41 if(v.size() != res.cols()) {
42 TH_MATH_ERROR(
"algebra::mat_diagonal", v.size(), INVALID_ARGUMENT);
47 if(v.size() != res.rows()) {
48 TH_MATH_ERROR(
"algebra::mat_diagonal", v.size(), INVALID_ARGUMENT);
53 for (
unsigned int i = 0; i < res.rows(); ++i)
54 for (
unsigned int j = 0; j < res.cols(); ++j)
55 res(i, j) = (i == j) ? v[i] : 0;
69 template<
typename Matrix,
typename Vector>
71 const Vector& v,
unsigned int rows = 0,
unsigned int cols = 0) {
87 template<
typename Matrix,
typename Vector>
89 const Vector& v,
unsigned int rows = 0,
unsigned int cols = 0) {
95 if(v.size() != (m.rows() - 1)) {
96 TH_MATH_ERROR(
"algebra::translation", v.size(), INVALID_ARGUMENT);
107 for (
unsigned int i = 0; i < m.rows() - 1; ++i)
108 m(i, m.cols() - 1) = v[i];
117 template<
typename Matrix>
119 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
123 m.resize(rows, cols);
126 TH_MATH_ERROR(
"algebra::rotation_2d", m.rows(), INVALID_ARGUMENT);
132 TH_MATH_ERROR(
"algebra::rotation_2d", m.cols(), INVALID_ARGUMENT);
140 if(m.rows() > 2 || m.cols() > 2)
158 template<
typename Matrix,
typename Vector>
160 real theta,
const Vector& axis,
unsigned int rows = 0,
unsigned int cols = 0) {
164 m.resize(rows, cols);
166 if(axis.size() < 3) {
167 TH_MATH_ERROR(
"algebra::rotation_3d", axis.size(), INVALID_ARGUMENT);
173 TH_MATH_ERROR(
"algebra::rotation_3d", m.rows(), INVALID_ARGUMENT);
179 TH_MATH_ERROR(
"algebra::rotation_3d", m.cols(), INVALID_ARGUMENT);
184 if(m.rows() > 3 || m.cols() > 3)
194 const real cm1 = (1 - c);
196 m(0, 0) = c + Rx * Rx * cm1;
197 m(0, 1) = Rx * Ry * cm1 - Rz * s;
198 m(0, 2) = Rx * Rz * cm1 - Ry * s;
200 m(1, 0) = Ry * Rx * cm1 + Rz * s;
201 m(1, 1) = c + Ry * Ry * cm1;
202 m(1, 2) = Ry * Rz * cm1 - Rx * s;
204 m(2, 0) = Rz * Rx * cm1 - Ry * s;
205 m(2, 1) = Rz * Ry * cm1 + Rx * s;
206 m(2, 2) = c + Rz * Rz * cm1;
217 template<
typename Matrix>
219 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
223 m.resize(rows, cols);
226 TH_MATH_ERROR(
"algebra::rotation_3d_xaxis", m.rows(), INVALID_ARGUMENT);
232 TH_MATH_ERROR(
"algebra::rotation_3d_xaxis", m.cols(), INVALID_ARGUMENT);
237 if(m.rows() > 3 || m.cols() > 3)
259 template<
typename Matrix>
261 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
265 m.resize(rows, cols);
268 TH_MATH_ERROR(
"algebra::rotation_3d_yaxis", m.rows(), INVALID_ARGUMENT);
274 TH_MATH_ERROR(
"algebra::rotation_3d_yaxis", m.cols(), INVALID_ARGUMENT);
279 if(m.rows() > 3 || m.cols() > 3)
302 template<
typename Matrix>
304 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
308 m.resize(rows, cols);
311 TH_MATH_ERROR(
"algebra::rotation_3d_zaxis", m.rows(), INVALID_ARGUMENT);
317 TH_MATH_ERROR(
"algebra::rotation_3d_zaxis", m.cols(), INVALID_ARGUMENT);
322 if(m.rows() > 3 || m.cols() > 3)
341 template<
typename Matrix>
345 unsigned int rows = 0,
unsigned int cols = 0) {
349 m.resize(rows, cols);
352 TH_MATH_ERROR(
"algebra::perspective", m.rows(), INVALID_ARGUMENT);
358 TH_MATH_ERROR(
"algebra::perspective", m.cols(), INVALID_ARGUMENT);
365 m(0, 0) = 2 * near / (right - left);
366 m(2, 0) = (right + left) / (right - left);
367 m(1, 1) = 2 * near / (top - bottom);
368 m(2, 1) = (top + bottom) / (top - bottom);
369 m(2, 2) = -(far + near) / (far - near);
370 m(3, 2) = -(2 * far * near) / (far - near);
380 template<
typename Matrix>
383 unsigned int rows = 0,
unsigned int cols = 0) {
387 m.resize(rows, cols);
390 TH_MATH_ERROR(
"algebra::perspective_fov", m.rows(), INVALID_ARGUMENT);
396 TH_MATH_ERROR(
"algebra::perspective_fov", m.cols(), INVALID_ARGUMENT);
402 const real width = height * aspect;
404 return perspective<Matrix>(-width, width, -height, height, near, far);
409 template<
typename Matrix>
413 unsigned int rows = 0,
unsigned int cols = 0) {
417 m.resize(rows, cols);
433 m(0, 0) = 2 / (right - left);
434 m(3, 0) = -(right + left) / (right - left);
435 m(1, 1) = 2 / (top - bottom);
436 m(3, 1) = -(top + bottom) / (top - bottom);
437 m(2, 2) = -2 / (far - near);
438 m(3, 2) = -(far + near) / (far - near);
447 typename Matrix,
typename Vector1,
448 typename Vector2,
typename Vector3>
449 inline Matrix
look_at(Vector1 camera, Vector2 target, Vector3 up) {
453 Vector1 x_axis, y_axis, z_axis;
501 template<
typename Matrix>
502 inline Matrix
symplectic(
unsigned int rows = 0,
unsigned int cols = 0) {
506 m.resize(rows, cols);
508 if(rows != cols || (rows % 2 != 0)) {
509 TH_MATH_ERROR(
"algebra::symplectic", rows, INVALID_ARGUMENT);
514 const unsigned int half = m.rows() / 2;
517 for (
unsigned int i = 0; i < half; ++i) {
534 template<
typename Matrix>
535 inline Matrix
hilbert(
unsigned int rows = 0) {
539 H.resize(rows, rows);
541 for (
unsigned int i = 0; i < H.rows(); ++i)
542 for (
unsigned int j = 0; j < H.cols(); ++j)
543 H(i, j) = 1.0 / (i + j + 1);
554 template<
typename Vector1,
typename Vector2>
556 const Vector1& p,
const Vector2& c = Vector2(0),
real r = 1) {
559 return c + q *
square(r / q.norm());
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
Matrix & mat_zeroes(Matrix &m)
Overwrite a matrix with all zeroes.
Definition: algebra.h:93
Matrix symplectic(unsigned int rows=0, unsigned int cols=0)
Generate a NxN symplectic matrix where N is even.
Definition: transform.h:502
Vector1 cross(const Vector1 &v1, const Vector2 &v2)
Compute the cross product between two tridimensional vectors.
Definition: algebra.h:373
Matrix & make_identity(Matrix &m)
Overwrite a matrix with the identity matrix.
Definition: algebra.h:77
Vector & make_normalized(Vector &v)
Normalize a given vector overwriting it.
Definition: algebra.h:327
Matrix look_at(Vector1 camera, Vector2 target, Vector3 up)
Return a transformation matrix that points the field of view towards a given point from the <camera> ...
Definition: transform.h:449
Matrix rotation_2d(real theta, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 2D rotation.
Definition: transform.h:118
Vector1 sphere_inversion(const Vector1 &p, const Vector2 &c=Vector2(0), real r=1)
Sphere inversion of a point with respect to a sphere of radius r centered at a point c.
Definition: transform.h:555
Matrix hilbert(unsigned int rows=0)
Construct the Hilbert matrix of arbitrary dimension.
Definition: transform.h:535
auto dot(const Vector1 &v, const Vector2 &w)
Computes the dot product between two vectors, using the Hermitian form if needed.
Definition: algebra.h:351
Matrix rotation_3d_xaxis(real theta, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 3D rotation around the x axis.
Definition: transform.h:218
Matrix & mat_error(Matrix &m)
Overwrite the given matrix with the error matrix with NaN values on the diagonal and zeroes everywher...
Definition: algebra.h:44
Matrix & diagonal(Matrix &res, const Vector &v)
Construct a matrix with the given vector as diagonal and zeroes everywhere else, overwriting the give...
Definition: transform.h:39
Vector & vec_scalmul(Field a, Vector &v)
Multiply a vector by a scalar of any compatible type.
Definition: algebra.h:634
Matrix perspective_fov(real fov, real aspect, real near, real far, unsigned int rows=0, unsigned int cols=0)
Returns a perspective projection matrix, using the Field of View as parameter.
Definition: transform.h:381
Matrix rotation_3d_yaxis(real theta, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 3D rotation around the y axis.
Definition: transform.h:260
Matrix rotation_3d(real theta, const Vector &axis, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 3D rotation around a given axis.
Definition: transform.h:159
Vector1 & vec_copy(Vector1 &dest, const Vector2 &src)
Copy a vector by overwriting another.
Definition: algebra.h:143
Vector2 & vec_diff(Vector1 &v1, const Vector2 &v2)
Subtract two vectors and store the result in the first vector.
Definition: algebra.h:1183
Matrix ortho(real left, real right, real bottom, real top, real near, real far, unsigned int rows=0, unsigned int cols=0)
Returns an orthogonal projection matrix.
Definition: transform.h:410
Matrix identity(unsigned int rows=0, unsigned int cols=0)
Returns the identity matrix.
Definition: transform.h:21
Matrix rotation_3d_zaxis(real theta, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 3D rotation around the z axis.
Definition: transform.h:303
Matrix perspective(real left, real right, real bottom, real top, real near, real far, unsigned int rows=0, unsigned int cols=0)
Returns a perspective projection matrix.
Definition: transform.h:342
Matrix translation(const Vector &v, unsigned int rows=0, unsigned int cols=0)
Returns a translation matrix, that is, an NxN matrix which describes a translation in N-1 dimensions.
Definition: transform.h:88
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
double real
A real number, defined as a floating point type.
Definition: constants.h:188
TH_CONSTEXPR real radians(real degrees)
Convert degrees to radians.
Definition: real_analysis.h:1253
dual2 cos(dual2 x)
Compute the cosine of a second order dual number.
Definition: dual2_functions.h:82
dual2 tan(dual2 x)
Compute the tangent of a second order dual number.
Definition: dual2_functions.h:94
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition: dual2_functions.h:70
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition: dual2_functions.h:23