package model; public class CollisionDetector { public static boolean figuresCollide(MovingFigure f1, MovingFigure f2) { if(f1 instanceof MovingCircle && f2 instanceof MovingCircle) return circlesCollide( (MovingCircle) f1, (MovingCircle) f2); if(f1 instanceof MovingSquare && f2 instanceof MovingSquare) return squaresCollide( (MovingSquare) f1, (MovingSquare) f2); if(f1 instanceof MovingCircle && f2 instanceof MovingSquare) return circleAndSquareCollide((MovingCircle) f1, (MovingSquare) f2); if(f1 instanceof MovingSquare && f2 instanceof MovingCircle) return circleAndSquareCollide((MovingCircle) f2, (MovingSquare) f1); else throw new IllegalArgumentException("Unsupported classes"); } private static boolean circlesCollide(MovingCircle c1, MovingCircle c2){ float centerDistance = distanceBetweenPoints(c1.getPosX(), c1.getPosY(), c2.getPosX(), c2.getPosY()); float radiusDistance = c1.getRadius() + c2.getRadius(); return centerDistance <= radiusDistance; } private static boolean squaresCollide(MovingSquare s1, MovingSquare s2) { if( s1.getPosY2() < s2.getPosY() ) return false; if( s1.getPosX2() < s2.getPosX() ) return false; if( s1.getPosY() > s2.getPosY2() ) return false; if( s1.getPosX() > s2.getPosX2() ) return false; return true; } private static boolean circleAndSquareCollide(MovingCircle c, MovingSquare s) { int x1 = s.getPosX(); int y1 = s.getPosY(); int x2 = s.getPosX2(); int y2 = s.getPosY2(); if( c.getPosX() > x1 && c.getPosX() < x2 && c.getPosY() > y1 && c.getPosY() < y2) return true; if( lineIntersectsWithCircle(x1, y1, x2, y1, c)) return true; if( lineIntersectsWithCircle(x2, y1, x2, y2, c)) return true; if( lineIntersectsWithCircle(x1, y2, x2, y2, c)) return true; if( lineIntersectsWithCircle(x1, y1, x1, y2, c)) return true; return false; } private static float distanceBetweenPoints(int posX1, int posY1, int posX2, int posY2) { int dx = posX2 - posX1; int dy = posY2 - posY1; int d2 = dx*dx + dy*dy; return (float) Math.sqrt((int) d2); } private static boolean lineIntersectsWithCircle(int x1, int y1, int x2, int y2, MovingCircle c) { int dx = x2 - x1; int dy = y2 - y1; dx -= c.getPosX(); //offset dy -= c.getPosY(); //offset double dr = Math.sqrt(dx*dx + dy*dy); double D = x1*y2 - x2*y1; double incidence = Math.pow(c.getRadius(), 2) * Math.pow(dr, 2) - Math.pow(D, 2); // r²dr² - D² return incidence >= 0; } private static int sgn(int x) { if ( x < 0 ) return -1; return 1; } }