KinderElektro/src/main/java/de/ph87/electro/circuit/part/Position.java

78 lines
2.1 KiB
Java

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);
}
}