pairinteraction
A Rydberg Interaction Calculator
euler.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2024 Pairinteraction Developers
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#pragma once
5
8
9#include <Eigen/Dense>
10#include <array>
11#include <type_traits>
12
14/**
15 * @function get_rotation_matrix
16 *
17 * @brief Build a matrix that rotates the coordinate system to the new z-axis and y-axis.
18 *
19 * @tparam Real The type of a real number.
20 *
21 * @param to_z_axis The new z-axis.
22 *
23 * @param to_y_axis The new y-axis.
24 *
25 * @return The passive rotation matrix.
26 */
27
28template <typename Real>
29inline Eigen::Matrix3<Real> get_rotation_matrix(std::array<Real, 3> to_z_axis,
30 std::array<Real, 3> to_y_axis) {
31 static_assert(std::is_floating_point_v<Real>);
32
33 auto to_z_axis_mapped = Eigen::Map<Eigen::Vector3<Real>>(to_z_axis.data()).normalized();
34 auto to_y_axis_mapped = Eigen::Map<Eigen::Vector3<Real>>(to_y_axis.data()).normalized();
35
36 auto scale = to_z_axis_mapped.norm() * to_y_axis_mapped.norm();
37 auto numerical_precision = 100 * scale * std::numeric_limits<Real>::epsilon();
38
39 if (std::abs(to_z_axis_mapped.dot(to_y_axis_mapped)) > numerical_precision) {
40 throw std::runtime_error("The z-axis and the y-axis are not orhogonal.");
41 }
42
44 rotator << to_y_axis_mapped.cross(to_z_axis_mapped), to_y_axis_mapped, to_z_axis_mapped;
45
46 return rotator;
47}
48
49/**
50 * @function get_euler_angles
51 *
52 * @brief Extract the Euler angles alpha, beta, gamma
53 *
54 * @tparam Real The type of a real number.
55 *
56 * @param to_z_axis The new z-axis.
57 *
58 * @param to_y_axis The new y-axis.
59 *
60 * @return The Euler angles.
61 */
62
63template <typename Real>
64inline std::array<Real, 3> get_euler_angles(std::array<Real, 3> to_z_axis,
65 std::array<Real, 3> to_y_axis) {
66 static_assert(std::is_floating_point_v<Real>);
67
68 auto rotator = get_rotation_matrix(to_z_axis, to_y_axis);
69 std::array<Real, 3> euler_zyz{};
70 Eigen::Map<Eigen::Vector3<Real>>(euler_zyz.data()) = rotator.eulerAngles(2, 1, 2);
71 return euler_zyz;
72}
73
74} // namespace pairinteraction::euler
Matrix< Type, 3, 3 > Matrix3
std::array< Real, 3 > get_euler_angles(std::array< Real, 3 > to_z_axis, std::array< Real, 3 > to_y_axis)
Extract the Euler angles alpha, beta, gamma.
Definition: euler.hpp:64
Eigen::Matrix3< Real > get_rotation_matrix(std::array< Real, 3 > to_z_axis, std::array< Real, 3 > to_y_axis)
Build a matrix that rotates the coordinate system to the new z-axis and y-axis.
Definition: euler.hpp:29