/
shvidkuli
/
kkrjava
Обзор
Документация
Войти
/
shvidkuli
/
kkrjava
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main/java/com/montecarlo/geometry/Triangle.java
99 строк
3 KB
kroc400
first_commit
30 апр 2026, 22:44
30 апр 2026, 22:44
2347fdb
Код
Авторство
О чём код?
package com.montecarlo.geometry; /** * A filled triangle defined by three vertices in 2D space. * * <p>Point containment is tested with the cross-product (half-plane) method: * a point lies inside (or on the boundary of) the triangle if all three * signed cross products {@code (edge × point)} have the same sign (or are zero).</p> */ public class Triangle implements Shape { private final Point p1; private final Point p2; private final Point p3; /** * Constructs a Triangle with the given three vertices. * Vertex order (clockwise or counterclockwise) does not matter. * * @param p1 first vertex * @param p2 second vertex * @param p3 third vertex */ public Triangle(Point p1, Point p2, Point p3) { this.p1 = p1; this.p2 = p2; this.p3 = p3; } /** @return first vertex */ public Point getP1() { return p1; } /** @return second vertex */ public Point getP2() { return p2; } /** @return third vertex */ public Point getP3() { return p3; } /** * Signed cross product of edge vector A→B and vector A→P. * Positive means P is to the left of A→B; negative means to the right. */ private double cross(Point a, Point b, Point p) { return (b.getX() - a.getX()) * (p.getY() - a.getY()) - (b.getY() - a.getY()) * (p.getX() - a.getX()); } /** * Returns {@code true} if point {@code p} is inside or on the boundary of this triangle. * * <p>Uses the sign-consistency of cross products: a point is inside iff the signs of * cross(p1,p2,p), cross(p2,p3,p), cross(p3,p1,p) are all non-negative or all * non-positive (allowing zeros for boundary points).</p> * * @param p the point to test * @return {@code true} if inside or on the boundary */ @Override public boolean contains(Point p) { double d1 = cross(p1, p2, p); double d2 = cross(p2, p3, p); double d3 = cross(p3, p1, p); boolean hasNeg = (d1 < 0) || (d2 < 0) || (d3 < 0); boolean hasPos = (d1 > 0) || (d2 > 0) || (d3 > 0); return !(hasNeg && hasPos); } /** * Returns the area of this triangle using the shoelace formula. * * @return non-negative area */ @Override public double analyticalArea() { return 0.5 * Math.abs( (p2.getX() - p1.getX()) * (p3.getY() - p1.getY()) - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) ); } /** * Returns the smallest axis-aligned bounding box enclosing this triangle. * * @return the bounding box */ @Override public BoundingBox getBoundingBox() { double minX = Math.min(p1.getX(), Math.min(p2.getX(), p3.getX())); double minY = Math.min(p1.getY(), Math.min(p2.getY(), p3.getY())); double maxX = Math.max(p1.getX(), Math.max(p2.getX(), p3.getX())); double maxY = Math.max(p1.getY(), Math.max(p2.getY(), p3.getY())); return new BoundingBox(minX, minY, maxX, maxY); } @Override public String toString() { return String.format("Triangle(%s, %s, %s)", p1, p2, p3); } }