Janus 2.0.0
High-performance C++20 dual-mode numerical framework
Loading...
Searching...
No Matches
Rotations.hpp
Go to the documentation of this file.
1#pragma once
7
12#include "janus/math/Linalg.hpp"
13#include "janus/math/Trig.hpp"
14
15namespace janus {
16
17// --- 2D Rotation Matrix ---
24template <typename T> Mat2<T> rotation_matrix_2d(const T &theta) {
25 T c = janus::cos(theta);
26 T s = janus::sin(theta);
27
28 Mat2<T> R;
29 R(0, 0) = c;
30 R(0, 1) = -s;
31 R(1, 0) = s;
32 R(1, 1) = c;
33 return R;
34}
35
36// --- 3D Rotation Matrix (Principal Axes) ---
44template <typename T> Mat3<T> rotation_matrix_3d(const T &theta, int axis) {
45 T c = janus::cos(theta);
46 T s = janus::sin(theta);
47 T one = static_cast<T>(1.0);
48 T zero = static_cast<T>(0.0);
49
51
52 switch (axis) {
53 case 0: // X-axis
54 R(1, 1) = c;
55 R(1, 2) = -s;
56 R(2, 1) = s;
57 R(2, 2) = c;
58 break;
59 case 1: // Y-axis
60 R(0, 0) = c;
61 R(0, 2) = s;
62 R(2, 0) = -s;
63 R(2, 2) = c;
64 break;
65 case 2: // Z-axis
66 R(0, 0) = c;
67 R(0, 1) = -s;
68 R(1, 0) = s;
69 R(1, 1) = c;
70 break;
71 default:
72 throw InvalidArgument("rotation_matrix_3d: axis must be 0 (X), 1 (Y), or 2 (Z)");
73 }
74 return R;
75}
76
77// --- Euler Angles ---
86template <typename T>
87Mat3<T> rotation_matrix_from_euler_angles(const T &roll, const T &pitch, const T &yaw) {
88 T sa = janus::sin(yaw);
89 T ca = janus::cos(yaw);
90 T sb = janus::sin(pitch);
91 T cb = janus::cos(pitch);
92 T sc = janus::sin(roll);
93 T cc = janus::cos(roll);
94
95 Mat3<T> R;
96 // Row 0
97 R(0, 0) = ca * cb;
98 R(0, 1) = ca * sb * sc - sa * cc;
99 R(0, 2) = ca * sb * cc + sa * sc;
100 // Row 1
101 R(1, 0) = sa * cb;
102 R(1, 1) = sa * sb * sc + ca * cc;
103 R(1, 2) = sa * sb * cc - ca * sc;
104 // Row 2
105 R(2, 0) = -sb;
106 R(2, 1) = cb * sc;
107 R(2, 2) = cb * cc;
108
109 return R;
110}
111
112// --- Validation ---
121template <typename Derived>
122auto is_valid_rotation_matrix(const Eigen::MatrixBase<Derived> &a, double tol = 1e-9) {
123 using Scalar = typename Derived::Scalar;
124
125 // Explicit determinant for small matrices to avoid CasADi Determinant node issues in evaluation
126 Scalar det_a;
127 if (a.rows() == 3 && a.cols() == 3) {
128 det_a = a(0, 0) * (a(1, 1) * a(2, 2) - a(1, 2) * a(2, 1)) -
129 a(0, 1) * (a(1, 0) * a(2, 2) - a(1, 2) * a(2, 0)) +
130 a(0, 2) * (a(1, 0) * a(2, 1) - a(1, 1) * a(2, 0));
131 } else if (a.rows() == 2 && a.cols() == 2) {
132 det_a = a(0, 0) * a(1, 1) - a(0, 1) * a(1, 0);
133 } else {
134 det_a = janus::det(a);
135 }
136
137 // Identity check: a.T * a approx I
138 auto eye_approx = a.transpose() * a;
139 auto eye = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>::Identity(a.rows(), a.cols());
140
141 if constexpr (std::is_floating_point_v<Scalar>) {
142 bool det_ok = std::abs(det_a - 1.0) < tol;
143 // Frobenius norm of error
144 bool ortho_ok = (eye_approx - eye).norm() < tol;
145 return det_ok && ortho_ok;
146 } else {
147 // Symbolic
148 auto diff_det = det_a - 1.0;
149 auto diff_eye = eye_approx - eye;
150
151 // Use Frobenius norm for matrix error
152 auto err_ortho = janus::norm(diff_eye, NormType::Frobenius);
153
154 // Conditions
155 auto det_cond = (janus::abs(diff_det) < tol);
156 auto ortho_cond = (err_ortho < tol);
157
158 return det_cond && ortho_cond;
159 }
160}
161
162} // namespace janus
Scalar and element-wise arithmetic functions (abs, sqrt, pow, exp, log, etc.).
C++20 concepts constraining valid Janus scalar types.
Custom exception hierarchy for Janus framework.
Core type aliases for numeric and symbolic Eigen/CasADi interop.
Linear algebra operations (solve, inverse, determinant, eigendecomposition, norms).
Trigonometric and inverse trigonometric functions.
Input validation failed (e.g., mismatched sizes, invalid parameters).
Definition JanusError.hpp:31
Definition Diagnostics.hpp:19
Mat2< T > rotation_matrix_2d(const T &theta)
Creates a 2x2 rotation matrix.
Definition Rotations.hpp:24
auto is_valid_rotation_matrix(const Eigen::MatrixBase< Derived > &a, double tol=1e-9)
Checks if matrix is a valid rotation matrix Checks determinant approx 1 and orthogonality (A^T * A ap...
Definition Rotations.hpp:122
@ Frobenius
Frobenius norm.
Definition Linalg.hpp:597
T abs(const T &x)
Computes the absolute value of a scalar.
Definition Arithmetic.hpp:21
auto det(const Eigen::MatrixBase< Derived > &A)
Computes matrix determinant.
Definition Linalg.hpp:549
Mat3< T > rotation_matrix_from_euler_angles(const T &roll, const T &pitch, const T &yaw)
Creates a 3x3 rotation matrix from Euler angles (Yaw-Pitch-Roll sequence).
Definition Rotations.hpp:87
Eigen::Matrix< Scalar, 2, 2 > Mat2
Definition JanusTypes.hpp:60
T cos(const T &x)
Computes cosine of x.
Definition Trig.hpp:46
Eigen::Matrix< Scalar, 3, 3 > Mat3
Definition JanusTypes.hpp:61
auto norm(const Eigen::MatrixBase< Derived > &x, NormType type=NormType::L2)
Computes vector/matrix norm.
Definition Linalg.hpp:607
T sin(const T &x)
Computes sine of x.
Definition Trig.hpp:21
Mat3< T > rotation_matrix_3d(const T &theta, int axis)
Creates a 3x3 rotation matrix about a principal axis.
Definition Rotations.hpp:44