예제 #1
0
  // 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;
  }
예제 #2
0
  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;
  }