2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid;
7 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
8 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
9 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon.SolidPolygon;
10 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.base.AbstractCompositeShape;
13 * A solid cylinder oriented along the Y-axis.
15 * <p>The cylinder has circular top and bottom caps connected by a curved side
16 * surface made of rectangular panels. The number of segments determines the
17 * smoothness of the curved surface.</p>
19 * <p><b>Usage example:</b></p>
21 * // Create a cylinder with radius 50, height 100, and 16 segments
22 * SolidPolygonCylinder cylinder = new SolidPolygonCylinder(
23 * new Point3D(0, 0, 200), 50, 100, 16, Color.RED);
24 * shapeCollection.addShape(cylinder);
27 * @see SolidPolygonCube
28 * @see SolidPolygonSphere
31 public class SolidPolygonCylinder extends AbstractCompositeShape {
34 * Constructs a solid cylinder centered at the given point.
36 * @param center the center point of the cylinder in 3D space.
37 * The cylinder is centered on the Y-axis, extending
38 * {@code height/2} above and below this point.
39 * @param radius the radius of the cylinder
40 * @param height the total height of the cylinder
41 * @param segments the number of segments around the circumference.
42 * Higher values create smoother cylinders. Minimum is 3.
43 * @param color the fill color applied to all polygons
45 public SolidPolygonCylinder(final Point3D center, final double radius,
46 final double height, final int segments,
50 final double halfHeight = height / 2.0;
51 final double bottomY = center.y - halfHeight;
52 final double topY = center.y + halfHeight;
54 Point3D bottomCenter = new Point3D(center.x, bottomY, center.z);
55 Point3D topCenter = new Point3D(center.x, topY, center.z);
57 Point3D[] bottomRing = new Point3D[segments];
58 Point3D[] topRing = new Point3D[segments];
60 for (int i = 0; i < segments; i++) {
61 double angle = 2.0 * Math.PI * i / segments;
62 double x = center.x + radius * Math.cos(angle);
63 double z = center.z + radius * Math.sin(angle);
64 bottomRing[i] = new Point3D(x, bottomY, z);
65 topRing[i] = new Point3D(x, topY, z);
68 for (int i = 0; i < segments; i++) {
69 int next = (i + 1) % segments;
71 addShape(new SolidPolygon(
72 new Point3D(bottomCenter.x, bottomCenter.y, bottomCenter.z),
73 new Point3D(bottomRing[i].x, bottomRing[i].y, bottomRing[i].z),
74 new Point3D(bottomRing[next].x, bottomRing[next].y, bottomRing[next].z),
77 addShape(new SolidPolygon(
78 new Point3D(topCenter.x, topCenter.y, topCenter.z),
79 new Point3D(topRing[next].x, topRing[next].y, topRing[next].z),
80 new Point3D(topRing[i].x, topRing[i].y, topRing[i].z),
83 addShape(new SolidPolygon(
84 new Point3D(bottomRing[i].x, bottomRing[i].y, bottomRing[i].z),
85 new Point3D(topRing[i].x, topRing[i].y, topRing[i].z),
86 new Point3D(bottomRing[next].x, bottomRing[next].y, bottomRing[next].z),
89 addShape(new SolidPolygon(
90 new Point3D(bottomRing[next].x, bottomRing[next].y, bottomRing[next].z),
91 new Point3D(topRing[i].x, topRing[i].y, topRing[i].z),
92 new Point3D(topRing[next].x, topRing[next].y, topRing[next].z),
96 setBackfaceCulling(true);