package holeg.utility.math.vector; import static holeg.utility.math.Maths.EPSILON; import holeg.utility.math.Maths; import java.awt.Rectangle; import java.util.Optional; public class Geometry { public static Rectangle createRectangleFromCorners(Vec2i corner, Vec2i otherCorner) { //Calculate left top corner, width, height Vec2i topLeft = new Vec2i(Math.min(corner.getX(), otherCorner.getX()), Math.min(corner.getY(), otherCorner.getY())); Vec2i bottomRight = new Vec2i(Math.max(corner.getX(), otherCorner.getX()), Math.max(corner.getY(), otherCorner.getY())); int width = bottomRight.getX() - topLeft.getX(); int height = bottomRight.getY() - topLeft.getY(); return new Rectangle(topLeft.getX(), topLeft.getY(), width, height); } public static Optional getProjectionOnSegmentIfInRange(Line line, Circle circle) { float lineLengthSqr = line.distanceSqr(); if (lineLengthSqr < EPSILON) { if (line.p1.getSquaredDistance(circle.position) < circle.radius * circle.radius) { return Optional.of(new Vec2f(line.p1)); } else { return Optional.empty(); } } Vec2f p2p1 = line.p2.subtract(line.p1); float t = Maths.clamp(Vec2f.dot(circle.position.subtract(line.p1), p2p1) / lineLengthSqr, 0.0f, 1.0f); Vec2f projection = line.p1.add(p2p1.multiply(t)); if (projection.getSquaredDistance(circle.position) < circle.radius * circle.radius) { return Optional.of(projection); } else { return Optional.empty(); } } public static class Circle { public Vec2f position; public float radius; public Circle(Vec2f position, float radius) { this.position = position; this.radius = radius; } } public static class Line { Vec2f p1; Vec2f p2; public Line(Vec2f p1, Vec2f p2) { this.p1 = p1; this.p2 = p2; } float distanceSqr() { return p1.getSquaredDistance(p2); } } }