ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
generic_transform3.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s).
12#include "detray/algebra/generic/algorithms/matrix/inverse/hard_coded.hpp"
13#include "detray/algebra/generic/impl/generic_matrix.hpp"
14#include "detray/algebra/generic/impl/generic_vector.hpp"
15#include "detray/algebra/type_traits.hpp"
16#include "detray/algebra/utils/approximately_equal.hpp"
17#include "detray/definitions/detail/qualifiers.hpp"
18
19// System include(s)
20#include <cassert>
21#include <concepts>
22#include <limits>
23
24namespace detray::algebra::generic::math {
25
27template <concepts::index index_t, concepts::scalar scalar_t,
28 template <typename, index_t, index_t> class matrix_t,
29 template <typename, index_t> class array_t>
30struct transform3 {
33
35 using scalar_type = scalar_t;
36
38 template <index_t N>
39 using array_type = array_t<scalar_t, N>;
40
41 // 4 x 4 Matrix (keep four rows for better alignment)
43 using matrix44 = matrix_t<scalar_t, 4, 4>;
45
47 using vector2 = detray::traits::get_vector_t<matrix44, 2, scalar_t>;
49 using vector3 = detray::traits::get_vector_t<matrix44, 3, scalar_t>;
52 using point2 = vector2;
55 using point3 = vector3;
56
58 using element_getter = detray::traits::element_getter_t<matrix44>;
60 using block_getter = detray::traits::block_getter_t<matrix44>;
61
64
66 template <concepts::scalar o_scalar_t>
68
70
74 generic::math::identity<matrix44>()};
75
77 generic::math::identity<matrix44>()};
78
79
81
83 constexpr transform3() = default;
84
92 DETRAY_HOST_DEVICE
93 transform3(const vector3 &t, const vector3 &x, const vector3 &y,
94 const vector3 &z, bool get_inverse = true) {
95 element_getter{}(_data, 0, 0) = element_getter{}(x, 0);
96 element_getter{}(_data, 1, 0) = element_getter{}(x, 1);
97 element_getter{}(_data, 2, 0) = element_getter{}(x, 2);
98 element_getter{}(_data, 3, 0) = 0.f;
99 element_getter{}(_data, 0, 1) = element_getter{}(y, 0);
100 element_getter{}(_data, 1, 1) = element_getter{}(y, 1);
101 element_getter{}(_data, 2, 1) = element_getter{}(y, 2);
102 element_getter{}(_data, 3, 1) = 0.f;
103 element_getter{}(_data, 0, 2) = element_getter{}(z, 0);
104 element_getter{}(_data, 1, 2) = element_getter{}(z, 1);
105 element_getter{}(_data, 2, 2) = element_getter{}(z, 2);
106 element_getter{}(_data, 3, 2) = 0.f;
107 element_getter{}(_data, 0, 3) = element_getter{}(t, 0);
108 element_getter{}(_data, 1, 3) = element_getter{}(t, 1);
109 element_getter{}(_data, 2, 3) = element_getter{}(t, 2);
110 element_getter{}(_data, 3, 3) = 1.f;
111
112 if (get_inverse) {
114 }
115 }
116
125 DETRAY_HOST_DEVICE
126 transform3(const vector3 &t, const vector3 &z, const vector3 &x,
127 bool get_inverse = true)
128 : transform3(t, x, cross(z, x), z, get_inverse) {}
129
133 DETRAY_HOST_DEVICE
134 explicit transform3(const vector3 &t) {
135 element_getter{}(_data, 0, 0) = 1.f;
136 element_getter{}(_data, 1, 0) = 0.f;
137 element_getter{}(_data, 2, 0) = 0.f;
138 element_getter{}(_data, 3, 0) = 0.f;
139 element_getter{}(_data, 0, 1) = 0.f;
140 element_getter{}(_data, 1, 1) = 1.f;
141 element_getter{}(_data, 2, 1) = 0.f;
142 element_getter{}(_data, 3, 1) = 0.f;
143 element_getter{}(_data, 0, 2) = 0.f;
144 element_getter{}(_data, 1, 2) = 0.f;
145 element_getter{}(_data, 2, 2) = 1.f;
146 element_getter{}(_data, 3, 2) = 0.f;
147 element_getter{}(_data, 0, 3) = element_getter{}(t, 0);
148 element_getter{}(_data, 1, 3) = element_getter{}(t, 1);
149 element_getter{}(_data, 2, 3) = element_getter{}(t, 2);
150 element_getter{}(_data, 3, 3) = 1.f;
151
153 }
154
158 DETRAY_HOST_DEVICE
159 explicit transform3(const matrix44 &m) : _data{m} {
161 }
162
167 DETRAY_HOST_DEVICE
168 transform3(const matrix44 &m, const matrix44 &m_inv)
169 : _data{m}, _data_inv{m_inv} {
170 // The assertion will not hold for (casts to) int
171 if constexpr (std::floating_point<scalar_type>) {
172 // The concrete type of matrix mult is not available at this point
173 auto prod = generic::math::zero<matrix44>();
174
175 constexpr element_getter elem{};
176
177 for (index_t i = 0; i < 4; ++i) {
178 for (index_t j = 0; j < 4; ++j) {
179 for (index_t k = 0; k < 4; ++k) {
180 elem(prod, k, j) += elem(m, k, i) * elem(m_inv, i, j);
181 }
182 }
183 }
184
185 [[maybe_unused]] constexpr auto epsilon{
186 std::numeric_limits<scalar_type>::epsilon()};
187 assert(algebra::approx_equal(prod, generic::math::identity<matrix44>(),
188 16.f * epsilon, 1e-6f));
189 }
190 }
191
195 DETRAY_HOST_DEVICE
196 explicit transform3(const array_type<16> &ma) {
197 element_getter{}(_data, 0, 0) = ma[0];
198 element_getter{}(_data, 1, 0) = ma[4];
199 element_getter{}(_data, 2, 0) = ma[8];
200 element_getter{}(_data, 3, 0) = 0.f;
201 element_getter{}(_data, 0, 1) = ma[1];
202 element_getter{}(_data, 1, 1) = ma[5];
203 element_getter{}(_data, 2, 1) = ma[9];
204 element_getter{}(_data, 3, 1) = 0.f;
205 element_getter{}(_data, 0, 2) = ma[2];
206 element_getter{}(_data, 1, 2) = ma[6];
207 element_getter{}(_data, 2, 2) = ma[10];
208 element_getter{}(_data, 3, 2) = 0.f;
209 element_getter{}(_data, 0, 3) = ma[3];
210 element_getter{}(_data, 1, 3) = ma[7];
211 element_getter{}(_data, 2, 3) = ma[11];
212 element_getter{}(_data, 3, 3) = 1.f;
213
215 }
216
220 DETRAY_HOST_DEVICE
221 constexpr bool operator==(const transform3 &rhs) const {
222 for (index_t j = 0; j < 4; j++) {
223 // Check only the rows that can differ
224 for (index_t i = 0; i < 3; i++) {
225 if (element_getter{}(_data, i, j) !=
226 element_getter{}(rhs._data, i, j)) {
227 return false;
228 }
229 }
230 }
231
232 return true;
233 }
234
240 DETRAY_HOST_DEVICE
241 static constexpr vector3 rotate(const matrix44 &m, const vector2 &v) {
242 vector3 ret{0.f, 0.f, 0.f};
243
244 element_getter{}(ret, 0) +=
245 element_getter{}(m, 0, 0) * element_getter{}(v, 0);
246 element_getter{}(ret, 1) +=
247 element_getter{}(m, 1, 0) * element_getter{}(v, 0);
248 element_getter{}(ret, 2) +=
249 element_getter{}(m, 2, 0) * element_getter{}(v, 0);
250
251 element_getter{}(ret, 0) +=
252 element_getter{}(m, 0, 1) * element_getter{}(v, 1);
253 element_getter{}(ret, 1) +=
254 element_getter{}(m, 1, 1) * element_getter{}(v, 1);
255 element_getter{}(ret, 2) +=
256 element_getter{}(m, 2, 1) * element_getter{}(v, 1);
257
258 return ret;
259 }
260
266 DETRAY_HOST_DEVICE
267 static constexpr vector3 rotate(const matrix44 &m, const vector3 &v) {
268 vector3 ret{0.f, 0.f, 0.f};
269
270 element_getter{}(ret, 0) +=
271 element_getter{}(m, 0, 0) * element_getter{}(v, 0);
272 element_getter{}(ret, 1) +=
273 element_getter{}(m, 1, 0) * element_getter{}(v, 0);
274 element_getter{}(ret, 2) +=
275 element_getter{}(m, 2, 0) * element_getter{}(v, 0);
276
277 element_getter{}(ret, 0) +=
278 element_getter{}(m, 0, 1) * element_getter{}(v, 1);
279 element_getter{}(ret, 1) +=
280 element_getter{}(m, 1, 1) * element_getter{}(v, 1);
281 element_getter{}(ret, 2) +=
282 element_getter{}(m, 2, 1) * element_getter{}(v, 1);
283
284 element_getter{}(ret, 0) +=
285 element_getter{}(m, 0, 2) * element_getter{}(v, 2);
286 element_getter{}(ret, 1) +=
287 element_getter{}(m, 1, 2) * element_getter{}(v, 2);
288 element_getter{}(ret, 2) +=
289 element_getter{}(m, 2, 2) * element_getter{}(v, 2);
290
291 return ret;
292 }
293
296 DETRAY_HOST_DEVICE
297 auto constexpr rotation() const {
298 return block_getter{}.template operator()<3, 3>(_data, 0, 0);
299 }
300
303 DETRAY_HOST_DEVICE
304 constexpr point3 x() const {
305 return {element_getter{}(_data, 0, 0), element_getter{}(_data, 1, 0),
306 element_getter{}(_data, 2, 0)};
307 }
308
311 DETRAY_HOST_DEVICE
312 constexpr point3 y() const {
313 return {element_getter{}(_data, 0, 1), element_getter{}(_data, 1, 1),
314 element_getter{}(_data, 2, 1)};
315 }
316
319 DETRAY_HOST_DEVICE
320 constexpr point3 z() const {
321 return {element_getter{}(_data, 0, 2), element_getter{}(_data, 1, 2),
322 element_getter{}(_data, 2, 2)};
323 }
324
327 DETRAY_HOST_DEVICE
328 constexpr point3 translation() const {
329 return {element_getter{}(_data, 0, 3), element_getter{}(_data, 1, 3),
330 element_getter{}(_data, 2, 3)};
331 }
332
335 DETRAY_HOST_DEVICE
336 constexpr const matrix44 &matrix() const { return _data; }
337
340 DETRAY_HOST_DEVICE
341 constexpr const matrix44 &matrix_inverse() const { return _data_inv; }
342
347 DETRAY_HOST_DEVICE constexpr point3 point_to_global(const point2 &v) const {
348 const vector3 rg = rotate(_data, v);
349
350 return {element_getter{}(rg, 0) + element_getter{}(_data, 0, 3),
351 element_getter{}(rg, 1) + element_getter{}(_data, 1, 3),
352 element_getter{}(rg, 2) + element_getter{}(_data, 2, 3)};
353 }
354
359 DETRAY_HOST_DEVICE constexpr point3 point_to_global(const point3 &v) const {
360 const vector3 rg = rotate(_data, v);
361
362 return {element_getter{}(rg, 0) + element_getter{}(_data, 0, 3),
363 element_getter{}(rg, 1) + element_getter{}(_data, 1, 3),
364 element_getter{}(rg, 2) + element_getter{}(_data, 2, 3)};
365 }
366
370 DETRAY_HOST_DEVICE constexpr point3 point_to_local(const point3 &v) const {
371 const vector3 rg = rotate(_data_inv, v);
372
373 return {element_getter{}(rg, 0) + element_getter{}(_data_inv, 0, 3),
374 element_getter{}(rg, 1) + element_getter{}(_data_inv, 1, 3),
375 element_getter{}(rg, 2) + element_getter{}(_data_inv, 2, 3)};
376 }
377
382 DETRAY_HOST_DEVICE constexpr vector3 vector_to_global(
383 const vector2 &v) const {
384 return rotate(_data, v);
385 }
386
391 DETRAY_HOST_DEVICE constexpr vector3 vector_to_global(
392 const vector3 &v) const {
393 return rotate(_data, v);
394 }
395
400 DETRAY_HOST_DEVICE constexpr vector3 vector_to_local(const vector3 &v) const {
401 return rotate(_data_inv, v);
402 }
403
404}; // struct transform3
405
406} // namespace detray::algebra::generic::math
Definition concepts.hpp:86
vector2 point2
Two-dimensional point representation (same storage as a vector).
Definition generic_transform3.hpp:52
auto constexpr rotation() const
This method retrieves the rotation of a transform.
Definition generic_transform3.hpp:297
constexpr point3 x() const
Definition generic_transform3.hpp:304
constexpr const matrix44 & matrix() const
This method retrieves the 4x4 matrix of a transform.
Definition generic_transform3.hpp:336
detray::traits::get_vector_t< matrix44, 2, scalar_t > vector2
Two-component vector type used for local plane coordinates.
Definition generic_transform3.hpp:47
detray::traits::element_getter_t< matrix44 > element_getter
Function (object) used for accessing a matrix element/block.
Definition generic_transform3.hpp:58
transform3(const array_type< 16 > &ma)
Constructor with arguments: matrix as array of scalar.
Definition generic_transform3.hpp:196
constexpr point3 point_to_global(const point2 &v) const
This method transform from a point from the local 2D cartesian frame to the global 3D cartesian frame...
Definition generic_transform3.hpp:347
array_t< scalar_t, N > array_type
Array type used by the transform.
Definition generic_transform3.hpp:39
constexpr point3 y() const
Definition generic_transform3.hpp:312
constexpr transform3()=default
Default constructor: identity.
transform3(const vector3 &t, const vector3 &x, const vector3 &y, const vector3 &z, bool get_inverse=true)
Constructor with arguments: t, x, y, z.
Definition generic_transform3.hpp:93
constexpr vector3 vector_to_global(const vector3 &v) const
This method transform from a vector from the local 3D cartesian frame to the global 3D cartesian fram...
Definition generic_transform3.hpp:391
transform3(const matrix44 &m, const matrix44 &m_inv)
Constructor with arguments: matrix and its inverse.
Definition generic_transform3.hpp:168
generic::matrix::inverse::hard_coded< matrix44 > matrix_inversion
Matrix inversion algorithm.
Definition generic_transform3.hpp:63
matrix_t< scalar_t, 4, 4 > matrix44
Homogeneous matrix type used to store the transform.
Definition generic_transform3.hpp:43
constexpr point3 point_to_global(const point3 &v) const
This method transform from a point from the local 3D cartesian frame to the global 3D cartesian frame...
Definition generic_transform3.hpp:359
transform3< index_t, o_scalar_t, matrix_t, array_t > other_type
Helper type to cast this to another floating point precision.
Definition generic_transform3.hpp:67
constexpr const matrix44 & matrix_inverse() const
This method retrieves the 4x4 matrix of an inverse transform.
Definition generic_transform3.hpp:341
static constexpr vector3 rotate(const matrix44 &m, const vector3 &v)
Rotate a vector into / from a frame.
Definition generic_transform3.hpp:267
constexpr point3 point_to_local(const point3 &v) const
Transform a global point to local coordinates.
Definition generic_transform3.hpp:370
scalar_t scalar_type
Scalar type.
Definition generic_transform3.hpp:35
constexpr point3 translation() const
This method retrieves the translation of a transform.
Definition generic_transform3.hpp:328
transform3(const vector3 &t, const vector3 &z, const vector3 &x, bool get_inverse=true)
Constructor with arguments: t, z, x.
Definition generic_transform3.hpp:126
transform3(const matrix44 &m)
Constructor with arguments: matrix.
Definition generic_transform3.hpp:159
transform3(const vector3 &t)
Constructor with arguments: translation.
Definition generic_transform3.hpp:134
constexpr point3 z() const
Definition generic_transform3.hpp:320
vector3 point3
Three-dimensional point representation (same storage as a vector).
Definition generic_transform3.hpp:55
constexpr vector3 vector_to_local(const vector3 &v) const
This method transform from a vector from the global 3D cartesian frame into the local 3D cartesian fr...
Definition generic_transform3.hpp:400
constexpr vector3 vector_to_global(const vector2 &v) const
This method transform from a vector from the local 2D cartesian frame to the global 3D cartesian fram...
Definition generic_transform3.hpp:382
static constexpr vector3 rotate(const matrix44 &m, const vector2 &v)
Rotate a vector into / from a frame.
Definition generic_transform3.hpp:241
detray::traits::get_vector_t< matrix44, 3, scalar_t > vector3
Three-component vector type used for spatial quantities.
Definition generic_transform3.hpp:49
constexpr bool operator==(const transform3 &rhs) const
Equality operator.
Definition generic_transform3.hpp:221
detray::traits::block_getter_t< matrix44 > block_getter
Accessor for the 3x3 rotation block of the homogeneous matrix.
Definition generic_transform3.hpp:60
"inverse getter", assuming a N X N matrix
Definition hard_coded.hpp:24