KinderElektro/src/main/java/de/ph87/electro/circuit/CircuitPainter.java

153 lines
5.5 KiB
Java

package de.ph87.electro.circuit;
import de.ph87.electro.circuit.node.Node;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.PartNode;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import static de.ph87.electro.CONFIG.*;
import static java.lang.Math.round;
public class CircuitPainter {
public static BufferedImage draw(final Circuit circuit, final int w, final int h) {
final BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = img.createGraphics();
draw(g, circuit, w, h);
return img;
}
public static void draw(final Graphics2D g, final Circuit circuit, final int w, final int h) {
g.setTransform(new AffineTransform());
drawBack(g, w, h);
drawParts(circuit, g);
g.setTransform(new AffineTransform());
drawRaster(g, w, h);
drawWires(circuit, g);
drawVoltages(circuit, g);
}
private static void drawBack(final Graphics2D g, final int w, final int h) {
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
}
private static void drawParts(final Circuit circuit, final Graphics2D g) {
circuit.streamParts().forEach(part -> {
g.setTransform(part.getTransform());
part.draw(g);
});
}
private static void drawRaster(final Graphics2D g, final int w, final int h) {
g.setStroke(RASTER_STROKE);
g.setColor(RASTER_COLOR);
for (int x = 0; x < w; x += RASTER) {
g.drawLine(x, 0, x, h);
}
for (int y = 0; y < h; y += RASTER) {
g.drawLine(0, y, w, y);
}
}
private static void drawWires(final Circuit circuit, final Graphics2D g) {
circuit.streamWires().forEach(wire -> wire.draw(g));
}
private static void drawVoltages(final Circuit circuit, final Graphics2D g) {
if (!SHOW_NODE_VOLTAGES && !SHOW_NODE_NAMES) {
return;
}
g.setColor(Color.BLACK);
g.setFont(LABEL_FONT);
final int third = g.getFont().getSize() / 3;
for (Part part : circuit.getParts()) {
for (final Node node : part.getNodes()) {
final Point absolute = node.getPosition();
if (SHOW_NODE_NAMES) {
int offsetY = third;
if (SHOW_NODE_VOLTAGES) {
offsetY -= third;
}
final String string = node.getName();
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g);
g.drawString(string, absolute.x - (int) (bounds.getWidth() / 2), absolute.y + offsetY);
}
if (SHOW_NODE_VOLTAGES) {
int offsetY = third;
if (SHOW_NODE_NAMES) {
offsetY += 2 * third;
}
final String string = "%.1fV".formatted(node.getVoltage());
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g);
g.drawString(string, absolute.x - (int) (bounds.getWidth() / 2), absolute.y + offsetY);
}
}
}
}
public static void drawLine(final Graphics2D g, final PartNode a, final PartNode b, final Color color, final Stroke stroke) {
drawLine(g, a.getInside(), b.getInside(), color, stroke);
}
public static void drawLine(final Graphics2D g, final PartNode a, final Point b, final Color color, final Stroke stroke) {
drawLine(g, a.getInside(), b, color, stroke);
}
public static void drawLine(final Graphics2D g, final Point a, final Point b, final Color color, final Stroke stroke) {
drawLine(g, a.x, a.y, b.x, b.y, color, stroke);
}
public static void drawLine(final Graphics2D g, final int x0, final int y0, final int x1, final int y1, final Color color, final Stroke stroke) {
g.setColor(color);
g.setStroke(stroke);
g.drawLine(x0, y0, x1, y1);
}
public static void fillRect(final Graphics2D g, final int x0, final int y0, final int x1, final int y1, final Color color) {
g.setColor(color);
g.fillRect(x0, y0, x1, y1);
}
public static void drawCircle(final Graphics2D g, final Point center, final int radius, final double degreesOffset, final double degreesRange, final Color border, final Stroke stroke, final Color fill) {
drawCircle(g, center.x, center.y, radius, border, stroke, fill, degreesOffset, degreesRange);
}
public static void drawCircle(final Graphics2D g, final int x, final int y, final int radius, final Color border, final Stroke stroke, final Color fill, final double degreesOffset, final double degreesRange) {
if (fill != null) {
g.setColor(fill);
g.fillArc(x - radius, y - radius, 2 * radius, 2 * radius, (int) round(degreesOffset), (int) round(degreesRange));
}
if (border != null && stroke != null) {
g.setColor(border);
g.setStroke(stroke);
g.drawArc(x - radius, y - radius, 2 * radius, 2 * radius, (int) round(degreesOffset), (int) round(degreesRange));
}
}
public static void drawText(final Graphics2D g, final Font font, final String text, final int x, int y, final Color color, final Orientation orientation) {
final AffineTransform transformBackup = g.getTransform();
if (orientation == Orientation.R180) {
g.rotate(orientation.getRadians(), P50, P50);
y = RASTER - y;
}
g.setFont(font);
g.setColor(color);
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);
final int xx = (int) round(x - bounds.getWidth() / 2);
final int yy = (int) round(y - bounds.getHeight() / 2 + font.getSize());
g.drawString(text, xx, yy);
g.setTransform(transformBackup);
}
}