AbstractMacroPrimitive.java
package com.varnernet.gerb4j.macro;
import com.varnernet.gerb4j.Polarity;
/**
* Base for all concrete macro primitive implementations. Provides the exposure flag,
* polarity-inversion, and coordinate-rotation helpers used by every primitive type.
*/
abstract class AbstractMacroPrimitive implements MacroPrimitive {
/**
* {@code true} when the primitive's exposure field is 1 (add); {@code false} when 0 (subtract).
*/
protected final boolean exposed;
protected AbstractMacroPrimitive(final boolean exposed) {
this.exposed = exposed;
}
/**
* Return the effective polarity: if exposure=1 use {@code base} as-is; if exposure=0 invert it
* (CLEAR cuts into DARK and vice-versa).
*
* @param base the base polarity
* @return the effective polarity
*/
protected Polarity effectivePolarity(final Polarity base) {
if (exposed) {
return base;
}
return base == Polarity.DARK ? Polarity.CLEAR : Polarity.DARK;
}
/**
* Rotate point {@code (x, y)} counter-clockwise by {@code degrees} about the macro origin {@code
* (0, 0)}. Positive angles are CCW per the Gerber spec.
*
* @param x the x coordinate
* @param y the y coordinate
* @param degrees the rotation angle in degrees
* @return the rotated point as [x', y']
*/
protected static double[] rotatePoint(final double x, final double y, final double degrees) {
if (degrees == 0.0) {
return new double[]{x, y};
}
double r = Math.toRadians(degrees);
double c = Math.cos(r);
double s = Math.sin(r);
return new double[]{x * c - y * s, x * s + y * c};
}
}