diff --git a/modules/geometry/CMakeLists.txt b/modules/geometry/CMakeLists.txt
index 183b7f4ddda01d12a2bbdb0a4a44c644276bd310..2345bca11072a580f724ce191bc491a898f3dfb1 100644
--- a/modules/geometry/CMakeLists.txt
+++ b/modules/geometry/CMakeLists.txt
@@ -13,10 +13,14 @@ set(vkcv_geometry_sources
 		${vkcv_geometry_source}/vkcv/geometry/Geometry.cpp
 		${vkcv_geometry_include}/vkcv/geometry/Volume.hpp
 		${vkcv_geometry_source}/vkcv/geometry/Volume.cpp
+		${vkcv_geometry_include}/vkcv/geometry/Circular.hpp
+		${vkcv_geometry_source}/vkcv/geometry/Circular.cpp
 		${vkcv_geometry_include}/vkcv/geometry/Sphere.hpp
 		${vkcv_geometry_source}/vkcv/geometry/Sphere.cpp
 		${vkcv_geometry_include}/vkcv/geometry/Cuboid.hpp
 		${vkcv_geometry_source}/vkcv/geometry/Cuboid.cpp
+		${vkcv_geometry_include}/vkcv/geometry/Cylinder.hpp
+		${vkcv_geometry_source}/vkcv/geometry/Cylinder.cpp
 )
 
 # adding source files to the project
diff --git a/modules/geometry/include/vkcv/geometry/Circular.hpp b/modules/geometry/include/vkcv/geometry/Circular.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..273a6136e783eaf4005374eb80b30db974d06883
--- /dev/null
+++ b/modules/geometry/include/vkcv/geometry/Circular.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+namespace vkcv::geometry {
+	
+	/**
+     * @addtogroup vkcv_geometry
+     * @{
+     */
+	
+	class Circular {
+	private:
+		float m_radius;
+	
+	public:
+		explicit Circular(float radius);
+		
+		Circular(const Circular& other) = default;
+		Circular(Circular&& other) = default;
+		
+		~Circular() = default;
+		
+		Circular& operator=(const Circular& other) = default;
+		Circular& operator=(Circular&& other) = default;
+		
+		[[nodiscard]]
+		float getRadius() const;
+		
+		void setRadius(float radius);
+		
+	};
+	
+	/** @} */
+	
+}
\ No newline at end of file
diff --git a/modules/geometry/include/vkcv/geometry/Cylinder.hpp b/modules/geometry/include/vkcv/geometry/Cylinder.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a0a2037b5a354b3adb5d0202f52d783ab21f5cbc
--- /dev/null
+++ b/modules/geometry/include/vkcv/geometry/Cylinder.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "Circular.hpp"
+#include "Volume.hpp"
+
+namespace vkcv::geometry {
+	
+	/**
+     * @addtogroup vkcv_geometry
+     * @{
+     */
+	
+	class Cylinder : public Volume, public Circular {
+	private:
+		float m_height;
+	
+	public:
+		Cylinder(const glm::vec3& position, float height, float radius);
+		
+		Cylinder(const Cylinder& other) = default;
+		Cylinder(Cylinder&& other) = default;
+		
+		~Cylinder() = default;
+		
+		Cylinder& operator=(const Cylinder& other) = default;
+		Cylinder& operator=(Cylinder&& other) = default;
+		
+		[[nodiscard]]
+		float getHeight() const;
+		
+		void setHeight(float height);
+		
+		[[nodiscard]]
+		float distanceTo(const glm::vec3& point) override;
+		
+	};
+	
+	/** @} */
+	
+}
\ No newline at end of file
diff --git a/modules/geometry/include/vkcv/geometry/Sphere.hpp b/modules/geometry/include/vkcv/geometry/Sphere.hpp
index 8370d5030571271c4b0f801977b8945386fcafac..cf99d078f3ca4682449db9fdf061717ae71ec6d8 100644
--- a/modules/geometry/include/vkcv/geometry/Sphere.hpp
+++ b/modules/geometry/include/vkcv/geometry/Sphere.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "Circular.hpp"
 #include "Volume.hpp"
 
 namespace vkcv::geometry {
@@ -9,7 +10,7 @@ namespace vkcv::geometry {
      * @{
      */
 	
-	class Sphere : public Volume {
+	class Sphere : public Volume, public Circular {
 	private:
 		float m_radius;
 		
@@ -24,11 +25,6 @@ namespace vkcv::geometry {
 		Sphere& operator=(const Sphere& other) = default;
 		Sphere& operator=(Sphere&& other) = default;
 		
-		[[nodiscard]]
-		float getRadius() const;
-		
-		void setRadius(float radius);
-		
 		[[nodiscard]]
 		float distanceTo(const glm::vec3& point) override;
 		
diff --git a/modules/geometry/src/vkcv/geometry/Circular.cpp b/modules/geometry/src/vkcv/geometry/Circular.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..21990406bfa41d0fd5a226d9ba868acbe5578442
--- /dev/null
+++ b/modules/geometry/src/vkcv/geometry/Circular.cpp
@@ -0,0 +1,17 @@
+
+#include "vkcv/geometry/Circular.hpp"
+
+namespace vkcv::geometry {
+	
+	Circular::Circular(float radius)
+	: m_radius(radius) {}
+	
+	float Circular::getRadius() const {
+		return m_radius;
+	}
+	
+	void Circular::setRadius(float radius) {
+		m_radius = radius;
+	}
+
+}
diff --git a/modules/geometry/src/vkcv/geometry/Cylinder.cpp b/modules/geometry/src/vkcv/geometry/Cylinder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..11ba3f257d0f8bc898bb28ca087cd4e6786d2eee
--- /dev/null
+++ b/modules/geometry/src/vkcv/geometry/Cylinder.cpp
@@ -0,0 +1,36 @@
+
+#include "vkcv/geometry/Cylinder.hpp"
+
+namespace vkcv::geometry {
+	
+	Cylinder::Cylinder(const glm::vec3 &position, float height, float radius)
+	: Volume(position), Circular(radius), m_height(height) {}
+	
+	float Cylinder::getHeight() const {
+		return m_height;
+	}
+	
+	void Cylinder::setHeight(float height) {
+		m_height = height;
+	}
+	
+	float Cylinder::distanceTo(const glm::vec3 &point) {
+		const auto& position = getPosition();
+		
+		const auto verticalDistance = glm::abs(position.y - point.y) - getHeight();
+		const auto circularDistance = glm::distance(
+				glm::vec2(position.x, position.z),
+				glm::vec2(point.x, point.z)
+		) - getRadius();
+		
+		if (circularDistance <= 0.0f) {
+			return glm::max(verticalDistance, circularDistance);
+		} else
+		if (verticalDistance <= 0.0f) {
+			return circularDistance;
+		} else {
+			return glm::length(glm::vec2(verticalDistance, circularDistance));
+		}
+	}
+	
+}
diff --git a/modules/geometry/src/vkcv/geometry/Sphere.cpp b/modules/geometry/src/vkcv/geometry/Sphere.cpp
index 5b32f72d3f2023636315615519c55eab57c14ee9..a46353064e32f4f5af7e60c7767dd3505d74f204 100644
--- a/modules/geometry/src/vkcv/geometry/Sphere.cpp
+++ b/modules/geometry/src/vkcv/geometry/Sphere.cpp
@@ -4,15 +4,7 @@
 namespace vkcv::geometry {
 	
 	Sphere::Sphere(const glm::vec3& position, float radius)
-	: Volume(position), m_radius(radius) {}
-	
-	float Sphere::getRadius() const {
-		return m_radius;
-	}
-	
-	void Sphere::setRadius(float radius) {
-		m_radius = radius;
-	}
+	: Volume(position), Circular(radius) {}
 	
 	float Sphere::distanceTo(const glm::vec3 &point) {
 		return glm::distance(getPosition(), point) - getRadius();