/*////////////////////////////////////////////////////////////////////////////// // CMT Cosmic Muon Tomography project ////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova All rights reserved Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it > ------------------------------------------------------------------ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. //////////////////////////////////////////////////////////////////////////////*/ #ifndef U_CYLINDER_H #define U_CYLINDER_H #include "Geometry.h" #include "Core/Object.h" #include "Math/Dense.h" #include "Math/Transform.h" namespace uLib { /** * @brief Represents a cylindrical volume centered in the base circle. * * Cylinder inherits from AffineTransform, which defines its parent * coordinate system. It contains an internal local transformation (m_LocalT) * that defines the cylinder's actual volume (radius and height) * relative to the emitter's origin (base circle center). */ class Cylinder : public AffineTransform, public Object { typedef AffineTransform BaseClass; public: virtual const char * GetClassName() const { return "Cylinder"; } /** * @brief Default constructor. * Initializes with radius 1 and height 1. */ Cylinder() : m_LocalT(this), m_Radius(1.0), m_Height(1.0) { UpdateLocalMatrix(); } /** * @brief Constructor with radius and height. */ Cylinder(float radius, float height) : m_LocalT(this), m_Radius(radius), m_Height(height) { UpdateLocalMatrix(); } /** * @brief Copy constructor. */ Cylinder(const Cylinder ©) : m_LocalT(this), AffineTransform(copy) { this->SetRadius(copy.GetRadius()); this->SetHeight(copy.GetHeight()); } /** Sets the radius of the cylinder */ inline void SetRadius(float r) { m_Radius = r; UpdateLocalMatrix(); } /** Gets the radius of the cylinder */ inline float GetRadius() const { return m_Radius; } /** Sets the height of the cylinder */ inline void SetHeight(float h) { m_Height = h; UpdateLocalMatrix(); } /** Gets the height of the cylinder */ inline float GetHeight() const { return m_Height; } /** * @brief Returns the world transformation matrix of the cylinder's volume. */ Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } /** * @brief Returns the local transformation matrix of the cylinder's volume. */ Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); } /** * @brief Transforms local cylindrical coordinates to world space. * @param r Local radius (absolute). * @param theta Local angle in radians. * @param z Local height (absolute, relative to base circle). * @return Transformed point in world space. */ inline Vector4f GetWorldPoint(float r, float theta, float z) const { return BaseClass::GetWorldMatrix() * Vector4f(r * std::cos(theta), r * std::sin(theta), z, 1.0f); } /** * @brief Transforms a world point to cylindrical local space. * @return Vector3f(r, theta, z) */ inline Vector3f GetCylindricalLocal(const Vector4f &world_v) const { Vector4f local_v = BaseClass::GetWorldMatrix().inverse() * world_v; float r = std::sqrt(local_v.x() * local_v.x() + local_v.y() * local_v.y()); float theta = std::atan2(local_v.y(), local_v.x()); return Vector3f(r, theta, local_v.z()); } signals: /** Signal emitted when the cylinder geometry or transform is updated */ virtual void Updated() override { ULIB_SIGNAL_EMIT(Cylinder::Updated); } private: /** Recalculates the internal local matrix based on radius and height */ void UpdateLocalMatrix() { m_LocalT = AffineTransform(this); // BaseClass is parent m_LocalT.Scale(Vector3f(m_Radius, m_Radius, m_Height)); this->Updated(); } float m_Radius; float m_Height; AffineTransform m_LocalT; }; } // namespace uLib #endif // U_CYLINDER_H