Untitled
unknown
java
a year ago
5.4 kB
7
Indexable
Never
package com.epam.rd.autotasks.figures; class Quadrilateral extends Figure { private Point _a; private Point _b; private Point _c; private Point _d; public Quadrilateral(Point a, Point b, Point c, Point d) { // Check if the points are not null if (a == null || b == null || c == null || d == null) { throw new IllegalArgumentException("Points cannot be null"); } // Check if the points are not collinear if (collinear(a, b, c) || collinear(b, c, d) || collinear(c, d, a) || collinear(d, a, b)) { throw new IllegalArgumentException("Points cannot be collinear"); } // Check if the quadrilateral is convex if (!isConvex(a, b, c, d)) { throw new IllegalArgumentException("Quadrilateral must be convex"); } // Assign the points to the fields _a = a;_b = b; _c = c;_d = d; } public static boolean collinear(Point p1, Point p2, Point p3) { // Calculate the cross product of the vectors p1p2 and p1p3 double cross = (p2.getX() - p1.getX()) *(p3.getY() - p1.getY()) - (p2.getY() - p1.getY())* (p3.getX() - p1.getX()); // Check if the cross product is zero, which means the vectors are parallel return Math.abs(cross) < 1e-6; // Use a small tolerance to account for floating-point errors } @Override public Point centroid() { // Calculate the area of the quadrilateral using the shoelace formula double area = Math.abs((_a.getX()*_b.getY() - _b.getX()*_a.getY()) + (_b.getX()*_c.getY() - _c.getX()*_b.getY()) + (_c.getX()*_d.getY() - _d.getX()*_c.getY()) + (_d.getX()*_a.getY() - _a.getX()*_d.getY())) / 2.0; // Calculate the x and y coordinates of the centroid using the formula from https://en.wikipedia.org/wiki/Centroid#Of_a_polygon double x = (_a.getX() +_b.getX()) *(_a.getX()* _b.getY() -_b.getX() *_a.getY()) + (_b.getX() +_c.getX())*(_b.getX()*_c.getY() -_c.getX()*_b.getY()) + (_c.getX() +_d.getX())*(_c.getX()*_d.getY() -_d.getX()*_c.getY()) + (_d.getX() +_a.getX())*(_d.getX()*_a.getY() -_a.getX()*_d.getY()); x = x / (6.0*area); double y = (_a.getY() +_b.getY())*(_a.getX()*_b.getY() -_b.getX()*_a.getY()) + (_b.getY() +_c.getY())*(_b.getX()*_c.getY() -_c.getX()*_b.getY()) + (_c.getY() +_d.getY())*(_c.getX()*_d.getY() -_d.getX()*_c.getY()) + (_d.getY() +_a.getY())*(_d.getX()*_a.getY() -_a.getX()*_d.getY()); y = y / (6.0*area); // Return a new point with the calculated coordinates return new Point(-x, -y); } @Override public boolean isTheSame(Figure figure) { // Check if the figure is not null and is a quadrilateral if (figure == null || !(figure instanceof Quadrilateral)) { return false; } // Cast the figure to a quadrilateral Quadrilateral quad = (Quadrilateral) figure; // Define a small tolerance value for comparing doubles double epsilon = 1e-6; // Check if the four points of this quadrilateral are equal to the four points of the other quadrilateral // Note: order of the vertices does not matter return (equals(this._a, quad._a, epsilon) || equals(this._a, quad._b, epsilon) || equals(this._a, quad._c, epsilon) || equals(this._a, quad._d, epsilon)) && (equals(this._b, quad._a, epsilon) || equals(this._b, quad._b, epsilon) || equals(this._b, quad._c, epsilon) || equals(this._b, quad._d, epsilon)) && (equals(this._c, quad._a, epsilon) || equals(this._c, quad._b, epsilon) || equals(this._c, quad._c, epsilon) || equals(this._c, quad._d, epsilon)) && (equals(this._d, quad._a, epsilon) || equals(this._d, quad._b, epsilon) || equals(this._d, quad._c, epsilon) || equals(this._d, quad._d, epsilon)); } // A helper method to check if two points are equal using a tolerance value private boolean equals(Point p1, Point p2, double epsilon) { // Check if the x and y coordinates of the points are within the tolerance range return Math.abs(p1.getX() - p2.getX()) <= epsilon && Math.abs(p1.getY() - p2.getY()) <= epsilon; } // A helper method to check if a quadrilateral is convex using the cross product of consecutive edges private boolean isConvex(Point a, Point b, Point c, Point d) { // Calculate the vectors of the four edges Point ab = new Point(b.getX() - a.getX(), b.getY() - a.getY()); Point bc = new Point(c.getX() - b.getX(), c.getY() - b.getY()); Point cd = new Point(d.getX() - c.getX(), d.getY() - c.getY()); Point da = new Point(a.getX() - d.getX(), a.getY() - d.getY()); // Calculate the cross products of the consecutive edges double cross1 = ab.getX() *bc.getY() - ab.getY()* bc.getX(); double cross2 = bc.getX() *cd.getY() - bc.getY()* cd.getX(); double cross3 = cd.getX() *da.getY() - cd.getY()* da.getX(); double cross4 = da.getX() *ab.getY() - da.getY()* ab.getX(); // Check if the signs of the cross products are the same return (cross1 > 0 && cross2 > 0 && cross3 > 0 && cross4 > 0) || (cross1 < 0 && cross2 < 0 && cross3 < 0 && cross4 < 0); } }