package com.project.shared.utils;
import com.project.shared.data.Point2D;
public class PolygonUtils {
/**
* Returns whether edge number i in the array of a polygon edges is a
* separating edge between two polygons, given the corners of both polygons.
*
* <p>
* A separating edge is one which divides the plane such that one polygon is
* on one side and the other polygon is on the other side.
* </p>
*/
public static boolean isSeparatingEdge(Point2D[] myCorners, Point2D[] myEdges, Point2D[] otherCorners, int i)
{
int numCorners = myCorners.length;
Point2D edgeNormal = myEdges[i].getRotatedBy90Deg();
Point2D cornerOnOpposingEdge = myCorners[(i + 2) % numCorners];
Point2D edgeVertex = myCorners[i];
// Check what side of the edge a vertex of this rect belongs to
int mySide = getSideOfPointOnEdge(edgeVertex, edgeNormal, cornerOnOpposingEdge);
// Check the first corner of the other rect to see its side
int otherRectSide = getSideOfPointOnEdge(edgeVertex, edgeNormal, otherCorners[0]);
if (mySide == otherRectSide) {
// the edge is NOT a separating line, because one of our vertices
// and the other rect's vertices are on the same side.
return false;
}
for (int j = 1; j < numCorners; j++) {
if (otherRectSide != getSideOfPointOnEdge(edgeVertex, edgeNormal, otherCorners[j])) {
// the edge is NOT a separating line, because two vertices of the other rect
// are on two different sides of the edge.
return false;
}
}
return true;
}
/**
* Returns the side of a point relative to the given edge.
*/
private static int getSideOfPointOnEdge(Point2D edgeVertex, Point2D edgeNormal, Point2D testPoint) {
return Integer.signum(edgeNormal.dotProduct(testPoint.minus(edgeVertex)));
}
/**
* Returns true of the two polygons overlap.
* @See <a href="http://stackoverflow.com/questions/115426/algorithm-to-detect-intersection-of-two-rectangles">http://stackoverflow.com/questions/115426/algorithm-to-detect-intersection-of-two-rectangles</a>
*/
public static boolean areOverlapping(Point2D[] myCorners, Point2D[] otherCorners)
{
Point2D[] myEdges = PointUtils.getEdgeVectors(myCorners);
Point2D[] otherEdges = PointUtils.getEdgeVectors(otherCorners);
int numCorners = myCorners.length;
for (int i = 0; i < numCorners; i++) {
if (isSeparatingEdge(myCorners, myEdges, otherCorners, i)) {
return false;
}
if (isSeparatingEdge(otherCorners, otherEdges, myCorners, i)) {
return false;
}
}
return true;
}
}