CenterLineMacroPrimitive.java
package com.varnernet.gerb4j.macro;
import com.varnernet.gerb4j.Polarity;
import com.varnernet.gerb4j.render.GerberOutputTarget;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Gerber macro primitive type 21 — Center Line (filled rectangle). Format: {@code
* 21,exposure,width,height,centerX,centerY,rotation}
*/
final class CenterLineMacroPrimitive extends AbstractMacroPrimitive {
private final double width;
private final double height;
private final double centerX;
private final double centerY;
private final double rotation;
CenterLineMacroPrimitive(
final boolean exposed,
final double width,
final double height,
final double centerX,
final double centerY,
final double rotation) {
super(exposed);
this.width = width;
this.height = height;
this.centerX = centerX;
this.centerY = centerY;
this.rotation = rotation;
}
@Override
public Rectangle2D getBounds() {
// Conservative axis-aligned bounds; for rotated rects this over-estimates slightly.
double hw = width / 2.0;
double hh = height / 2.0;
double[][] corners = {
{centerX - hw, centerY - hh},
{centerX + hw, centerY - hh},
{centerX + hw, centerY + hh},
{centerX - hw, centerY + hh}
};
double minX = Double.MAX_VALUE;
double maxX = -Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
double maxY = -Double.MAX_VALUE;
for (double[] c : corners) {
double[] r = rotatePoint(c[0], c[1], rotation);
minX = Math.min(minX, r[0]);
maxX = Math.max(maxX, r[0]);
minY = Math.min(minY, r[1]);
maxY = Math.max(maxY, r[1]);
}
return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
}
@Override
public void render(final Point2D flashPoint, final GerberOutputTarget target, final Polarity polarity) {
double hw = width / 2.0;
double hh = height / 2.0;
double[][] local = {
{centerX - hw, centerY - hh},
{centerX + hw, centerY - hh},
{centerX + hw, centerY + hh},
{centerX - hw, centerY + hh}
};
Path2D.Double path = new Path2D.Double();
for (int i = 0; i < 4; i++) {
double[] rot = rotatePoint(local[i][0], local[i][1], rotation);
if (i == 0) {
path.moveTo(flashPoint.getX() + rot[0], flashPoint.getY() + rot[1]);
} else {
path.lineTo(flashPoint.getX() + rot[0], flashPoint.getY() + rot[1]);
}
}
path.closePath();
target.drawRegion(path, effectivePolarity(polarity));
}
}