123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- 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;
- /**
- * A helper class for geometric shapes and operations.
- */
- public class Geometry {
- /**
- * Construct a Rectangle with only the points from two corners.
- * The Rectangle is axis aligned.
- * The ordering of the corner is irrelevant.
- * @param corner a corner of the Rectangle
- * @param otherCorner another corner of the Rectangle
- * @return the corresponding rectangle
- */
- 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);
- }
- /**
- * If the line Intersect the circle the projection is returned.
- * @param line the 2d line
- * @param circle the 2d circle
- * @return the projection
- */
- public static Optional<Vec2f> getProjectionOnSegmentIfInRange(Line line, Circle circle) {
- float lineLengthSqr = line.lengthSqr();
- if (lineLengthSqr < EPSILON) {
- if (line.p1.getDistanceSqr(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.getDistanceSqr(circle.position) < circle.radius * circle.radius) {
- return Optional.of(projection);
- } else {
- return Optional.empty();
- }
- }
- /**
- * A simple representation of a 2d circle via a center point and a radius.
- */
- public static class Circle {
- /**
- * The center of the circle.
- */
- public Vec2f position;
- /**
- * The radius of the circle.
- */
- public float radius;
- /**
- * Construct the circle with a center point and a radius.
- * @param position center of the circle
- * @param radius radius of the circle
- */
- public Circle(Vec2f position, float radius) {
- this.position = position;
- this.radius = radius;
- }
- }
- /**
- * A simple representation of a 2D-line via two points.
- */
- public static class Line {
- /**
- * First point
- */
- Vec2f p1;
- /**
- * Second Point
- */
- Vec2f p2;
- /**
- * Construct a line via two points.
- *
- * @param p1 first point
- * @param p2 second point
- */
- public Line(Vec2f p1, Vec2f p2) {
- this.p1 = p1;
- this.p2 = p2;
- }
- /**
- * Returns the squared length of the line.
- *
- * @return the squared length of the line
- */
- float lengthSqr() {
- return p1.getDistanceSqr(p2);
- }
- }
- }
|