106 lines
3.1 KiB
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);
|
|
}
|
|
|
|
}
|