public Letter getIntersection() {
    try {
      // int xx = this.imgOffset[0];
      // int yy = this.imgOffset[1];
      int left = offset[0];
      int top = offset[1];
      int tmpIntersectionWidth = intersectionDimension[0];
      int tmpIntersectionHeight = intersectionDimension[1];

      // long starter=Utilities.getTimer();

      int[][] g = new int[tmpIntersectionWidth][tmpIntersectionHeight];

      for (int x = 0; x < tmpIntersectionWidth; x++) {
        for (int y = 0; y < tmpIntersectionHeight; y++) {
          g[x][y] = a.getPixelValue(x + left, y + top);
        }
      }

      Letter ret = getA().createLetter();
      int[] l = getA().getLocation();
      ret.setLocation(new int[] {l[0] + left, l[1] + top});
      ret.setGrid(g);
      ret.clean();
      return ret;
    } catch (Exception e) {
      JDLogger.exception(e);
      return getA();
    }
  }
  public Letter getDifference() {
    try {
      int xx = imgOffset[0];
      int yy = imgOffset[1];
      int left = offset[0];
      int top = offset[1];
      int tmpIntersectionWidth = intersectionDimension[0];
      int tmpIntersectionHeight = intersectionDimension[1];

      // long starter=Utilities.getTimer();

      int[][] g = new int[tmpIntersectionWidth][tmpIntersectionHeight];

      for (int x = 0; x < tmpIntersectionWidth; x++) {
        for (int y = 0; y < tmpIntersectionHeight; y++) {
          g[x][y] = getA().getMaxPixelValue();
          int pixelType = getPixelType(x, y, xx, yy, left, top);

          switch (pixelType) {
            case 0:

              // g[x][y] = 0xcccccc;
              break;
            case 1:
              if (hasNeighbour(x, y, xx, yy, left, top, pixelType) > overlayNoiseSize) {

                // g[x][y] = 0xff0000;
              } else {
                // g[x][y] = 0xff0000;

              }
              g[x][y] = 0;
              break;
            case 2:
              if (hasNeighbour(x, y, xx, yy, left, top, pixelType) > overlayNoiseSize) {
                g[x][y] = 0;
              }
              // else {
              // g[x][y] = 0;
              // g[x][y] = 0x00ff00;
              // }
              break;
            default:
          }
        }
      }

      Letter ret = getA().createLetter();
      int[] l = getA().getLocation();
      ret.setLocation(new int[] {l[0] + left, l[1] + top});
      ret.setGrid(g);
      ret.clean();
      return ret;
    } catch (Exception e) {
      return getA();
    }
  }
  /** Scan ist die eigentliche vergleichsfunktion. a und b werden dabei gegeneinander verschoben. */
  private void scan() {
    long startTime = System.currentTimeMillis();
    double bestValue = 20000.0;
    preValityPercent = 20000.0;
    tmpPreScanValue = 20000.0;
    // logger.info(b.getDecodedValue()+"----");

    // scanvarianzen geben an wieviel beim verschieben über die grenzen
    // geschoben wird. große werte brauchen CPU
    int vx = getScanVarianceX();
    int vy = getScanVarianceY();
    vx = Math.min(vx, b.getWidth());
    vy = Math.min(vy, b.getHeight());
    int scanXFrom = -vx;
    int scanXTo = a.getWidth() - b.getWidth() + vx;
    int scanYFrom = -vy;
    int scanYTo = a.getHeight() - b.getHeight() + vy;
    int tmp;
    if (scanXTo < scanXFrom) {
      tmp = scanXTo;
      scanXTo = scanXFrom;
      scanXFrom = tmp;
    }
    if (scanYTo < scanYFrom) {
      tmp = scanYTo;
      scanYTo = scanYFrom;
      scanYFrom = tmp;
    }

    double value;
    Letter tmpIntersection = null;
    if (isCreateIntersectionLetter()) {
      tmpIntersection = new Letter();
    }
    int left;
    int right;
    int top;
    int bottom;
    int tmpIntersectionWidth;
    int tmpIntersectionHeight;

    // if(b.id==1371) logger.info(" Scan from " + scanXFrom + "/" + scanXTo
    // + " - " + scanYFrom + "/" + scanYTo + " Var: " + vx + "/" + vy);
    // schleife verschieb a und b gegeneinander. Dabei wird um den
    // jeweiligen Mittelpunkt herumgesprungen. Die Warscheinlichsten Fälle
    // in der Nullage werden zuerst geprüft
    // if (this.getDecodedValue().equals("1"))
    // logger.info(this.getDecodedValue() + " :start");

    for (int xx = Utilities.getJumperStart(scanXFrom, scanXTo);
        Utilities.checkJumper(xx, scanXFrom, scanXTo);
        xx = Utilities.nextJump(xx, scanXFrom, scanXTo, 1)) {
      for (int yy = Utilities.getJumperStart(scanYFrom, scanYTo);
          Utilities.checkJumper(yy, scanYFrom, scanYTo);
          yy = Utilities.nextJump(yy, scanYFrom, scanYTo, 1)) {
        // Offsets
        left = Math.max(0, xx);
        right = Math.min(xx + b.getWidth(), a.getWidth());
        top = Math.max(0, yy);
        bottom = Math.min(yy + b.getHeight(), a.getHeight());
        // intersection ^=ausschnitt
        tmpIntersectionWidth = right - left;
        tmpIntersectionHeight = bottom - top;
        if (tmpIntersectionWidth <= 0 || tmpIntersectionHeight <= 0) {
          // logger.warning("Scannvarianzen zu groß: " +
          // tmpIntersectionWidth + "/" + tmpIntersectionHeight);
          continue;
        }
        if (isCreateIntersectionLetter()) {
          tmpIntersection = new Letter();
          tmpIntersection.setOwner(owner);
          intersectionGrid = new int[tmpIntersectionWidth][tmpIntersectionHeight];
          tmpIntersection.setGrid(intersectionGrid);
        }
        //
        if (preScanFilter > 0) {
          tmpPreScanValue =
              scanPreIntersection(xx, yy, left, top, tmpIntersectionWidth, tmpIntersectionHeight);
          // logger.info("_"+preScan);

          if ((int) tmpPreScanValue > preScanFilter) {
            if (preValityPercent > tmpPreScanValue) {
              setPreValityPercent(tmpPreScanValue);
            }
            continue;
          }
        }
        // logger.info("Scan
        // "+tmpIntersectionWidth+"/"+tmpIntersectionHeight+" -
        // "+a.getElementPixel());

        value = scanIntersection(xx, yy, left, top, tmpIntersectionWidth, tmpIntersectionHeight);
        // logger.info(tmpIntersectionWidth+"/"+tmpIntersectionHeight+"
        // : "+" scanIntersection: ");
        //
        // if(getDecodedValue().equalsIgnoreCase("v")&&getBothElementsNum()==3){
        // logger.info("JJJ");
        // }
        if (value < bestValue) {
          bestValue = value;
          setExtensionError(tmpExtensionError);
          setValityPercent(value);
          setHeightFaktor(tmpHeightFaktor);
          setWidthFaktor(tmpWidthFaktor);
          setIntersectionHeight(tmpIntersectionHeight);
          setIntersectionWidth(tmpIntersectionWidth);
          setIntersectionStartX(xx);
          setIntersectionStartY(yy);
          setPosition(left, top);
          setBothElementNum(bothElements.size());
          setCoverageFaktorA(tmpCoverageFaktorA);
          setCoverageFaktorB(tmpCoverageFaktorB);
          setPixelErrorA(tmpErrorA);
          setPreValityPercent(tmpPreScanValue);
          setPixelErrorB(tmpErrorB);
          setPixelANotB(tmpPixelAButNotB);
          setPixelBNotA(tmpPixelBButNotA);
          setPixelBoth(tmpPixelBoth);
          intersectionAHeightFaktor = 0.0;
          intersectionAWidthFaktor = 0.0;
          setIntersectionAHeightFaktor(tmpHeightAFaktor);
          setIntersectionAWidthFaktor(tmpWidthAFaktor);

          setTotalPixelError(tmpErrorTotal);
          if (isCreateIntersectionLetter()) {
            setIntersectionLetter(tmpIntersection);
          }
        }
      }
    }
    // }

    scanTime = (int) (System.currentTimeMillis() - startTime);
  }