package de.ph87.electro.circuit.part; import lombok.Getter; import lombok.ToString; import java.awt.*; import java.awt.event.MouseEvent; import static de.ph87.electro.CONFIG.RASTER; import static de.ph87.electro.CONFIG.WIRE_HOVER_STROKE_BACK; import static java.lang.Math.*; @Getter @ToString public final class Position { public static final Position ZERO = new Position(0, 0); public final Point absolute; public final Point inside; public final Point raster; public Position(final int x, final int y) { this.absolute = new Point(x, y); this.raster = new Point(x / RASTER, y / RASTER); this.inside = new Point(x % RASTER, y % RASTER); } @Override public int hashCode() { return absolute.hashCode(); } public Position(final double x, final double y) { this((int) round(x), (int) round(y)); } public Position(final Point point) { this(point.x, point.y); } public Position(final MouseEvent event) { this(event.getX(), event.getY()); } public Position plus(final Point vector) { return new Position(absolute.x + vector.x, absolute.y + vector.y); } public double distance(final Position position) { return sqrt(pow(position.absolute.x - absolute.x, 2) + pow(position.absolute.y - absolute.y, 2)); } public boolean distanceToLine(final Position lineStart, final Position lineEnd) { double dx = lineEnd.absolute.x - lineStart.absolute.x; double dy = lineEnd.absolute.y - lineStart.absolute.y; double lineLength = dx * dx + dy * dy; if (lineLength == 0) { return distance(lineStart) <= WIRE_HOVER_STROKE_BACK.getLineWidth(); } double t = ((absolute.x - lineStart.absolute.x) * dx + (absolute.y - lineStart.absolute.y) * dy) / lineLength; t = Math.max(0, Math.min(1, t)); double closestX = lineStart.absolute.x + t * dx; double closestY = lineStart.absolute.y + t * dy; final double distance = sqrt(pow(closestX - absolute.x, 2) + pow(closestY - absolute.y, 2)); return distance <= WIRE_HOVER_STROKE_BACK.getLineWidth(); } public Position alignToRaster() { return new Position(raster.x * RASTER, raster.y * RASTER); } }