function rerouteLine()

in public/bubblesets.js [1287:1385]


  function rerouteLine(rectangle, rerouteBuffer, intersections, wrapNormal) {
    var topIntersect = intersections[0];
    var leftIntersect = intersections[1];
    var bottomIntersect = intersections[2];
    var rightIntersect = intersections[3];

    // wrap around the most efficient way
    if(wrapNormal) {
      // left side
      if(leftIntersect.getState() === Intersection.POINT) {
        if(topIntersect.getState() === Intersection.POINT) // triangle, must go around top left
          return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
        if(bottomIntersect.getState() === Intersection.POINT) // triangle, must go around bottom left
          return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
        // else through left to right, calculate areas
        var totalArea = rectangle.height() * rectangle.width();
        // top area
        var topArea = rectangle.width() * (((leftIntersect.getPoint().y() - rectangle.minY())
                    + (rightIntersect.getPoint().y() - rectangle.minY())) * 0.5);
        if(topArea < totalArea * 0.5) {
          // go around top (the side which would make a greater movement)
          if(leftIntersect.getPoint().y() > rightIntersect.getPoint().y()) // top left
            return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
          // top right
          return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
        }
        // go around bottom
        if(leftIntersect.getPoint().y() < rightIntersect.getPoint().y()) // bottom left
          return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
        // bottom right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      }
      // right side
      if(rightIntersect.getState() === Intersection.POINT) {
        if(topIntersect.getState() === Intersection.POINT) // triangle, must go around top right
          return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
        if(bottomIntersect.getState() === Intersection.POINT) // triangle, must go around bottom right
          return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      }
      // else through top to bottom, calculate areas
      var totalArea = rectangle.height() * rectangle.width();
      var leftArea = rectangle.height() * (((topIntersect.getPoint().x() - rectangle.minX()) + (bottomIntersect.getPoint().x() - rectangle.minX())) * 0.5);
      if(leftArea < totalArea * 0.5) {
        // go around left
        if(topIntersect.getPoint().x() > bottomIntersect.getPoint().x()) // top left
          return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
        // bottom left
        return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      }
      // go around right
      if(topIntersect.getPoint().x() < bottomIntersect.getPoint().x()) // top right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
      // bottom right
      return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
    }
    // wrap around opposite (usually because the first move caused a problem)
    if(leftIntersect.getState() === Intersection.POINT) {
      if(topIntersect.getState() === Intersection.POINT) // triangle, must go around bottom right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      if(bottomIntersect.getState() === Intersection.POINT) // triangle, must go around top right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
      // else through left to right, calculate areas
      var totalArea = rectangle.height() * rectangle.width();
      var topArea = rectangle.width() * (((leftIntersect.getPoint().y() - rectangle.minY()) + (rightIntersect.getPoint().y() - rectangle.minY())) * 0.5);
      if(topArea < totalArea * 0.5) {
        // go around bottom (the side which would make a lesser movement)
        if(leftIntersect.getPoint().y() > rightIntersect.getPoint().y()) // bottom right
          return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
        // bottom left
        return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      }
      // go around top
      if(leftIntersect.getPoint().y() < rightIntersect.getPoint().y()) // top right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
      // top left
      return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
    }
    if(rightIntersect.getState() === Intersection.POINT) {
      if(topIntersect.getState() === Intersection.POINT) // triangle, must go around bottom left
        return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      if(bottomIntersect.getState() === Intersection.POINT) // triangle, must go around top left
        return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
    }
    // else through top to bottom, calculate areas
    var totalArea = rectangle.height() * rectangle.width();
    var leftArea = rectangle.height() * (((topIntersect.getPoint().x() - rectangle.minX()) + (bottomIntersect.getPoint().x() - rectangle.minX())) * 0.5);
    if(leftArea < totalArea * 0.5) {
      // go around right
      if(topIntersect.getPoint().x() > bottomIntersect.getPoint().x()) // bottom right
        return new Point(rectangle.maxX() + rerouteBuffer, rectangle.maxY() + rerouteBuffer);
      // top right
      return new Point(rectangle.maxX() + rerouteBuffer, rectangle.minY() - rerouteBuffer);
    }
    // go around left
    if(topIntersect.getPoint().x() < bottomIntersect.getPoint().x()) // bottom left
      return new Point(rectangle.minX() - rerouteBuffer, rectangle.maxY() + rerouteBuffer);
    // top left
    return new Point(rectangle.minX() - rerouteBuffer, rectangle.minY() - rerouteBuffer);
  }