primitives-3d_antiprism.js

import {Solid} from "../modeling";
import {Axis, Plane, Vector} from "../math";
import {Polygon, RegularPolygon} from "../primitives-2d";

/**
 * Creates an antiprism based on the specified parameters.
 * An antiprism is a polyhedron with two parallel polygonal bases connected by alternating triangular faces.
 * @memberof primitives-3D
 * @alias Antiprism
 * @param {Object} parameters - The parameters for the antiprism.
 * @param {Plane} [parameters.plane=Plane.XY] - The plane in which the antiprism is constructed.
 * @param {Vector} [parameters.center=Vector.ZERO] - The center of the antiprism.
 * @param {number} parameters.radius - The radius of the circumscribed circle of the base polygons.
 * @param {number} parameters.vertices - The number of vertices for the base polygons.
 * @returns {Solid} A `Solid` object representing the constructed antiprism.
 */
const Antiprism = ({plane = Plane.XY, center = Vector.ZERO, radius, vertices}) => {
  const faces = [];
  const sideLength = 2 * radius * Math.sin(Math.PI / vertices);
  const height = Math.sqrt(1 - Math.pow(1 / Math.cos(Math.PI / (2 * vertices)), 2) / 4) * sideLength;

  const base = RegularPolygon({
    plane: plane,
    center: center.subtract(new Vector({z: height / 2})),
    radius: radius,
    vertices: vertices,
  }).reverse();
  const baseVertices = base.vertices.map((vertex) => vertex.position);

  const top = RegularPolygon({plane: plane, center: center.add(new Vector({z: height / 2})), radius: radius, vertices: vertices}).rotate({
    axis: new Axis({
      origin: center,
      direction: plane.normal,
    }),
    angle: Math.PI / vertices,
  });
  const topVertices = top.vertices.map((vertex) => vertex.position);

  faces.push(base);
  const length = baseVertices.length;
  for (let i = 0; i < length; i++) {
    faces.push(
      Polygon({
        vertices: [baseVertices[(i + 1) % length], topVertices[i], topVertices[(i + 1) % length]],
      })
    );
    faces.push(
      Polygon({
        vertices: [topVertices[i], baseVertices[i], baseVertices[(i + 1) % topVertices.length]],
      })
    );
  }
  faces.push(top);
  return Solid.fromFaces(...faces);
};

export {Antiprism};