a926a94a88e7c110b69c25e76d372f152164573d
[sixth-3d.git] /
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.composite.solid;
6
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;
11
12 /**
13  * A solid cylinder oriented along the Y-axis.
14  *
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>
18  *
19  * <p><b>Usage example:</b></p>
20  * <pre>{@code
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);
25  * }</pre>
26  *
27  * @see SolidPolygonCube
28  * @see SolidPolygonSphere
29  * @see SolidPolygon
30  */
31 public class SolidPolygonCylinder extends AbstractCompositeShape {
32
33     /**
34      * Constructs a solid cylinder centered at the given point.
35      *
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
44      */
45     public SolidPolygonCylinder(final Point3D center, final double radius,
46                                 final double height, final int segments,
47                                 final Color color) {
48         super();
49
50         final double halfHeight = height / 2.0;
51         final double bottomY = center.y - halfHeight;
52         final double topY = center.y + halfHeight;
53
54         Point3D bottomCenter = new Point3D(center.x, bottomY, center.z);
55         Point3D topCenter = new Point3D(center.x, topY, center.z);
56
57         Point3D[] bottomRing = new Point3D[segments];
58         Point3D[] topRing = new Point3D[segments];
59
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);
66         }
67
68         for (int i = 0; i < segments; i++) {
69             int next = (i + 1) % segments;
70
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),
75                     color));
76
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),
81                     color));
82
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),
87                     color));
88
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),
93                     color));
94         }
95
96         setBackfaceCulling(true);
97     }
98 }