Untitled
unknown
java
2 years ago
5.4 kB
15
Indexable
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);
}
}
Editor is loading...