// implementation of Seperating Axis Theorem public boolean intersects(Rectangle b) { ArrayList<Vector2d> aAxes = getEdgeNormals(); ArrayList<Vector2d> bAxes = b.getEdgeNormals(); for (int i = 0; i < aAxes.size(); i++) { Vector2d p1 = project(aAxes.get(i)); Vector2d p2 = b.project(aAxes.get(i)); if ((p1.x > p2.y || p2.x > p1.y)) // if they overlap they are intersecting on this axis return false; } for (int i = 0; i < bAxes.size(); i++) { Vector2d p1 = project(bAxes.get(i)); Vector2d p2 = b.project(bAxes.get(i)); if ((p1.x > p2.y || p2.x > p1.y)) // if they overlap they are intersecting on this axis return false; } return true; }
public Vector2d intersect(Rectangle b) { double overlap = Double.MAX_VALUE; // depth Vector2d collisionNormal = null; // minimum penetration vector or collision normal ArrayList<Vector2d> aAxes = getEdgeNormals(); ArrayList<Vector2d> bAxes = b.getEdgeNormals(); for (int i = 0; i < aAxes.size(); i++) { Vector2d p1 = project(aAxes.get(i)); Vector2d p2 = b.project(aAxes.get(i)); if ((p1.x > p2.y || p2.x > p1.y)) // if they overlap they are intersecting on this axis return null; else { double o = Math.min(p1.y, p2.y) - Math.max(p1.x, p2.x); if (o < overlap) { overlap = o; collisionNormal = aAxes.get(i); } } } for (int i = 0; i < bAxes.size(); i++) { Vector2d p1 = project(bAxes.get(i)); Vector2d p2 = b.project(bAxes.get(i)); if ((p1.x > p2.y || p2.x > p1.y)) // if they overlap they are intersecting on this axis return null; else { double o = Math.min(p1.y, p2.y) - Math.max(p1.x, p2.x); if (o < overlap) { overlap = o; collisionNormal = bAxes.get(i); } } } // collision normal and penetration depth has been found // now we find the most perpendicular edges to the collision normal Line aEdge = bestEdge(collisionNormal); Line bEdge = b.bestEdge(new Vector2d(-collisionNormal.x, -collisionNormal.y)); // determine reference and incident edges Line reference, incident; Vector2d ref; boolean flipped = false; if (aEdge.toVector2d().dot(collisionNormal) <= bEdge.toVector2d().dot(collisionNormal)) { reference = aEdge; incident = bEdge; } else { reference = bEdge; incident = aEdge; flipped = true; } ref = reference.toVector2d().normalize(); double offset1 = ref.dot(reference.getPoint1()); ArrayList<Vector2d> clipPoints = clip(incident.getPoint1(), incident.getPoint2(), new Vector2d(-ref.x, -ref.y), -offset1); if (clipPoints.size() < 2) return null; System.out.println("clip1 success"); double offset2 = ref.dot(reference.getPoint2()); clipPoints = clip(clipPoints.get(0), clipPoints.get(1), ref, offset2); if (clipPoints.size() < 2) return null; System.out.println("clip2 success"); Vector2d refNormal = ref.getLeftNormal(); if (flipped) refNormal = new Vector2d(refNormal.x * -1, refNormal.y * -1); double max = refNormal.dot(reference.getPoint1()); if (refNormal.dot(clipPoints.get(0)) - max < 0.0) { clipPoints.remove(clipPoints.get(0)); if (!clipPoints.isEmpty()) if (refNormal.dot(clipPoints.get(0)) - max < 0.0) clipPoints.remove(clipPoints.get(0)); } if (!clipPoints.isEmpty()) { Vector2d collision = new Vector2d(0, 0); for (int i = 0; i < clipPoints.size(); i++) { collision = new Vector2d(collision.x + clipPoints.get(i).x, collision.y + clipPoints.get(i).y); } collision = new Vector2d(collision.x / clipPoints.size(), collision.y / clipPoints.size()); return collision; } else return null; }