File indexing completed on 2026-05-27 07:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/test/cpu/algebra_fixture.hpp"
0011
0012
0013 #include "detray/algebra/utils/approximately_equal.hpp"
0014 #include "detray/algebra/utils/casts.hpp"
0015 #include "detray/algebra/utils/print.hpp"
0016
0017
0018 #include <gtest/gtest.h>
0019
0020
0021 #include <array>
0022 #include <iostream>
0023
0024 namespace detray::test {
0025
0026
0027 TEST_F(detray_algebra, transform3D) {
0028 static_assert(detray::concepts::transform3D<transform3>);
0029
0030
0031 vector3 z = detray::vector::normalize(vector3{3.f, 2.f, 1.f});
0032 vector3 x = detray::vector::normalize(vector3{2.f, -3.f, 0.f});
0033 vector3 y = detray::vector::cross(z, x);
0034 point3 t = {2.f, 3.f, 4.f};
0035
0036
0037 transform3 trf1(t, z, x);
0038 ASSERT_TRUE(trf1 == trf1);
0039 transform3 trf2;
0040 trf2 = trf1;
0041
0042
0043 std::cout << trf1 << std::endl;
0044
0045
0046 ASSERT_TRUE(detray::algebra::approx_equal(trf1, trf1));
0047 ASSERT_TRUE(detray::algebra::approx_equal(trf1, trf1, this->epsilon()));
0048
0049 scalar rel_err{1.f + 10.f * this->epsilon()};
0050 transform3 trf1_err(rel_err * t, rel_err * z, rel_err * x);
0051 ASSERT_TRUE(
0052 detray::algebra::approx_equal(trf1, trf1_err, 200.f * this->epsilon()));
0053 ASSERT_FALSE(
0054 detray::algebra::approx_equal(trf1, trf1_err, 10.f * this->epsilon()));
0055
0056 const auto trf1_cast_f = detray::algebra::cast_to<float>(trf1);
0057 const auto& mat_f = trf1_cast_f.matrix();
0058 const auto& mat_inv_f = trf1_cast_f.matrix_inverse();
0059
0060 for (std::size_t j = 0u; j < 3u; ++j) {
0061 for (std::size_t i = 0u; i < 2u; ++i) {
0062 auto elem_i = detray::getter::element(mat_f, i, j);
0063 auto elem_inv_i = detray::getter::element(mat_inv_f, i, j);
0064
0065 static_assert(std::same_as<decltype(elem_i), float>);
0066 static_assert(std::same_as<decltype(elem_inv_i), float>);
0067 ASSERT_FLOAT_EQ(elem_i,
0068 static_cast<float>(detray::getter::element(mat_f, i, j)));
0069 ASSERT_FLOAT_EQ(elem_inv_i, static_cast<float>(detray::getter::element(
0070 mat_inv_f, i, j)));
0071 }
0072 }
0073
0074 const auto trf1_cast_d = detray::algebra::cast_to<double>(trf1);
0075 const auto& mat_d = trf1_cast_d.matrix();
0076 const auto& mat_inv_d = trf1_cast_d.matrix_inverse();
0077
0078 for (std::size_t j = 0u; j < 3u; ++j) {
0079 for (std::size_t i = 0u; i < 2u; ++i) {
0080 auto elem_i = detray::getter::element(mat_d, i, j);
0081 auto elem_inv_i = detray::getter::element(mat_inv_d, i, j);
0082
0083 static_assert(std::same_as<decltype(elem_i), double>);
0084 static_assert(std::same_as<decltype(elem_inv_i), double>);
0085 ASSERT_DOUBLE_EQ(
0086 elem_i, static_cast<double>(detray::getter::element(mat_d, i, j)));
0087 ASSERT_DOUBLE_EQ(elem_inv_i, static_cast<double>(detray::getter::element(
0088 mat_inv_d, i, j)));
0089 }
0090 }
0091
0092 const auto trf1_cast_i = detray::algebra::cast_to<int>(trf1);
0093 const auto& mat_i = trf1_cast_i.matrix();
0094 const auto& mat_inv_i = trf1_cast_i.matrix_inverse();
0095
0096 for (std::size_t j = 0u; j < 3u; ++j) {
0097 for (std::size_t i = 0u; i < 2u; ++i) {
0098 auto elem_i = detray::getter::element(mat_i, i, j);
0099 auto elem_inv_i = detray::getter::element(mat_inv_i, i, j);
0100
0101 static_assert(std::same_as<decltype(elem_i), int>);
0102 static_assert(std::same_as<decltype(elem_inv_i), int>);
0103 ASSERT_EQ(elem_i, static_cast<int>(detray::getter::element(mat_i, i, j)));
0104 ASSERT_EQ(elem_inv_i,
0105 static_cast<int>(detray::getter::element(mat_inv_i, i, j)));
0106 }
0107 }
0108
0109 const auto rot = trf2.rotation();
0110 ASSERT_NEAR(detray::getter::element(rot, 0, 0), x[0], this->epsilon());
0111 ASSERT_NEAR(detray::getter::element(rot, 1, 0), x[1], this->epsilon());
0112 ASSERT_NEAR(detray::getter::element(rot, 2, 0), x[2], this->epsilon());
0113 ASSERT_NEAR(detray::getter::element(rot, 0, 1), y[0], this->epsilon());
0114 ASSERT_NEAR(detray::getter::element(rot, 1, 1), y[1], this->epsilon());
0115 ASSERT_NEAR(detray::getter::element(rot, 2, 1), y[2], this->epsilon());
0116 ASSERT_NEAR(detray::getter::element(rot, 0, 2), z[0], this->epsilon());
0117 ASSERT_NEAR(detray::getter::element(rot, 1, 2), z[1], this->epsilon());
0118 ASSERT_NEAR(detray::getter::element(rot, 2, 2), z[2], this->epsilon());
0119
0120 auto trn = trf2.translation();
0121 ASSERT_NEAR(trn[0], 2.f, this->epsilon());
0122 ASSERT_NEAR(trn[1], 3.f, this->epsilon());
0123 ASSERT_NEAR(trn[2], 4.f, this->epsilon());
0124
0125
0126 auto m44 = trf2.matrix();
0127 transform3 trfm(m44);
0128
0129
0130 [[maybe_unused]] vector3
0131 test_vector;
0132
0133
0134 test_vector = detray::getter::vector<3>(m44, 0, 0);
0135 test_vector = detray::getter::vector<3>(m44, 0, 1);
0136 test_vector = detray::getter::vector<3>(m44, 0, 2);
0137
0138
0139 auto m44_inv = trf2.matrix_inverse();
0140
0141
0142 test_vector = detray::getter::vector<3>(m44_inv, 0, 0);
0143 test_vector = detray::getter::vector<3>(m44_inv, 0, 1);
0144 test_vector = detray::getter::vector<3>(m44_inv, 0, 2);
0145
0146
0147 auto rotm = trfm.rotation();
0148 ASSERT_NEAR(detray::getter::element(rotm, 0, 0), x[0], this->epsilon());
0149 ASSERT_NEAR(detray::getter::element(rotm, 1, 0), x[1], this->epsilon());
0150 ASSERT_NEAR(detray::getter::element(rotm, 2, 0), x[2], this->epsilon());
0151 ASSERT_NEAR(detray::getter::element(rotm, 0, 1), y[0], this->epsilon());
0152 ASSERT_NEAR(detray::getter::element(rotm, 1, 1), y[1], this->epsilon());
0153 ASSERT_NEAR(detray::getter::element(rotm, 2, 1), y[2], this->epsilon());
0154 ASSERT_NEAR(detray::getter::element(rotm, 0, 2), z[0], this->epsilon());
0155 ASSERT_NEAR(detray::getter::element(rotm, 1, 2), z[1], this->epsilon());
0156 ASSERT_NEAR(detray::getter::element(rotm, 2, 2), z[2], this->epsilon());
0157
0158 auto trnm = trfm.translation();
0159 ASSERT_NEAR(trnm[0], 2.f, this->epsilon());
0160 ASSERT_NEAR(trnm[1], 3.f, this->epsilon());
0161 ASSERT_NEAR(trnm[2], 4.f, this->epsilon());
0162
0163
0164 std::array<scalar, 16> matray_helper = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f,
0165 0.f, 0.f, 0.f, 0.f, 1.f, 0.f,
0166 0.f, 0.f, 0.f, 0.f};
0167 typename transform3::template array_type<16> matray;
0168 for (unsigned int i = 0u; i < 16u; ++i) {
0169 matray[i] = matray_helper[i];
0170 }
0171 transform3 trfma(matray);
0172
0173
0174 auto rotma = trfma.rotation();
0175 ASSERT_NEAR(detray::getter::element(rotma, 0, 0), 1.f, this->epsilon());
0176 ASSERT_NEAR(detray::getter::element(rotma, 1, 0), 0.f, this->epsilon());
0177 ASSERT_NEAR(detray::getter::element(rotma, 2, 0), 0.f, this->epsilon());
0178 ASSERT_NEAR(detray::getter::element(rotma, 0, 1), 0.f, this->epsilon());
0179 ASSERT_NEAR(detray::getter::element(rotma, 1, 1), 1.f, this->epsilon());
0180 ASSERT_NEAR(detray::getter::element(rotma, 2, 1), 0.f, this->epsilon());
0181 ASSERT_NEAR(detray::getter::element(rotma, 0, 2), 0.f, this->epsilon());
0182 ASSERT_NEAR(detray::getter::element(rotma, 1, 2), 0.f, this->epsilon());
0183 ASSERT_NEAR(detray::getter::element(rotma, 2, 2), 1.f, this->epsilon());
0184
0185 auto trnma = trfma.translation();
0186 ASSERT_NEAR(trnma[0], 0.f, this->epsilon());
0187 ASSERT_NEAR(trnma[1], 0.f, this->epsilon());
0188 ASSERT_NEAR(trnma[2], 0.f, this->epsilon());
0189 }
0190
0191
0192 TEST_F(detray_algebra, global_transformations) {
0193
0194 vector3 z = detray::vector::normalize(vector3{3.f, 2.f, 1.f});
0195 vector3 x = detray::vector::normalize(vector3{2.f, -3.f, 0.f});
0196 [[maybe_unused]] vector3 y = detray::vector::cross(z, x);
0197 point3 t = {2.f, 3.f, 4.f};
0198 transform3 trf(t, z, x);
0199
0200
0201 point3 lzero = {0.f, 0.f, 0.f};
0202 point3 gzero = trf.point_to_global(lzero);
0203 ASSERT_NEAR(gzero[0], t[0], this->epsilon());
0204 ASSERT_NEAR(gzero[1], t[1], this->epsilon());
0205 ASSERT_NEAR(gzero[2], t[2], this->epsilon());
0206
0207
0208 point3 lpoint = {3.f, 4.f, 5.f};
0209 point3 gpoint = trf.point_to_global(lpoint);
0210 point3 lpoint_r = trf.point_to_local(gpoint);
0211 ASSERT_NEAR(lpoint[0], lpoint_r[0], this->tolerance());
0212 ASSERT_NEAR(lpoint[1], lpoint_r[1], this->tolerance());
0213 ASSERT_NEAR(lpoint[2], lpoint_r[2], this->tolerance());
0214
0215
0216
0217 transform3 ttrf(t);
0218
0219 vector3 gvector = {1.f, 1.f, 1.f};
0220 vector3 lvector = ttrf.vector_to_local(gvector);
0221 ASSERT_NEAR(gvector[0], lvector[0], this->tolerance());
0222 ASSERT_NEAR(gvector[1], lvector[1], this->tolerance());
0223 ASSERT_NEAR(gvector[2], lvector[2], this->tolerance());
0224
0225
0226 vector3 lvectorB = {7.f, 8.f, 9.f};
0227 vector3 gvectorB = trf.vector_to_local(lvectorB);
0228 vector3 lvectorC = trf.vector_to_global(gvectorB);
0229 ASSERT_NEAR(lvectorB[0], lvectorC[0], this->tolerance());
0230 ASSERT_NEAR(lvectorB[1], lvectorC[1], this->tolerance());
0231 ASSERT_NEAR(lvectorB[2], lvectorC[2], this->tolerance());
0232 }
0233
0234 }