PolygonAperture.java

package com.varnernet.gerb4j;

import com.varnernet.gerb4j.render.GerberOutputTarget;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 * A regular polygon aperture (Gerber {@code P} standard aperture template).
 *
 * <p>Defined by an outer diameter, vertex count, rotation angle, and optional hole diameter.
 */
public final class PolygonAperture extends Aperture {
    private final double outerDiameter;
    private final int vertices;
    private final double rotation;
    private final double holeDiameter;

    /**
     * Creates a new polygon aperture.
     *
     * @param id            the aperture identifier
     * @param outerDiameter the outer diameter of the polygon
     * @param vertices      the number of vertices
     * @param rotation      the rotation angle in degrees
     * @param holeDiameter  the diameter of the optional hole (0.0 for no hole)
     */
    public PolygonAperture(
            final String id,
            final String outerDiameter,
            final String vertices,
            final String rotation,
            final String holeDiameter) {
        super(id);
        this.outerDiameter = Double.parseDouble(outerDiameter);
        this.vertices = (int) Double.parseDouble(vertices);
        this.rotation = (rotation == null) ? 0.0 : Double.parseDouble(rotation);
        this.holeDiameter = (holeDiameter == null) ? 0.0 : Double.parseDouble(holeDiameter);
    }

    /**
     * Returns the outer diameter of the polygon.
     *
     * @return the outer diameter
     */
    public double getDiameter() {
        return outerDiameter;
    }

    /**
     * Returns the number of vertices in the polygon.
     *
     * @return the number of vertices
     */
    public int getNumVertices() {
        return vertices;
    }

    /**
     * Returns the rotation angle of the polygon in degrees.
     *
     * @return the rotation angle
     */
    public double getRotation() {
        return rotation;
    }

    /**
     * Returns the diameter of the optional hole.
     *
     * @return the hole diameter (0.0 if no hole)
     */
    public double getHoleDiameter() {
        return holeDiameter;
    }

    /**
     * Bounds centred at (0,0) — circumscribed circle of the polygon.
     */
    @Override
    public Rectangle2D getBounds() {
        double r = outerDiameter / 2.0;
        return new Rectangle2D.Double(-r, -r, outerDiameter, outerDiameter);
    }

    @Override
    public void render(final Point2D flashPoint, final GerberOutputTarget target, final Polarity polarity) {
        target.drawPolygon(flashPoint, vertices, outerDiameter, rotation, polarity);
        if (holeDiameter > 0) {
            target.drawCircle(flashPoint, holeDiameter, 0.0, invertPolarity(polarity));
        }
    }
}