KinderElektro/src/main/java/de/ph87/electro/circuit/wire/Wire.java

106 lines
3.1 KiB
Java

package de.ph87.electro.circuit.wire;
import de.ph87.electro.circuit.part.node.Node;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import static de.ph87.electro.CONFIG.*;
import static java.lang.Math.*;
@Getter
@ToString
public class Wire {
@NonNull
private final Node a;
@NonNull
private final Node b;
@Setter
private double current = Double.NaN;
@Setter
private boolean ghost = false;
public Wire(@NonNull final Node a, @NonNull final Node b) {
this.a = a;
this.b = b;
a.getWires().add(this);
b.getWires().add(this);
}
public boolean intersects(final Point position) {
return distanceToLine(position, a.getPosition(), b.getPosition());
}
public boolean distanceToLine(final Point point, final Point lineStart, final Point lineEnd) {
double dx = lineEnd.x - lineStart.x;
double dy = lineEnd.y - lineStart.y;
double lineLength = dx * dx + dy * dy;
if (lineLength == 0) {
return sqrt(pow(lineStart.x - point.x, 2) + pow(lineStart.y - point.y, 2)) <= WIRE_HOVER_STROKE_BACK.getLineWidth();
}
double t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / lineLength;
t = Math.max(0, Math.min(1, t));
double closestX = lineStart.x + t * dx;
double closestY = lineStart.y + t * dy;
final double distance = sqrt(pow(closestX - point.x, 2) + pow(closestY - point.y, 2));
return distance <= WIRE_HOVER_STROKE_BACK.getLineWidth();
}
public Node getOpposite(final Node node) {
if (a == node) {
return b;
} else if (b == node) {
return a;
}
throw new RuntimeException();
}
public double getCurrent(final Node node) {
return node == a ? current : -current;
}
public void draw(final Graphics2D g) {
final Color color = ghost ? new Color(a.getColor().getRed(), a.getColor().getGreen(), a.getColor().getBlue(), 64) : a.getColor();
g.setColor(color);
g.setStroke(WIRE_STROKE);
g.drawLine(a.getPosition().x, a.getPosition().y, b.getPosition().x, b.getPosition().y);
if (SHOW_WIRE_DETAILS) {
drawValues(g, "%.2f A".formatted(abs(current)), -0.5);
drawValues(g, "%.2f V".formatted(a.getVoltage()), +0.5);
}
}
private void drawValues(final Graphics2D g, final String string, final double offset) {
g.setFont(LABEL_FONT);
final Rectangle2D bounds = g.getFontMetrics().getStringBounds(string, g);
final Point aa = a.getPosition();
final Point bb = b.getPosition();
final int mx = (aa.x + bb.x) / 2;
final int my = (aa.y + bb.y) / 2;
final int bx = (int) round((mx - bounds.getWidth() / 2)) - 2;
final int by = (int) round((my - bounds.getHeight() / 2) + offset * bounds.getHeight()) - 2;
g.setColor(new Color(255, 255, 255, 200));
g.fillRect(bx, by, (int) round(bounds.getWidth()) + 4, (int) round(bounds.getHeight()) + 4);
final int sx = (int) round((mx - bounds.getWidth() / 2));
final int sy = (int) round(my + bounds.getHeight() / 3 + offset * bounds.getHeight());
g.setColor(a.getColor());
g.drawString(string, sx, sy);
}
}