ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
vc_aos_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 "algebra/impl/vc_aos_approximately_equal.hpp"
13#include "detray/algebra/common/math.hpp"
14#include "detray/algebra/common/matrix.hpp"
15#include "detray/algebra/common/matrix_getter.hpp"
16#include "detray/algebra/common/vector.hpp"
17#include "detray/algebra/concepts.hpp"
18#include "detray/algebra/utils/approximately_equal.hpp"
19#include "detray/definitions/detail/qualifiers.hpp"
20
21// Vc include(s).
22#ifdef _MSC_VER
23#pragma warning(push, 0)
24#endif // MSVC
25#include <Vc/Vc>
26#ifdef _MSC_VER
27#pragma warning(pop)
28#endif // MSVC
29
30// System include(s).
31#include <cassert>
32#include <concepts>
33#include <limits>
34
35namespace detray::algebra::vc_aos::math {
36
37using algebra::storage::operator*;
38using algebra::storage::operator/;
39using algebra::storage::operator-;
40using algebra::storage::operator+;
41
43template <template <typename, std::size_t> class array_t,
44 concepts::scalar scalar_t>
45struct transform3 {
46 private:
47 // How to address matrix columns
48 enum elem : std::size_t {
49 e_x = 0u,
50 e_y = 1u,
51 e_z = 2u,
52 e_t = 3u,
53 };
54
55 public:
58
60 using scalar_type = scalar_t;
61
63 template <std::size_t N>
64 using array_type = array_t<scalar_type, N>;
65
71 using point2 = vector2;
73 using point3 = vector3;
74
79
82
84 template <concepts::scalar o_scalar_t>
86
88
91
96
99 DETRAY_HOST_DEVICE
100 constexpr transform3()
101 : _data{algebra::storage::identity<matrix44>()},
102 _data_inv{algebra::storage::identity<matrix44>()} {}
103
110 DETRAY_HOST_DEVICE
111 transform3(const vector3 &t, const vector3 &x, const vector3 &y,
112 const vector3 &z)
113 : _data{x, y, z, t}, _data_inv{invert(_data)} {}
114
122 DETRAY_HOST_DEVICE
123 transform3(const vector3 &t, const vector3 &z, const vector3 &x)
124 : transform3(
125 t, x,
126 column_t(z[1] * x[2] - x[1] * z[2], z[2] * x[0] - x[2] * z[0],
127 z[0] * x[1] - x[0] * z[1]),
128 z) {}
129
133 DETRAY_HOST_DEVICE
134 explicit transform3(const vector3 &t)
135 : _data{column_t{1.f, 0.f, 0.f}, column_t{0.f, 1.f, 0.f},
136 column_t{0.f, 0.f, 1.f}, t},
138
142 DETRAY_HOST_DEVICE
143 explicit transform3(const matrix44 &m) : _data{m}, _data_inv{invert(_data)} {}
144
149 DETRAY_HOST_DEVICE
150 transform3(const matrix44 &m, const matrix44 &m_inv)
151 : _data{m}, _data_inv{m_inv} {
152 // The assertion will not hold for (casts to) int
153 if constexpr (std::floating_point<scalar_type>) {
154 [[maybe_unused]] constexpr auto epsilon{
155 std::numeric_limits<float>::epsilon()};
156 assert(algebra::approx_equal(invert(m), m_inv, 16.f * epsilon, 1e-6f));
157 }
158 }
159
163 DETRAY_HOST_DEVICE
164 explicit transform3(const array_type<16> &ma) {
165 // The values that are not set here, are known to be zero or one
166 // and never used explicitly
167 _data[e_x] = column_t{ma[0], ma[4], ma[8]};
168 _data[e_y] = column_t{ma[1], ma[5], ma[9]};
169 _data[e_z] = column_t{ma[2], ma[6], ma[10]};
170 _data[e_t] = column_t{ma[3], ma[7], ma[11]};
171
173 }
174
177 transform3(const transform3 &rhs) = default;
178 ~transform3() = default;
179
183 DETRAY_HOST_DEVICE
184 constexpr bool operator==(const transform3 &rhs) const {
185 return (_data == rhs._data);
186 }
187
192 DETRAY_HOST_DEVICE
193 constexpr const scalar_type &operator()(std::size_t row,
194 std::size_t col) const {
195 return _data[col][row];
196 }
197
201 DETRAY_HOST_DEVICE
202 constexpr scalar_type &operator()(std::size_t row, std::size_t col) {
203 return _data[col][row];
204 }
205
211 DETRAY_HOST_DEVICE
212 constexpr scalar_type determinant(const matrix44 &m) const {
213 return -m[e_z][0] * m[e_y][1] * m[e_x][2] +
214 m[e_y][0] * m[e_z][1] * m[e_x][2] +
215 m[e_z][0] * m[e_x][1] * m[e_y][2] -
216 m[e_x][0] * m[e_z][1] * m[e_y][2] -
217 m[e_y][0] * m[e_x][1] * m[e_z][2] +
218 m[e_x][0] * m[e_y][1] * m[e_z][2];
219 }
220
226 DETRAY_HOST_DEVICE
227 constexpr matrix44 invert(const matrix44 &m) const {
228 matrix44 i;
229 i[e_x][0] = -m[e_z][1] * m[e_y][2] + m[e_y][1] * m[e_z][2];
230 i[e_x][1] = m[e_z][1] * m[e_x][2] - m[e_x][1] * m[e_z][2];
231 i[e_x][2] = -m[e_y][1] * m[e_x][2] + m[e_x][1] * m[e_y][2];
232 // i[e_x][3] = 0;
233 i[e_y][0] = m[e_z][0] * m[e_y][2] - m[e_y][0] * m[e_z][2];
234 i[e_y][1] = -m[e_z][0] * m[e_x][2] + m[e_x][0] * m[e_z][2];
235 i[e_y][2] = m[e_y][0] * m[e_x][2] - m[e_x][0] * m[e_y][2];
236 // i[e_y][3] = 0;
237 i[e_z][0] = -m[e_z][0] * m[e_y][1] + m[e_y][0] * m[e_z][1];
238 i[e_z][1] = m[e_z][0] * m[e_x][1] - m[e_x][0] * m[e_z][1];
239 i[e_z][2] = -m[e_y][0] * m[e_x][1] + m[e_x][0] * m[e_y][1];
240 // i[e_z][3] = 0;
241 i[e_t][0] =
242 m[e_t][0] * m[e_z][1] * m[e_y][2] - m[e_z][0] * m[e_t][1] * m[e_y][2] -
243 m[e_t][0] * m[e_y][1] * m[e_z][2] + m[e_y][0] * m[e_t][1] * m[e_z][2] +
244 m[e_z][0] * m[e_y][1] * m[e_t][2] - m[e_y][0] * m[e_z][1] * m[e_t][2];
245 i[e_t][1] =
246 m[e_z][0] * m[e_t][1] * m[e_x][2] - m[e_t][0] * m[e_z][1] * m[e_x][2] +
247 m[e_t][0] * m[e_x][1] * m[e_z][2] - m[e_x][0] * m[e_t][1] * m[e_z][2] -
248 m[e_z][0] * m[e_x][1] * m[e_t][2] + m[e_x][0] * m[e_z][1] * m[e_t][2];
249 i[e_t][2] =
250 m[e_t][0] * m[e_y][1] * m[e_x][2] - m[e_y][0] * m[e_t][1] * m[e_x][2] -
251 m[e_t][0] * m[e_x][1] * m[e_y][2] + m[e_x][0] * m[e_t][1] * m[e_y][2] +
252 m[e_y][0] * m[e_x][1] * m[e_t][2] - m[e_x][0] * m[e_y][1] * m[e_t][2];
253 // i[e_t][3] = 1;
254 const scalar_type idet{scalar_type(1.f) / determinant(i)};
255
256 i[e_x] = i[e_x] * idet;
257 i[e_y] = i[e_y] * idet;
258 i[e_z] = i[e_z] * idet;
259 i[e_t] = i[e_t] * idet;
260
261 return i;
262 }
263
269 template <concepts::vector2D vector2_type>
270 DETRAY_HOST_DEVICE constexpr auto rotate(const matrix44 &m,
271 const vector2_type &v) const {
272 return m[e_x] * v[0] + m[e_y] * v[1];
273 }
274
280 template <concepts::vector3D vector3_type>
281 DETRAY_HOST_DEVICE constexpr auto rotate(const matrix44 &m,
282 const vector3_type &v) const {
283 return m[e_x] * v[0] + m[e_y] * v[1] + m[e_z] * v[2];
284 }
285
288 DETRAY_HOST_DEVICE
289 constexpr auto rotation() const {
291
292 matrix_t submatrix;
293 for (unsigned int icol = 0; icol < 3; ++icol) {
294 submatrix[icol] = _data[icol];
295 }
296 return submatrix;
297 }
298
301 DETRAY_HOST_DEVICE
302 constexpr const auto &x() const { return _data[e_x]; }
303
306 DETRAY_HOST_DEVICE
307 constexpr const auto &y() const { return _data[e_y]; }
308
311 DETRAY_HOST_DEVICE
312 constexpr const auto &z() const { return _data[e_z]; }
313
316 DETRAY_HOST_DEVICE
317 constexpr const auto &translation() const { return _data[e_t]; }
318
321 DETRAY_HOST_DEVICE
322 constexpr const matrix44 &matrix() const { return _data; }
323
326 DETRAY_HOST_DEVICE
327 constexpr const matrix44 &matrix_inverse() const { return _data_inv; }
328
337 template <concepts::point2D point2_type>
338 DETRAY_HOST_DEVICE constexpr auto point_to_global(
339 const point2_type &p) const {
340 return rotate(_data, p) + _data[e_t];
341 }
342
351 template <concepts::point3D point3_type>
352 DETRAY_HOST_DEVICE constexpr auto point_to_global(
353 const point3_type &p) const {
354 return rotate(_data, p) + _data[e_t];
355 }
356
365 template <concepts::point3D point3_type>
366 DETRAY_HOST_DEVICE constexpr auto point_to_local(const point3_type &p) const {
367 return rotate(_data_inv, p) + _data_inv[e_t];
368 }
369
378 template <concepts::vector2D vector2_type>
379 DETRAY_HOST_DEVICE constexpr auto vector_to_global(
380 const vector2_type &v) const {
381 return rotate(_data, v);
382 }
383
392 template <concepts::vector3D vector3_type>
393 DETRAY_HOST_DEVICE constexpr auto vector_to_global(
394 const vector3_type &v) const {
395 return rotate(_data, v);
396 }
397
406 template <concepts::vector3D vector3_type>
407 DETRAY_HOST_DEVICE constexpr auto vector_to_local(
408 const vector3_type &v) const {
409 return rotate(_data_inv, v);
410 }
411}; // struct transform3
412
413} // namespace detray::algebra::vc_aos::math
Vector wrapper for AoS vs interleaved SoA data.
Definition vector.hpp:52
Functor used to access elements of a matrix.
Definition matrix_getter.hpp:21
Generic matrix type that can take vectors as columns.
Definition matrix.hpp:25
algebra::storage::vector< ROW, scalar_t, array_t > vector_type
Definition matrix.hpp:27
constexpr auto point_to_global(const point3_type &p) const
This method transform from a point from the local 3D cartesian frame to the global 3D cartesian frame...
Definition vc_aos_transform3.hpp:352
transform3(const vector3 &t)
Constructor with arguments: translation.
Definition vc_aos_transform3.hpp:134
transform3< array_t, o_scalar_t > other_type
Helper type to cast this to another floating point precision.
Definition vc_aos_transform3.hpp:85
algebra::storage::vector< 3u, scalar_type, array_t > vector3
Three-component vector type used for spatial quantities.
Definition vc_aos_transform3.hpp:69
constexpr auto rotate(const matrix44 &m, const vector3_type &v) const
Rotate a vector into / from a frame.
Definition vc_aos_transform3.hpp:281
constexpr scalar_type & operator()(std::size_t row, std::size_t col)
Return a writable matrix element.
Definition vc_aos_transform3.hpp:202
algebra::storage::matrix< array_t, scalar_type, 3u, 4u > matrix44
4x4 matrix type (Last row is {0, 0, 0, 1} and can be omitted)
Definition vc_aos_transform3.hpp:76
transform3(const matrix44 &m)
Constructor with arguments: matrix.
Definition vc_aos_transform3.hpp:143
algebra::storage::vector< 2u, scalar_type, array_t > vector2
Vector and point types.
Definition vc_aos_transform3.hpp:67
vector2 point2
Two-dimensional point representation.
Definition vc_aos_transform3.hpp:71
constexpr transform3()
Default constructor: identity.
Definition vc_aos_transform3.hpp:100
scalar_t scalar_type
Scalar type used by the transform.
Definition vc_aos_transform3.hpp:60
transform3(const matrix44 &m, const matrix44 &m_inv)
Constructor with arguments: matrix and its inverse.
Definition vc_aos_transform3.hpp:150
matrix44 _data
Definition vc_aos_transform3.hpp:93
constexpr const matrix44 & matrix() const
This method retrieves the 4x4 matrix of a transform.
Definition vc_aos_transform3.hpp:322
constexpr const auto & x() const
Definition vc_aos_transform3.hpp:302
transform3(const transform3 &rhs)=default
Copy an existing transform.
constexpr const auto & translation() const
This method retrieves the translation.
Definition vc_aos_transform3.hpp:317
constexpr matrix44 invert(const matrix44 &m) const
Definition vc_aos_transform3.hpp:227
constexpr auto rotate(const matrix44 &m, const vector2_type &v) const
Rotate a vector into / from a frame.
Definition vc_aos_transform3.hpp:270
constexpr auto rotation() const
This method retrieves the rotation of a transform.
Definition vc_aos_transform3.hpp:289
constexpr const auto & y() const
Definition vc_aos_transform3.hpp:307
transform3(const array_type< 16 > &ma)
Constructor with arguments: matrix as std::array of scalar.
Definition vc_aos_transform3.hpp:164
constexpr scalar_type determinant(const matrix44 &m) const
The determinant of a 4x4 matrix.
Definition vc_aos_transform3.hpp:212
constexpr auto point_to_local(const point3_type &p) const
This method transform from a vector from the global 3D cartesian frame into the local 3D cartesian fr...
Definition vc_aos_transform3.hpp:366
algebra::storage::element_getter element_getter
Function (object) used for accessing a matrix element.
Definition vc_aos_transform3.hpp:81
constexpr auto vector_to_local(const vector3_type &v) const
This method transform from a vector from the global 3D cartesian frame into the local 3D cartesian fr...
Definition vc_aos_transform3.hpp:407
constexpr const auto & z() const
Definition vc_aos_transform3.hpp:312
constexpr const matrix44 & matrix_inverse() const
This method retrieves the 4x4 matrix of an inverse transform.
Definition vc_aos_transform3.hpp:327
constexpr auto vector_to_global(const vector3_type &v) const
This method transform from a vector from the local 3D cartesian frame to the global 3D cartesian fram...
Definition vc_aos_transform3.hpp:393
constexpr const scalar_type & operator()(std::size_t row, std::size_t col) const
Matrix access operator.
Definition vc_aos_transform3.hpp:193
constexpr bool operator==(const transform3 &rhs) const
Equality operator.
Definition vc_aos_transform3.hpp:184
typename matrix44::vector_type column_t
Column type used to construct the stored matrix.
Definition vc_aos_transform3.hpp:78
transform3(const vector3 &t, const vector3 &z, const vector3 &x)
Constructor with arguments: t, z, x.
Definition vc_aos_transform3.hpp:123
matrix44 _data_inv
Definition vc_aos_transform3.hpp:95
constexpr auto vector_to_global(const vector2_type &v) const
This method transform from a vector from the local 2D cartesian frame to the global 3D cartesian fram...
Definition vc_aos_transform3.hpp:379
array_t< scalar_type, N > array_type
Vector storage with N components in the selected array layout.
Definition vc_aos_transform3.hpp:64
vector3 point3
Three-dimensional point representation.
Definition vc_aos_transform3.hpp:73
transform3(const vector3 &t, const vector3 &x, const vector3 &y, const vector3 &z)
Constructor with arguments: t, x, y, z.
Definition vc_aos_transform3.hpp:111
constexpr auto point_to_global(const point2_type &p) const
This method transform from a point from the local 2D cartesian frame to the global 3D cartesian frame...
Definition vc_aos_transform3.hpp:338