Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 09:06:15

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/transform/TransformSimplifier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "orange/OrangeTypes.hh"
0011 
0012 #include "VariantTransform.hh"
0013 
0014 namespace celeritas
0015 {
0016 //---------------------------------------------------------------------------//
0017 /*!
0018  * Return a simplified version of a transformation.
0019  *
0020  * Like surface simplification, we want to consider whether two different
0021  * transformations will result in a distance change of \f$\epsilon\f$ for a
0022  * point that's at the length scale from the origin. Setting the length scale
0023  * to unity (the default), we use the relative tolerance.
0024  *
0025  * A *translation* can be deleted if its magnitude is less than epsilon.
0026  *
0027  * For a translation, we use the fact that the trace (sum of diagonal elements)
0028  * of any proper (non-reflecting) rotation matrix has an angle of rotation \f[
0029    \mathrm{Tr}[R] = 2 \cos \theta + 1
0030  * \f] about an axis of rotation. Applying the rotation to a point
0031  * at a unit distance will yield an iscoceles triangle with sides 1 and inner
0032  * angle \f$\theta\f$. For the displacement to be no more than \f$\epsilon\f$
0033  * then the angle must be \f[
0034   \sin \theta/2 \le \epsilon/2
0035   \f]
0036  * which with some manipulation means that a "soft zero" rotation has a trace
0037  * \f[
0038  \mathrm{Tr}[R] \ge 3 - \epsilon^2 \,.
0039  \f]
0040  *
0041  * Note that this means no rotational simplifications may be performed when the
0042  * geometry tolerance is less than the square root of machine precision.
0043  */
0044 class TransformSimplifier
0045 {
0046   public:
0047     // Construct with tolerance
0048     explicit inline TransformSimplifier(Tolerance<> const& tol);
0049 
0050     //! No simplification can be applied to a null transformation
0051     VariantTransform operator()(NoTransformation const& nt) { return nt; }
0052 
0053     // Translation may simplify to no transformation
0054     VariantTransform operator()(Translation const& nt);
0055 
0056     // Simplify, possibly to translation or no transform
0057     VariantTransform operator()(Transformation const& nt);
0058 
0059   private:
0060     real_type eps_;
0061 };
0062 
0063 //---------------------------------------------------------------------------//
0064 // INLINE DEFINITIONS
0065 //---------------------------------------------------------------------------//
0066 /*!
0067  * Construct with tolerance.
0068  */
0069 TransformSimplifier::TransformSimplifier(Tolerance<> const& tol)
0070     : eps_{tol.rel}
0071 {
0072     CELER_EXPECT(tol);
0073 }
0074 
0075 //---------------------------------------------------------------------------//
0076 }  // namespace celeritas