Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:31

0001 #ifndef Geom_Plane_H
0002 #define Geom_Plane_H
0003 
0004 /** \class Plane
0005  *
0006  *  A plane in 3D space.
0007  *  
0008  *  \warning Surfaces are reference counted, so only ReferenceCountingPointer
0009  *  should be used to point to them. For this reason, they should be 
0010  *  using the static build() method. 
0011  *  (The normal constructor will become private in the future).
0012  */
0013 
0014 #include "DataFormats/GeometrySurface/interface/Surface.h"
0015 
0016 class Plane : public Surface {
0017 public:
0018   template <typename... Args>
0019   Plane(Args&&... args) : Surface(std::forward<Args>(args)...) {
0020     setPosPrec();
0021     computeSpan();
0022   }
0023 
0024   using PlanePointer = ReferenceCountingPointer<Plane>;
0025   using ConstPlanePointer = ConstReferenceCountingPointer<Plane>;
0026   using BoundPlanePointer = ReferenceCountingPointer<Plane>;
0027   using ConstBoundPlanePointer = ConstReferenceCountingPointer<Plane>;
0028 
0029   /// Construct a Plane.
0030   /// The reference frame is defined by pos and rot; the plane is
0031   /// orthogonal to the local Z axis.
0032   template <typename... Args>
0033   static PlanePointer build(Args&&... args) {
0034     return PlanePointer(new Plane(std::forward<Args>(args)...));
0035   }
0036 
0037   ~Plane() override {}
0038 
0039   // extension of Surface interface for planes
0040 
0041   GlobalVector normalVector() const { return GlobalVector(rotation().z()); }
0042 
0043   /// Fast access to distance from plane for a point.
0044   /// return 0 if too close
0045   float localZ(const GlobalPoint& gp) const { return normalVector().dot(gp - position()); }
0046 
0047   float localZclamped(const GlobalPoint& gp) const {
0048     auto d = localZ(gp);
0049     return std::abs(d) > posPrec() ? d : 0;
0050   }
0051 
0052   /// Fast access to component perpendicular to plane for a vector.
0053   float localZ(const GlobalVector& gv) const { return normalVector().dot(gv); }
0054 
0055   // precision on position
0056   float posPrec() const { return m_posPrec; }
0057 
0058   void computeSpan() {
0059     if (theBounds)
0060       theBounds->computeSpan(*this);
0061   }
0062 
0063   // implementation of Surface interface
0064 
0065   SurfaceOrientation::Side side(const LocalPoint& p, Scalar toler) const final {
0066     return (std::abs(p.z()) < toler)
0067                ? SurfaceOrientation::onSurface
0068                : (p.z() > 0 ? SurfaceOrientation::positiveSide : SurfaceOrientation::negativeSide);
0069   }
0070 
0071   SurfaceOrientation::Side side(const GlobalPoint& p, Scalar toler) const final {
0072     Scalar lz = localZ(p);
0073     return (std::abs(lz) < toler ? SurfaceOrientation::onSurface
0074                                  : (lz > 0 ? SurfaceOrientation::positiveSide : SurfaceOrientation::negativeSide));
0075   }
0076 
0077   /// tangent plane to surface from global point
0078   ConstReferenceCountingPointer<TangentPlane> tangentPlane(const GlobalPoint&) const final;
0079 
0080   /// tangent plane to surface from local point
0081   ConstReferenceCountingPointer<TangentPlane> tangentPlane(const LocalPoint&) const final;
0082 
0083 private:
0084   void setPosPrec() {
0085     constexpr auto maxf = std::numeric_limits<float>::max();
0086     auto p = position();
0087     float l = std::max(std::max(std::abs(p.x()), std::abs(p.y())), std::abs(p.z()));
0088     m_posPrec = std::abs(
0089         l - ::nextafterf(l, maxf));  //  LSB  (can be multiplied by 4 or divided by 4 for safety depending on usage)
0090   }
0091 
0092   Scalar m_posPrec;  // the precision on the actual global position
0093 };
0094 using BoundPlane = Plane;
0095 
0096 #endif