Пример #1
0
    /** For each rectangle, packs each one then chooses the best and packs that. Slow! */
    public Page pack(Array<Rect> rects, FreeRectChoiceHeuristic method) {
      rects = new Array(rects);
      while (rects.size > 0) {
        int bestRectIndex = -1;
        Rect bestNode = new Rect();
        bestNode.score1 = Integer.MAX_VALUE;
        bestNode.score2 = Integer.MAX_VALUE;

        // Find the next rectangle that packs best.
        for (int i = 0; i < rects.size; i++) {
          Rect newNode = scoreRect(rects.get(i), method);
          if (newNode.score1 < bestNode.score1
              || (newNode.score1 == bestNode.score1 && newNode.score2 < bestNode.score2)) {
            bestNode.set(rects.get(i));
            bestNode.score1 = newNode.score1;
            bestNode.score2 = newNode.score2;
            bestNode.x = newNode.x;
            bestNode.y = newNode.y;
            bestNode.width = newNode.width;
            bestNode.height = newNode.height;
            bestNode.rotated = newNode.rotated;
            bestRectIndex = i;
          }
        }

        if (bestRectIndex == -1) break;

        placeRect(bestNode);
        rects.removeIndex(bestRectIndex);
      }

      Page result = getResult();
      result.remainingRects = rects;
      return result;
    }
Пример #2
0
 public Page getResult() {
   int w = 0, h = 0;
   for (int i = 0; i < usedRectangles.size; i++) {
     Rect rect = usedRectangles.get(i);
     w = Math.max(w, rect.x + rect.width);
     h = Math.max(h, rect.y + rect.height);
   }
   Page result = new Page();
   result.outputRects = new Array(usedRectangles);
   result.occupancy = getOccupancy();
   result.width = w;
   result.height = h;
   return result;
 }
Пример #3
0
 /**
  * @param fully If true, the only results that pack all rects will be considered. If false, all
  *     results are considered, not all rects may be packed.
  */
 private Page packAtSize(boolean fully, int width, int height, Array<Rect> inputRects) {
   Page bestResult = null;
   for (int i = 0, n = methods.length; i < n; i++) {
     maxRects.init(width, height);
     Page result;
     if (!settings.fast) {
       result = maxRects.pack(inputRects, methods[i]);
     } else {
       Array<Rect> remaining = new Array();
       for (int ii = 0, nn = inputRects.size; ii < nn; ii++) {
         Rect rect = inputRects.get(ii);
         if (maxRects.insert(rect, methods[i]) == null) {
           while (ii < nn) remaining.add(inputRects.get(ii++));
         }
       }
       result = maxRects.getResult();
       result.remainingRects = remaining;
     }
     if (fully && result.remainingRects.size > 0) continue;
     if (result.outputRects.size == 0) continue;
     bestResult = getBest(bestResult, result);
   }
   return bestResult;
 }
Пример #4
0
  private Page packPage(Array<Rect> inputRects) {
    int edgePaddingX = 0, edgePaddingY = 0;
    if (!settings.duplicatePadding) { // if duplicatePadding, edges get only half padding.
      edgePaddingX = settings.paddingX;
      edgePaddingY = settings.paddingY;
    }
    // Find min size.
    int minWidth = Integer.MAX_VALUE;
    int minHeight = Integer.MAX_VALUE;
    for (int i = 0, nn = inputRects.size; i < nn; i++) {
      Rect rect = inputRects.get(i);
      minWidth = Math.min(minWidth, rect.width);
      minHeight = Math.min(minHeight, rect.height);
      if (settings.rotation) {
        if ((rect.width > settings.maxWidth || rect.height > settings.maxHeight)
            && (rect.width > settings.maxHeight || rect.height > settings.maxWidth)) {
          throw new RuntimeException(
              "Image does not fit with max page size "
                  + settings.maxWidth
                  + "x"
                  + settings.maxHeight
                  + " and padding "
                  + settings.paddingX
                  + ","
                  + settings.paddingY
                  + ": "
                  + rect);
        }
      } else {
        if (rect.width > settings.maxWidth) {
          throw new RuntimeException(
              "Image does not fit with max page width "
                  + settings.maxWidth
                  + " and paddingX "
                  + settings.paddingX
                  + ": "
                  + rect);
        }
        if (rect.height > settings.maxHeight
            && (!settings.rotation || rect.width > settings.maxHeight)) {
          throw new RuntimeException(
              "Image does not fit in max page height "
                  + settings.maxHeight
                  + " and paddingY "
                  + settings.paddingY
                  + ": "
                  + rect);
        }
      }
    }
    minWidth = Math.max(minWidth, settings.minWidth);
    minHeight = Math.max(minHeight, settings.minHeight);

    if (!settings.silent) System.out.print("Packing");

    // Find the minimal page size that fits all rects.
    Page bestResult = null;
    if (settings.square) {
      int minSize = Math.max(minWidth, minHeight);
      int maxSize = Math.min(settings.maxWidth, settings.maxHeight);
      BinarySearch sizeSearch =
          new BinarySearch(minSize, maxSize, settings.fast ? 25 : 15, settings.pot);
      int size = sizeSearch.reset(), i = 0;
      while (size != -1) {
        Page result = packAtSize(true, size - edgePaddingX, size - edgePaddingY, inputRects);
        if (!settings.silent) {
          if (++i % 70 == 0) System.out.println();
          System.out.print(".");
        }
        bestResult = getBest(bestResult, result);
        size = sizeSearch.next(result == null);
      }
      if (!settings.silent) System.out.println();
      // Rects don't fit on one page. Fill a whole page and return.
      if (bestResult == null)
        bestResult = packAtSize(false, maxSize - edgePaddingX, maxSize - edgePaddingY, inputRects);
      sort.sort(bestResult.outputRects, rectComparator);
      bestResult.width = Math.max(bestResult.width, bestResult.height);
      bestResult.height = Math.max(bestResult.width, bestResult.height);
      return bestResult;
    } else {
      BinarySearch widthSearch =
          new BinarySearch(minWidth, settings.maxWidth, settings.fast ? 25 : 15, settings.pot);
      BinarySearch heightSearch =
          new BinarySearch(minHeight, settings.maxHeight, settings.fast ? 25 : 15, settings.pot);
      int width = widthSearch.reset(), i = 0;
      int height = settings.square ? width : heightSearch.reset();
      while (true) {
        Page bestWidthResult = null;
        while (width != -1) {
          Page result = packAtSize(true, width - edgePaddingX, height - edgePaddingY, inputRects);
          if (!settings.silent) {
            if (++i % 70 == 0) System.out.println();
            System.out.print(".");
          }
          bestWidthResult = getBest(bestWidthResult, result);
          width = widthSearch.next(result == null);
          if (settings.square) height = width;
        }
        bestResult = getBest(bestResult, bestWidthResult);
        if (settings.square) break;
        height = heightSearch.next(bestWidthResult == null);
        if (height == -1) break;
        width = widthSearch.reset();
      }
      if (!settings.silent) System.out.println();
      // Rects don't fit on one page. Fill a whole page and return.
      if (bestResult == null)
        bestResult =
            packAtSize(
                false,
                settings.maxWidth - edgePaddingX,
                settings.maxHeight - edgePaddingY,
                inputRects);
      sort.sort(bestResult.outputRects, rectComparator);
      return bestResult;
    }
  }