public GeneralPath transform(GeneralPath in) {
    GeneralPath out = new GeneralPath();
    PathIterator it = in.getPathIterator(null);
    float[] seg = new float[6];

    Point2D.Double din = new Point2D.Double();
    Point2D.Double dout = new Point2D.Double();

    while (!it.isDone()) {
      int l = it.currentSegment(seg);
      din.x = seg[0];
      din.y = seg[1];
      projection.transform(din, dout);
      float x = (float) dout.x - minx;
      float y = maxy - (float) dout.y;

      try {
        if (!projection.inside(din.x, din.y)) l = PathIterator.SEG_MOVETO;
      } catch (Exception e) {
        l = PathIterator.SEG_MOVETO;
      }

      if (l == PathIterator.SEG_MOVETO) {
        out.moveTo(x, y);
      } else {
        out.lineTo(x, y);
      }
      it.next();
    }
    return out;
  }
Exemple #2
0
  /** @param override true if should kill even if invulerable, false if not */
  public void kill(boolean override) {
    if (!override) {
      if (star || invulerable || piped) return;
    }
    deathPos.setLocation(pos);
    if (deathPos.y < 0) {
      deathPos.y = 0;
    }
    if (metal) {
      metal = false;
      startInvulnerable();
      invulerableTime = 3000 / 15;
      Point2D.Double v = new Point2D.Double(Math.random() * 8 - 4, Math.random() * 4 + 7);

      TMetalCap cap = new TMetalCap();
      cap.setPos(pos.x, pos.y);
      cap.kill(v);
      this.addSpawn(cap);
      return;
    }
    cape = false;
    dead = true;
    numBullets = 0;
    falling = false;
    acc = new Point2D.Double();
    vel = new Point2D.Double();
    deadTime = 25;
  }
  public static Utility.Pair<ArrayList<Double>, ArrayList<Double>> calcFacingEdges(
      Point2D.Double position,
      Hashtable<ArrayList<Point2D.Double>, ArrayList<Point2D.Double>> obstacleToNormals) {

    ArrayList<Point2D.Double> lineStartPoints = new ArrayList<Point2D.Double>();
    ArrayList<Point2D.Double> lineEndPoints = new ArrayList<Point2D.Double>();

    Point2D.Double pointToLineEndpoint = new Point2D.Double();

    for (Entry<ArrayList<Double>, ArrayList<Double>> e : obstacleToNormals.entrySet()) {
      ArrayList<Double> obstacle = e.getKey();
      ArrayList<Double> normals = e.getValue();

      Point2D.Double lineStartPoint = obstacle.get(0);
      int numNormals = normals.size();
      for (int i = 0; i < normals.size(); ++i) {
        Point2D.Double n = normals.get(i);
        pointToLineEndpoint.x = lineStartPoint.x - position.x;
        pointToLineEndpoint.y = lineStartPoint.y - position.y;
        double dot = n.x * pointToLineEndpoint.x + n.y * pointToLineEndpoint.y;
        Point2D.Double lineEndPoint = obstacle.get((i + 1) % numNormals);
        if (dot < 0) {
          lineStartPoints.add(lineStartPoint);
          lineEndPoints.add(lineEndPoint);
        }
        lineStartPoint = lineEndPoint;
      }
    }

    return new Utility.Pair<ArrayList<Point2D.Double>, ArrayList<Point2D.Double>>(
        lineStartPoints, lineEndPoints);
  }
  private synchronized void initBars() {
    if (bars != null) {
      return;
    }

    bars = new Area[BAR_COUNT];

    final double fixedAngle = 2.0 * Math.PI / (double) bars.length;
    for (int i = 0; i < bars.length; ++i) {
      Area primitive = makeBar();

      Point2D.Double center = new Point2D.Double((double) DIAMETER / 2, (double) DIAMETER / 2);
      AffineTransform toCircle =
          AffineTransform.getRotateInstance(
              ((double) -i) * fixedAngle, center.getX(), center.getY());
      AffineTransform toBorder = AffineTransform.getTranslateInstance(45.0, -6.0);

      AffineTransform toScale = AffineTransform.getScaleInstance(0.1, 0.1);

      primitive.transform(toBorder);
      primitive.transform(toCircle);
      primitive.transform(toScale);

      bars[i] = primitive;
    }
  }
  @Override
  public void zoomOutButtonHit() {
    if (zoomLevel < 5) {
      zoomLevel++;

      double x = viewPoint.getX() + viewWidth / 2;
      double y = viewPoint.getY() + viewWidth / 2;
      viewWidth = viewWidth * 2;
      x = x - viewWidth / 2;
      y = y - viewWidth / 2;

      if (x < 0) {
        x = 0;
      } else if (x + viewWidth > 2048) {
        x = x - (x + viewWidth - 2048);
      }
      if (y < 0) {
        y = 0;
      } else if (y + viewWidth > 2048) {
        y = y - (y + viewWidth - 2048);
      }

      viewPoint.setLocation(x, y);

      setChanged();
      notifyObservers();
    }
  }
Exemple #6
0
  /**
   * Fits screen to specified geometry bounds.
   *
   * @param aArea A geometry in geo coordinates space.
   * @throws Exception
   */
  public void fit(Geometry aArea) throws Exception {

    Geometry bounds = aArea.getBoundary();
    Envelope envBounds = bounds.getEnvelopeInternal();
    Point2D.Double leftUpCorner = new Point2D.Double(envBounds.getMinX(), envBounds.getMinY());
    Point2D.Double rightBottomCorner = new Point2D.Double(envBounds.getMaxX(), envBounds.getMaxY());
    Point2D.Double cartlu = geo2Cartesian(leftUpCorner);
    Point2D.Double cartrb = geo2Cartesian(rightBottomCorner);
    double destWidth = Math.abs(cartrb.getX() - cartlu.getX());
    double destHeight = Math.abs(cartrb.getY() - cartlu.getY());
    Coordinate centre =
        new Coordinate((cartrb.getX() + cartlu.getX()) / 2, (cartrb.getY() + cartlu.getY()) / 2);

    Dimension size = getSize();
    Point2D.Double screenLT = awtScreen2Cartesian(new Point(0, 0));
    Point2D.Double screenBR = awtScreen2Cartesian(new Point(size.width, size.height));

    double srcWidth = screenBR.x - screenLT.x;
    double srcHeight = screenBR.y - screenLT.y;
    double sx = srcWidth / destWidth;
    double sy = srcHeight / destHeight;
    double coef = Math.min(sx, sy);
    coef = snapScale(coef);
    scaleView(coef, coef, false);

    Point2D.Double projectedScreenCenter = screen2Cartesian(new Point(0, 0));
    translateView(projectedScreenCenter.x - centre.x, projectedScreenCenter.y - centre.y, true);
    repaint();
  }
    public Point2D.Double getDirectionFor(Task task) {
      Point2D.Double loc = task.ownerLoc;
      Point2D.Double tLoc = task.targetLoc;
      Point2D.Double tVel = task.target.getVelocity();
      double tSpeed = tVel == null ? 0 : tVel.distance(0, 0);
      Point2D.Double diff = new Point2D.Double(tLoc.x - loc.x, tLoc.y - loc.y);

      if (tSpeed == 0 || task.owner.par.topSpeed < tSpeed * 1.0001)
        return PlanarMathUtils.normalize(diff);

      // In this algorithm, the capture point is assumed to be where the pursuer would first be able
      // to overtake the evader if the evader kept heading
      // in its current direction... this is where the ratio of speeds is equal to the ratio of
      // distances to this hypothetical point.
      // The evader's distance to this point is dE, and the pursuer heads toward the evader's
      // position plus its heading times dE*leadFactor.
      double mu =
          task.owner.par.topSpeed / tSpeed; // ratio of speeds is used several times in the formula
      double dcosth =
          (tVel.x * diff.x + tVel.y * diff.y)
              / tSpeed; // basic dot product formula for cosine... provides ||diff|| * cos of angle
                        // between diff and tVel
      double dE =
          (Math.abs(dcosth) - Math.sqrt(dcosth * dcosth - (1 - mu * mu) * diff.distanceSq(0, 0)))
              / (1 - mu * mu);

      return unitVectorTo(
          loc,
          new Point2D.Double(
              tLoc.x + tVel.x * leadFactor * dE / tSpeed,
              tLoc.y + tVel.y * leadFactor * dE / tSpeed),
          task.type.multiplier);
    }
  public double getDistance(Vector<VivaeObject> objects) {
    GeneralPath thisPath = new GeneralPath(this.getTransformedShape());
    PathIntersection pi = new PathIntersection();
    Point2D.Double[] points;
    double dist = ray_length;
    double nd;
    for (VivaeObject vivaeObject : objects) {
      if (vivaeObject != this.owner) {
        GeneralPath gp = new GeneralPath(vivaeObject.getTransformedShape());
        points = pi.getIntersections(thisPath, gp);
        for (Point2D.Double point : points) {
          nd = pi.euclideanDistance(point.getX(), point.getY(), owner.getX(), owner.getY());
          if (nd < dist) {
            dist = nd;
          }
          // System.out.println(dist);
        }
      }
    }

    opacity = Math.max((float) (1d - (dist / ray_length)), opacity);
    opacityOfRay = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);

    return 1d - (dist / ray_length);
  }
Exemple #9
0
  /* CENTROID */
  public static Point2D.Double polygonCenterOfMass(Point2D.Double[] polygon) {
    int N = polygon.length - 1;

    double cx = 0, cy = 0;
    //        double A = signedPolygonArea(polygon);
    Point2D.Double res = new Point2D.Double();
    int i, j;
    double sumDet = 0;

    double factor = 0;
    for (i = 0; i < N; i++) {
      j = i + 1;
      factor = (polygon[i].x * polygon[j].y - polygon[j].x * polygon[i].y);
      cx += (polygon[i].x + polygon[j].x) * factor;
      cy += (polygon[i].y + polygon[j].y) * factor;

      sumDet += factor;
    }
    factor = 1 / (3 * sumDet);

    //        A*=6.0;
    //        factor=1/A;
    cx *= factor;
    cy *= factor;
    res.x = cx;
    res.y = cy;
    return res;
  }
  /**
   * Builds the circular shape and returns the result as an array of <code>Area</code>. Each <code>
   * Area</code> is one of the bars composing the shape.
   */
  private Area[] buildTicker() {
    width = this.getPreferredSize().getWidth();
    height = this.getPreferredSize().getHeight();

    Area[] ticker = new Area[barsCount];
    Point2D.Double center = new Point2D.Double((double) width / 2, (double) height / 2);
    double fixedAngle = 2.0 * Math.PI / ((double) barsCount);

    for (double i = 0.0; i < (double) barsCount; i++) {
      Area primitive = buildPrimitive();

      AffineTransform toCenter = AffineTransform.getTranslateInstance(center.getX(), center.getY());
      AffineTransform toBorder = AffineTransform.getTranslateInstance(45.0 / 8, -6.0 / 8);
      AffineTransform toCircle =
          AffineTransform.getRotateInstance(-i * fixedAngle, center.getX(), center.getY());

      AffineTransform toWheel = new AffineTransform();
      toWheel.concatenate(toCenter);
      toWheel.concatenate(toBorder);

      primitive.transform(toWheel);
      primitive.transform(toCircle);

      ticker[(int) i] = primitive;
    }

    return ticker;
  }
Exemple #11
0
 public void zoomToGarminGeo(double factor, int longitude, int latitude) {
   Point2D.Double mapCoord = new Point2D.Double();
   COORD tempCoord = transformer.createTempCoord();
   transformer.wgs84ToMap(
       CoordUtils.toWGS84Rad(longitude), CoordUtils.toWGS84Rad(latitude), tempCoord, mapCoord);
   zoom(factor, (int) mapCoord.getX(), (int) mapCoord.getY());
 }
Exemple #12
0
  protected void updateMovement() {
    Point2D.Double newLocation;
    double acceleration = computeAcceleration();

    speed += acceleration;
    if ((speed > -1) && speed < 0) {
      speed = 0;
    } // just a cheat for stabilising the speed if it's close to 0

    if (speed >= 0) {
      tempOrientation = orientation;
      newLocation = updateXY(orientation);
    } else {
      newLocation =
          updateXY(
              direction); // if speed is <0, that means the bunny is spinning and its direction is
                          // different from orientation
      spin();
    }

    // to check if intersectig with something - be that bounds or components
    newLocation = checkIntersects(newLocation);

    // let the bunny rotate if it was trying to (i.e. if arrows were pressed)
    rotate();

    // give the new newLocation to the bunny
    x = newLocation.getX();
    y = newLocation.getY();
  }
  @Override
  public List<GeoEventPage> getNextFrame() {
    List<GeoEventPage> list = new ArrayList<GeoEventPage>();

    if (Math.random() <= 0.9) {
      currentCycle++;
      return list;
    }

    for (int j = 0; j < 5; j++) {
      Point2D.Double newPoint;
      if (Math.random() <= 0.05) {
        newPoint = addNewSeedPoint();
      } else {
        Point2D.Double randomSeedPoint = seedPoints.get((int) (Math.random() * seedPoints.size()));
        newPoint = new Point.Double(randomSeedPoint.x, randomSeedPoint.y);

        double distance = (Math.random() * ((CumulativeGeoFrameRenderer.LONGITUDE_DEGREES / 10)));
        newPoint.x += (Math.random() * distance) - (distance / 2);
        newPoint.y += (Math.random() * distance) - (distance / 2);
      }

      GeoEventPage randomPage = new GeoEventPage(newPoint.x, newPoint.y, currentCycle, 0, 0, 0, "");
      list.add(randomPage);
    }

    currentCycle++;
    return list;
  }
  /** Redraws the image. */
  private void redrawImage() {
    ScreenToWorldPointConverter converter = null;
    try {
      converter =
          new ScreenToWorldPointConverter(
              currWXMin, currWYMin, currWXMax, currWYMax, 0, 0, width - 1, height - 1);
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }

    Point2D P = null;
    Point2D.Double screenPoint = new Point2D.Double();
    ComplexNumber C = null;
    Color theColor = null;
    int colorIndex = 0;
    for (int i = 0; i < width; ++i) {
      for (int j = 0; j < height; ++j) {
        screenPoint.setLocation(i, j);
        P = converter.getWorldCoordinates(screenPoint);
        C = new ComplexNumber(new RealNumber(P.getX()), new RealNumber(P.getY()));
        colorIndex = Mandelbrot.divergenceIndex(C);
        if (colorIndex < 0) {
          theColor = Color.black;
        } else {
          theColor = Mandelbrot.getColor(colorIndex);
        }
        img.paintPixel(i, j, theColor.getRGB());
      }
    }
  }
  /**
   * Check if a sprite contains the given point (x,y).
   *
   * @param elt The sprite.
   * @param x The point abscissa.
   * @param y The point ordinate.
   * @return True if (x,y) is in the given element.
   */
  protected boolean spriteContains(GraphicElement elt, double x, double y) {
    Values size = elt.getStyle().getSize();
    double w2 = metrics.lengthToPx(size, 0) / 2;
    double h2 = size.size() > 1 ? metrics.lengthToPx(size, 1) / 2 : w2;
    Point2D.Double dst = spritePositionPx((GraphicSprite) elt); // new
    // Point2D.Double(
    // elt.getX(),
    // elt.getY()
    // );
    // Point2D.Double dst = new Point2D.Double();

    // Tx.transform( src, dst );
    dst.x -= metrics.viewport[0];
    dst.y -= metrics.viewport[1];

    double x1 = dst.x - w2;
    double x2 = dst.x + w2;
    double y1 = dst.y - h2;
    double y2 = dst.y + h2;

    if (x < x1) return false;
    if (y < y1) return false;
    if (x > x2) return false;
    if (y > y2) return false;

    return true;
  }
  public Point2D.Double projectInverse(double xyx, double xyy, Point2D.Double out) {
    double t = 0;

    double lpphi = RYC * xyy;
    if (Math.abs(lpphi) > 1.) {
      if (Math.abs(lpphi) > ONETOL) {
        throw new ProjectionException("I");
      } else if (lpphi < 0.) {
        t = -1.;
        lpphi = -Math.PI;
      } else {
        t = 1.;
        lpphi = Math.PI;
      }
    } else {
      lpphi = 2. * Math.asin(t = lpphi);
    }
    out.x = RXC * xyx / (1. + 2. * Math.cos(lpphi) / Math.cos(0.5 * lpphi));
    lpphi = RC * (t + Math.sin(lpphi));
    if (Math.abs(lpphi) > 1.) {
      if (Math.abs(lpphi) > ONETOL) {
        throw new ProjectionException("I");
      } else {
        lpphi = lpphi < 0. ? -MapMath.HALFPI : MapMath.HALFPI;
      }
    } else {
      lpphi = Math.asin(lpphi);
    }
    out.y = lpphi;
    return out;
  }
Exemple #17
0
  private void draw(Graphics2D g2, Point2D cursor, double width, double height) {

    double widthFactor = 0.95f;
    double heightFactor = 0.95f;

    double yAxeWidth = width - (width * widthFactor);
    double xAxeHeight = height - height * heightFactor;

    Point2D.Double localCursor = new Point2D.Double(cursor.getX(), cursor.getY());
    localCursor.x += yAxeWidth;

    plot.draw(g2, localCursor, width * widthFactor, height * heightFactor);

    Range plotYRange = plot.getPlotModel().getYRange();

    AxisState yAxisState =
        yAxis.build(g2, cursor, yAxeWidth, height * heightFactor, plot.getPlotArea(), plotYRange);

    localCursor.y += height * heightFactor;

    Range plotXRange = plot.getPlotModel().getXRange();

    AxisState xAxisState =
        xAxis.build(
            g2, localCursor, width * widthFactor, xAxeHeight, plot.getPlotArea(), plotXRange);

    synFontSize(xAxisState, yAxisState);

    xAxis.draw();
    yAxis.draw();

    gridRenderer.draw(g2, plot.getPlotArea(), xAxisState, yAxisState);
  }
  /**
   * Compute the position of a sprite if it is not attached.
   *
   * @param sprite The sprite.
   * @param pos Where to stored the computed position, if null, the position is created.
   * @param units The units the computed position must be given into.
   * @return The same instance as pos, or a new one if pos was null.
   */
  protected Point2D.Double getSpritePositionFree(
      GraphicSprite sprite, Point2D.Double pos, Units units) {
    if (pos == null) pos = new Point2D.Double();

    if (sprite.getUnits() == units) {
      pos.x = sprite.getX();
      pos.y = sprite.getY();
    } else if (units == Units.GU && sprite.getUnits() == Units.PX) {
      pos.x = sprite.getX();
      pos.y = sprite.getY();

      xT.transform(pos, pos);
    } else if (units == Units.PX && sprite.getUnits() == Units.GU) {
      pos.x = sprite.getX();
      pos.y = sprite.getY();

      Tx.transform(pos, pos);
    } else if (units == Units.GU && sprite.getUnits() == Units.PERCENTS) {
      pos.x = metrics.lo.x + (sprite.getX() / 100f) * metrics.graphWidthGU();
      pos.y = metrics.lo.y + (sprite.getY() / 100f) * metrics.graphHeightGU();
    } else if (units == Units.PX && sprite.getUnits() == Units.PERCENTS) {
      pos.x = (sprite.getX() / 100f) * metrics.viewport[2];
      pos.y = (sprite.getY() / 100f) * metrics.viewport[3];
    } else {
      throw new RuntimeException("Unhandled yet sprite positioning.");
    }

    return pos;
  }
Exemple #19
0
  public final void updateMousePos(double xRW, double yRW) {

    if (isVisible) {
      // double xRW = view.toRealWorldCoordX(mx);
      // double yRW = view.toRealWorldCoordY(my);

      int mx = view.toScreenCoordX(xRW);
      int my = view.toScreenCoordY(yRW);

      // round angle to nearest 15 degrees if alt pressed
      if (points.size() == 1 && view.getEuclidianController().altDown) {
        GeoPoint p = (GeoPoint) points.get(0);
        double px = p.inhomX;
        double py = p.inhomY;
        double angle = Math.atan2(yRW - py, xRW - px) * 180 / Math.PI;
        double radius = Math.sqrt((py - yRW) * (py - yRW) + (px - xRW) * (px - xRW));

        // round angle to nearest 15 degrees
        angle = Math.round(angle / 15) * 15;

        xRW = px + radius * Math.cos(angle * Math.PI / 180);
        yRW = py + radius * Math.sin(angle * Math.PI / 180);

        mx = view.toScreenCoordX(xRW);
        my = view.toScreenCoordY(yRW);

        endPoint.x = xRW;
        endPoint.y = yRW;
        view.getEuclidianController().setLineEndPoint(endPoint);
      } else view.getEuclidianController().setLineEndPoint(null);
      line.setLine(coordsA[0], coordsA[1], mx, my);
    }
  }
 private Point2D getBezier(
     double percent, Point2D.Double C1, Point2D.Double C2, Point2D.Double C3, Point2D.Double C4) {
   Point2D.Double pos = new Point2D.Double();
   pos.x = C1.x * B1(percent) + C2.x * B2(percent) + C3.x * B3(percent) + C4.x * B4(percent);
   pos.y = C1.y * B1(percent) + C2.y * B2(percent) + C3.y * B3(percent) + C4.y * B4(percent);
   return pos;
 }
  public void draw(Graphics g, int xPos, int yPos, short state) {
    BufferedImage src;
    boolean top = false;
    if (popFrame > 0) {
      if (updatePopFrame) {
        popFrame++;
        if (popFrame >= POP_FRAME_COUNT) popFrame = 0;
      }
    }
    if (popFrame > 0) g.drawImage(PoliteSolidBlock.popImg[popFrame - 1], xPos, yPos, null);

    Game game = Game.getGame();
    Point2D.Double cellID = game.screenToWorld(new Point2D.Double(xPos + 1, yPos + 1));
    cellID = game.worldToCell(cellID);
    cellID.y = cellID.y - 1;
    Cell c = game.getCell((int) (cellID.x), (int) (cellID.y));
    if (c != null)
      if (c.getBlockTypeInt() != Cell.POLITE_SOLID_BLOCK || (c.getState() <= 0 && state > 0))
        top = true;
    if (top) {
      if (state > 0) src = PoliteSolidBlock.topActiveImg;
      else src = PoliteSolidBlock.topInactiveImg;
    } else {
      if (state > 0) src = PoliteSolidBlock.activeImg;
      else src = PoliteSolidBlock.inactiveImg;
    }
    g.drawImage(src, xPos, yPos, null);
  }
  public static Point2D.Double pointBetween(Point2D.Double p, Point2D.Double p2, double pos) {

    Point2D.Double n =
        new Point2D.Double(
            p.getX() * (1 - pos) + p2.getX() * (pos), p.getY() * (1 - pos) + p2.getY() * (pos));

    return n;
  }
  public Point2D.Double projectInverse(double xyx, double xyy, Point2D.Double out) {
    double c;

    out.y = MapMath.asin(xyy / C_y);
    out.x = xyx / (C_x * ((c = Math.cos(out.y)) - 0.5));
    out.y = MapMath.asin((out.y + Math.sin(out.y) * (c - 1.)) / C_p);
    return out;
  }
  /** Checks if we are close to a wall and reverse the tank */
  public double avoidWalls(Point2D.Double myPos) {
    double reverse = 0;

    if (myPos.getX() > 720 || myPos.getX() < 80 || myPos.getY() > 520 || myPos.getY() < 80) {
      reverse = -1000;
    }
    return reverse;
  }
 void calcPos(AffineTransform w2n) {
   w2n.transform(worldPos, screenPos); // work in normalized coordinate space
   bbPos.setRect(
       screenPos.getX() + bb.getX(),
       screenPos.getY() + bb.getY(),
       bb.getWidth(),
       bb.getHeight());
 }
Exemple #26
0
 @Override
 public void vScrollbarChanged(int value) {
   if (value != viewPoint.getY()) {
     viewPoint.setLocation(viewPoint.getX(), value);
     setChanged();
     notifyObservers();
   }
 }
Exemple #27
0
 /**
  * Returns a coordinate location starting from (x,y) and proceeding the given travel distance at
  * the given heading.
  *
  * @param x starting x-coordinate
  * @param y starting y-coordinate
  * @param travelDistance distance to travel from starting coordinate
  * @param headingRoboDegrees heading to travel in (in Robocode degrees)
  * @return location after traveling the given distance at the given heading
  */
 public static Point2D.Double getLocation(
     double x, double y, double travelDistance, double headingRoboDegrees) {
   double pheta = Math.toRadians(convertDegrees(headingRoboDegrees));
   Point2D.Double location = new Point2D.Double();
   location.x = x + travelDistance * Math.cos(pheta);
   location.y = y + travelDistance * Math.sin(pheta);
   return location;
 }
Exemple #28
0
  private void calculatePpvVsScore() {

    if (needToRecalculate && this.data != null && this.data.hasPositives()) {

      int window = 100;

      CovariationTriplet[] triplets = new CovariationTriplet[this.data.getNumberOfElements()];

      int tripletCounter = 0;
      for (int i = 1; i <= this.data.getMatrixSize(); i++) {
        for (int j = i + 1; j <= this.data.getMatrixSize(); j++) {
          triplets[tripletCounter] =
              new CovariationTriplet(i, j, this.data.getMatrix().getValue(i, j));
          tripletCounter++;
        }
      }

      this.data.getMatrix().getMin();

      Arrays.sort(triplets, CovariationTriplet.getComparator(true));

      List<Point2D.Double> ppvVsScore = new ArrayList<>();

      Point2D.Double firstPoint = new Point2D.Double(0, 0);

      ppvVsScore.add(firstPoint);

      Set<Pair<Integer, Integer>> positives = this.data.getPositives();

      for (int i = 0; i < window; i++) {
        firstPoint.x += triplets[0].getValue();
        Pair<Integer, Integer> pair =
            new Pair<>(triplets[i].getNominalX(), triplets[i].getNominalY());
        firstPoint.y += positives.contains(pair) ? 1 : 0;
      }

      Point2D.Double currentPoint = new Point2D.Double(firstPoint.x, firstPoint.y);

      for (int i = window; i < triplets.length; i++) {
        Pair<Integer, Integer> pairBegin =
            new Pair<>(triplets[i - window].getNominalX(), triplets[i - window].getNominalY());

        Pair<Integer, Integer> pairNew =
            new Pair<>(triplets[i].getNominalX(), triplets[i].getNominalY());

        currentPoint =
            new Point2D.Double(
                currentPoint.x - triplets[i - window].getValue() + triplets[i].getValue(),
                currentPoint.y
                    - (positives.contains(pairBegin) ? 1 : 0)
                    + (positives.contains(pairNew) ? 1 : 0));

        ppvVsScore.add(currentPoint);
      }

      this.ppvVsScore = ppvVsScore;
    }
  }
 /**
  * @return vector pointing from one vector to another, scaled to specified length; returns zero
  *     vector if from/to points are equal
  */
 public static Point2D.Double scaledUnitVector(
     double length, Point2D.Double from, Point2D.Double to) {
   Point2D.Double dir = new Point2D.Double(to.x - from.x, to.y - from.y);
   double magn = dir.distance(0, 0);
   if (magn == 0) return new Point2D.Double();
   dir.x *= length / magn;
   dir.y *= length / magn;
   return dir;
 }
  /**
   * Detects mouse being release. This completes the rectangle representing the new complex plane.
   * It draws the selected rectangle first, redraws the image and repaints the screen.
   */
  @Override
  public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub
    /*
     * currSXMax = e.getX(); currSYMax = e.getY();
     *
     * System.out.printf("currSXMax: %f, currSYMax: %f\n ",currSXMax,currSYMax
     * );
     */

    endX = e.getX();
    endY = e.getY();
    // DEBUG
    // System.out.printf("endX: %f, endY: %f\n ",endX,endY);

    currSXMin = Math.min(startX, endX);
    currSYMin = Math.min(startY, endY);
    currSXMax = Math.max(startX, endX);
    currSYMax = Math.max(startY, endY);

    // Graphics g = this.getGraphics();
    Graphics g = this.img.getGraphics();
    g.setColor(new Color(1, 1, 1, 0.7f));
    // DEBUG
    // System.out.printf("Recgtangle(%d, %d, %d, %d)\n", (int) currSXMin,
    // (int) currSYMin, (int) (currSXMax - currSXMin), (int) (currSYMax -
    // currSYMin));

    g.fillRect(
        (int) currSXMin,
        (int) currSYMin,
        (int) (currSXMax - currSXMin),
        (int) (currSYMax - currSYMin));

    Point2D.Double screenPoint = new Point2D.Double();
    Point2D P = null;

    ScreenToWorldPointConverter converter = null;
    try {
      converter =
          new ScreenToWorldPointConverter(
              currWXMin, currWYMin, currWXMax, currWYMax, 0, 0, width - 1, height - 1);
    } catch (Exception ex) {
      throw new IllegalStateException(ex);
    }
    screenPoint.setLocation(currSXMin, currSYMin);
    P = converter.getWorldCoordinates(screenPoint);
    currWXMin = P.getX();
    currWYMin = P.getY();

    screenPoint.setLocation(currSXMax, currSYMax);
    P = converter.getWorldCoordinates(screenPoint);
    currWXMax = P.getX();
    currWYMax = P.getY();
    redrawImage();
    repaint();
  }