6#ifndef THEORETICA_TRANSFORM_H
7#define THEORETICA_TRANSFORM_H
10#include "../core/error.h"
21 template<
typename Matrix>
22 inline Matrix
identity(
unsigned int rows = 0,
unsigned int cols = 0) {
39 template<
typename Vector,
typename Matrix>
40 inline Matrix&
diagonal(Matrix& res,
const Vector& v) {
42 if(v.size() != res.cols()) {
43 TH_MATH_ERROR(
"algebra::mat_diagonal", v.size(), INVALID_ARGUMENT);
48 if(v.size() != res.rows()) {
49 TH_MATH_ERROR(
"algebra::mat_diagonal", v.size(), INVALID_ARGUMENT);
54 for (
unsigned int i = 0; i < res.rows(); ++i)
55 for (
unsigned int j = 0; j < res.cols(); ++j)
56 res(i, j) = (i == j) ? v[i] : 0;
70 template<
typename Matrix,
typename Vector>
72 const Vector& v,
unsigned int rows = 0,
unsigned int cols = 0) {
88 template<
typename Matrix,
typename Vector>
90 const Vector& v,
unsigned int rows = 0,
unsigned int cols = 0) {
96 if(v.size() != (m.rows() - 1)) {
97 TH_MATH_ERROR(
"algebra::translation", v.size(), INVALID_ARGUMENT);
108 for (
unsigned int i = 0; i < m.rows() - 1; ++i)
109 m(i, m.cols() - 1) = v[i];
118 template<
typename Matrix>
120 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
124 m.resize(rows, cols);
127 TH_MATH_ERROR(
"algebra::rotation_2d", m.rows(), INVALID_ARGUMENT);
133 TH_MATH_ERROR(
"algebra::rotation_2d", m.cols(), INVALID_ARGUMENT);
141 if(m.rows() > 2 || m.cols() > 2)
159 template<
typename Matrix,
typename Vector>
161 real theta,
const Vector& axis,
unsigned int rows = 0,
unsigned int cols = 0) {
165 m.resize(rows, cols);
167 if(axis.size() < 3) {
168 TH_MATH_ERROR(
"algebra::rotation_3d", axis.size(), INVALID_ARGUMENT);
174 TH_MATH_ERROR(
"algebra::rotation_3d", m.rows(), INVALID_ARGUMENT);
180 TH_MATH_ERROR(
"algebra::rotation_3d", m.cols(), INVALID_ARGUMENT);
185 if(m.rows() > 3 || m.cols() > 3)
195 const real cm1 = (1 - c);
197 m(0, 0) = c + Rx * Rx * cm1;
198 m(0, 1) = Rx * Ry * cm1 - Rz * s;
199 m(0, 2) = Rx * Rz * cm1 + Ry * s;
201 m(1, 0) = Ry * Rx * cm1 + Rz * s;
202 m(1, 1) = c + Ry * Ry * cm1;
203 m(1, 2) = Ry * Rz * cm1 - Rx * s;
205 m(2, 0) = Rz * Rx * cm1 - Ry * s;
206 m(2, 1) = Rz * Ry * cm1 + Rx * s;
207 m(2, 2) = c + Rz * Rz * cm1;
218 template<
typename Matrix>
220 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
224 m.resize(rows, cols);
227 TH_MATH_ERROR(
"algebra::rotation_3d_xaxis", m.rows(), INVALID_ARGUMENT);
233 TH_MATH_ERROR(
"algebra::rotation_3d_xaxis", m.cols(), INVALID_ARGUMENT);
238 if(m.rows() > 3 || m.cols() > 3)
260 template<
typename Matrix>
262 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
266 m.resize(rows, cols);
269 TH_MATH_ERROR(
"algebra::rotation_3d_yaxis", m.rows(), INVALID_ARGUMENT);
275 TH_MATH_ERROR(
"algebra::rotation_3d_yaxis", m.cols(), INVALID_ARGUMENT);
280 if(m.rows() > 3 || m.cols() > 3)
303 template<
typename Matrix>
305 real theta,
unsigned int rows = 0,
unsigned int cols = 0) {
309 m.resize(rows, cols);
312 TH_MATH_ERROR(
"algebra::rotation_3d_zaxis", m.rows(), INVALID_ARGUMENT);
318 TH_MATH_ERROR(
"algebra::rotation_3d_zaxis", m.cols(), INVALID_ARGUMENT);
323 if(m.rows() > 3 || m.cols() > 3)
357 template<
typename Matrix>
361 unsigned int rows = 0,
unsigned int cols = 0) {
365 m.resize(rows, cols);
368 TH_MATH_ERROR(
"algebra::perspective", m.rows(), INVALID_ARGUMENT);
374 TH_MATH_ERROR(
"algebra::perspective", m.cols(), INVALID_ARGUMENT);
381 m(0, 0) = 2 * near / (right - left);
382 m(2, 0) = (right + left) / (right - left);
383 m(1, 1) = 2 * near / (top - bottom);
384 m(2, 1) = (top + bottom) / (top - bottom);
385 m(2, 2) = -(far + near) / (far - near);
386 m(3, 2) = -(2 * far * near) / (far - near);
396 template<
typename Matrix>
399 unsigned int rows = 0,
unsigned int cols = 0) {
403 m.resize(rows, cols);
406 TH_MATH_ERROR(
"algebra::perspective_fov", m.rows(), INVALID_ARGUMENT);
412 TH_MATH_ERROR(
"algebra::perspective_fov", m.cols(), INVALID_ARGUMENT);
418 const real width = height * aspect;
420 return perspective<Matrix>(-width, width, -height, height, near, far);
425 template<
typename Matrix>
429 unsigned int rows = 0,
unsigned int cols = 0) {
433 m.resize(rows, cols);
449 m(0, 0) = 2 / (right - left);
450 m(3, 0) = -(right + left) / (right - left);
451 m(1, 1) = 2 / (top - bottom);
452 m(3, 1) = -(top + bottom) / (top - bottom);
453 m(2, 2) = -2 / (far - near);
454 m(3, 2) = -(far + near) / (far - near);
463 typename Matrix,
typename Vector1,
464 typename Vector2,
typename Vector3>
465 inline Matrix
look_at(Vector1 camera, Vector2 target, Vector3 up) {
469 Vector1 x_axis, y_axis, z_axis;
517 template<
typename Matrix>
518 inline Matrix
symplectic(
unsigned int rows = 0,
unsigned int cols = 0) {
522 m.resize(rows, cols);
524 if(rows != cols || (rows % 2 != 0)) {
525 TH_MATH_ERROR(
"algebra::symplectic", rows, INVALID_ARGUMENT);
530 const unsigned int half = m.rows() / 2;
533 for (
unsigned int i = 0; i < half; ++i) {
550 template<
typename Matrix>
551 inline Matrix
hilbert(
unsigned int rows = 0) {
555 H.resize(rows, rows);
557 for (
unsigned int i = 0; i < H.rows(); ++i)
558 for (
unsigned int j = 0; j < H.cols(); ++j)
559 H(i, j) = 1.0 / (i + j + 1);
570 template<
typename Vector1,
typename Vector2>
572 const Vector1& p,
const Vector2& c = Vector2(0),
real r = 1) {
575 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:225
Matrix symplectic(unsigned int rows=0, unsigned int cols=0)
Generate a NxN symplectic matrix where N is even.
Definition transform.h:518
Vector1 cross(const Vector1 &v1, const Vector2 &v2)
Compute the cross product between two tridimensional vectors.
Definition algebra.h:373
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:465
Matrix & make_identity(Matrix &m)
Overwrite a matrix with the identity matrix.
Definition algebra.h:77
Matrix rotation_2d(real theta, unsigned int rows=0, unsigned int cols=0)
Returns a matrix representing a 2D rotation.
Definition transform.h:119
Vector & make_normalized(Vector &v)
Normalize a given vector overwriting it.
Definition algebra.h:327
Vector1 & vec_copy(Vector1 &dest, const Vector2 &src)
Copy a vector by overwriting another.
Definition algebra.h:143
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:571
Matrix hilbert(unsigned int rows=0)
Construct the Hilbert matrix of arbitrary dimension.
Definition transform.h:551
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
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:219
Matrix & mat_zeroes(Matrix &m)
Overwrite a matrix with all zeroes.
Definition algebra.h:93
Vector2 & vec_diff(Vector1 &v1, const Vector2 &v2)
Subtract two vectors and store the result in the first vector.
Definition algebra.h:1183
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:397
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:261
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:160
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:40
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:426
Matrix identity(unsigned int rows=0, unsigned int cols=0)
Returns the identity matrix.
Definition transform.h:22
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:304
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 with adjustable view volume boundaries.
Definition transform.h:358
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:89
Vector & vec_scalmul(Field a, Vector &v)
Multiply a vector by a scalar of any compatible type.
Definition algebra.h:634
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:198
TH_CONSTEXPR real radians(real degrees)
Convert degrees to radians.
Definition real_analysis.h:1252
dual2 cos(dual2 x)
Compute the cosine of a second order dual number.
Definition dual2_functions.h:86
dual2 tan(dual2 x)
Compute the tangent of a second order dual number.
Definition dual2_functions.h:100
dual2 sin(dual2 x)
Compute the sine of a second order dual number.
Definition dual2_functions.h:72
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition dual2_functions.h:23