// Ceres Solver - A fast non-linear least squares minimizer // Copyright 2023 Google Inc. All rights reserved. // http://ceres-solver.org/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Google Inc. nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. #ifndef CERES_PUBLIC_INTERNAL_EULER_ANGLES_H_ #define CERES_PUBLIC_INTERNAL_EULER_ANGLES_H_ #include namespace ceres { namespace internal { // The EulerSystem struct represents an Euler Angle Convention in compile time. // It acts like a trait structure and is also used as a tag for dispatching // Euler angle conversion function templates // // Internally, it implements the convention laid out in "Euler angle // conversion", Ken Shoemake, Graphics Gems IV, where a choice of axis for the // first rotation (out of 3) and 3 binary choices compactly specify all 24 // rotation conventions // // - InnerAxis: Axis for the first rotation. This is specified by struct tags // axis::X, axis::Y, and axis::Z // // - Parity: Defines the parity of the axis permutation. The axis sequence has // Even parity if the second axis of rotation is 'greater-than' the first axis // of rotation according to the order X {}; struct Y : std::integral_constant {}; struct Z : std::integral_constant {}; } // namespace axis struct Even; struct Odd; struct ProperEuler; struct TaitBryan; struct Extrinsic; struct Intrinsic; template struct EulerSystem { static constexpr bool kIsParityOdd = std::is_same_v; static constexpr bool kIsProperEuler = std::is_same_v; static constexpr bool kIsIntrinsic = std::is_same_v; static constexpr int kAxes[3] = { InnerAxisType::value, (InnerAxisType::value + 1 + static_cast(kIsParityOdd)) % 3, (InnerAxisType::value + 2 - static_cast(kIsParityOdd)) % 3}; }; } // namespace internal // Define human readable aliases to the type of the tags using ExtrinsicXYZ = internal::EulerSystem; using ExtrinsicXYX = internal::EulerSystem; using ExtrinsicXZY = internal::EulerSystem; using ExtrinsicXZX = internal::EulerSystem; using ExtrinsicYZX = internal::EulerSystem; using ExtrinsicYZY = internal::EulerSystem; using ExtrinsicYXZ = internal::EulerSystem; using ExtrinsicYXY = internal::EulerSystem; using ExtrinsicZXY = internal::EulerSystem; using ExtrinsicZXZ = internal::EulerSystem; using ExtrinsicZYX = internal::EulerSystem; using ExtrinsicZYZ = internal::EulerSystem; /* Rotating axes */ using IntrinsicZYX = internal::EulerSystem; using IntrinsicXYX = internal::EulerSystem; using IntrinsicYZX = internal::EulerSystem; using IntrinsicXZX = internal::EulerSystem; using IntrinsicXZY = internal::EulerSystem; using IntrinsicYZY = internal::EulerSystem; using IntrinsicZXY = internal::EulerSystem; using IntrinsicYXY = internal::EulerSystem; using IntrinsicYXZ = internal::EulerSystem; using IntrinsicZXZ = internal::EulerSystem; using IntrinsicXYZ = internal::EulerSystem; using IntrinsicZYZ = internal::EulerSystem; } // namespace ceres #endif // CERES_PUBLIC_INTERNAL_EULER_ANGLES_H_