private static Bounds computeExtensionBounds(
      Bounds backgroundBounds, Bounds unclippedContentBounds) {
    final Bounds totalBounds = unionOfBounds(backgroundBounds, unclippedContentBounds);
    final double backgroundCenterX, backgroundCenterY;
    backgroundCenterX = (backgroundBounds.getMinX() + backgroundBounds.getMaxX()) / 2.0;
    backgroundCenterY = (backgroundBounds.getMinY() + backgroundBounds.getMaxY()) / 2.0;
    assert totalBounds.contains(backgroundCenterX, backgroundCenterY);
    double extensionHalfWidth, extensionHalfHeight;
    extensionHalfWidth =
        Math.max(
            backgroundCenterX - totalBounds.getMinX(), totalBounds.getMaxX() - backgroundCenterX);
    extensionHalfHeight =
        Math.max(
            backgroundCenterY - totalBounds.getMinY(), totalBounds.getMaxY() - backgroundCenterY);

    // We a few pixels in order the parent ring of root object
    // to fit inside the extension rect.
    extensionHalfWidth += 20.0;
    extensionHalfHeight += 20.0;

    return new BoundingBox(
        backgroundCenterX - extensionHalfWidth,
        backgroundCenterY - extensionHalfHeight,
        extensionHalfWidth * 2,
        extensionHalfHeight * 2);
  }
  private static Bounds computeUnclippedBounds(Node node) {
    final Bounds layoutBounds;
    double minX, minY, maxX, maxY, minZ, maxZ;

    assert node != null;
    assert node.getLayoutBounds().isEmpty() == false;

    layoutBounds = node.getLayoutBounds();
    minX = layoutBounds.getMinX();
    minY = layoutBounds.getMinY();
    maxX = layoutBounds.getMaxX();
    maxY = layoutBounds.getMaxY();
    minZ = layoutBounds.getMinZ();
    maxZ = layoutBounds.getMaxZ();

    if (node instanceof Parent) {
      final Parent parent = (Parent) node;

      for (Node child : parent.getChildrenUnmodifiable()) {
        final Bounds childBounds = child.getBoundsInParent();
        minX = Math.min(minX, childBounds.getMinX());
        minY = Math.min(minY, childBounds.getMinY());
        maxX = Math.max(maxX, childBounds.getMaxX());
        maxY = Math.max(maxY, childBounds.getMaxY());
        minZ = Math.min(minZ, childBounds.getMinZ());
        maxZ = Math.max(maxZ, childBounds.getMaxZ());
      }
    }

    assert minX <= maxX;
    assert minY <= maxY;
    assert minZ <= maxZ;

    return new BoundingBox(minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ);
  }
Пример #3
0
 private static Bounds intersectBounds(Bounds a, Bounds b) {
   double minX = Math.max(a.getMinX(), b.getMinX());
   double minY = Math.max(a.getMinY(), b.getMinY());
   double maxX = Math.min(a.getMaxX(), b.getMaxX());
   double maxY = Math.min(a.getMaxY(), b.getMaxY());
   double width = maxX - minX;
   double height = maxY - minY;
   return new BoundingBox(minX, minY, width, height);
 }
Пример #4
0
  private void init(LedColor initialColor) {
    PhongMaterial material = new PhongMaterial();
    material.setDiffuseColor(initialColor.getColor());

    int ledSpacing = 60;
    int ledSize = 10;

    for (int x = 0; x < cubeSize; x++) {
      for (int y = 0; y < cubeSize; y++) {
        for (int z = 0; z < cubeSize; z++) {
          final Sphere led = new Sphere(ledSize);
          led.setMaterial(material);
          led.setTranslateX(x * (ledSize + ledSpacing) + ledSize);
          led.setTranslateY(y * (ledSize + ledSpacing) + ledSize);
          led.setTranslateZ(z * (ledSize + ledSpacing) + ledSize);
          led.setOnMouseClicked(
              event -> {
                fireOnClick(event);
              });
          led.setUserData(new Coordinate3D(x, z, cubeSize - y - 1));
          getChildren().add(led);
          leds.add(led);
        }
      }
    }

    // add some axis
    Bounds b = getBoundsInLocal();

    Cylinder xAxis = new Cylinder(2, b.getMaxX());
    xAxis.setMaterial(new PhongMaterial(Color.RED));
    xAxis.getTransforms().add(new Rotate(90, Rotate.Z_AXIS));
    xAxis.setTranslateX(b.getMaxX() / 2);
    xAxis.setTranslateY(b.getMaxY() + 20);
    getChildren().add(xAxis);

    Cylinder yAxis = new Cylinder(2, b.getMaxZ());
    yAxis.setMaterial(new PhongMaterial(Color.BLUE));
    yAxis.getTransforms().add(new Rotate(90, Rotate.X_AXIS));
    yAxis.setTranslateX(-20);
    yAxis.setTranslateY(b.getMaxY() + 20);
    yAxis.setTranslateZ(b.getMaxZ() / 2);
    getChildren().add(yAxis);

    Cylinder zAxis = new Cylinder(2, b.getMaxX());
    zAxis.setMaterial(new PhongMaterial(Color.GREEN));
    zAxis.setTranslateX(-20);
    zAxis.setTranslateY(b.getMaxY() / 2);
    getChildren().add(zAxis);
  }
Пример #5
0
  private void advanceBall() {
    double refAngle = 0;
    boolean doBounce = false;
    double jitter = 0;

    if (ballBounds.getMaxY() >= rectBounds.getMinY()) {
      if (ballBounds.getMaxX() < rectBounds.getMinX()
          || ballBounds.getMinX() > rectBounds.getMaxX()) {
        isExploding = true;
        ball.setFill(Color.RED);
      } else {
        // calculate a value between -0.5 and 0.5 which corresponds to the
        // position within the platform where the ball bounces
        double pos = (ball.getTranslateX() - rect.getTranslateX()) / rect.getWidth();
        if (pos < 0) {
          pos = 0;
        }
        if (pos > 1) {
          pos = 1;
        }
        pos = pos - 0.5;

        // system.err.printf("%s\n", pos);
        jitter = pos;
        doBounce = true;
      }
    }

    if (ballBounds.getMinY() <= areaBounds.getMinY()
        || ballBounds.getMaxY() >= areaBounds.getMaxY()) { // this must never happen!
      doBounce = true;
    } else if (ballBounds.getMinX() <= areaBounds.getMinX()
        || ballBounds.getMaxX() >= areaBounds.getMaxX()) {
      doBounce = true;
      refAngle = Math.PI / 2;
    }

    if (doBounce) {
      ballAngle = calculateExitAngle(ballAngle, refAngle) + jitter;
      dx = ballSpeed * Math.cos(ballAngle);
      dy = ballSpeed * Math.sin(ballAngle);
    }

    ball.setTranslateX(ball.getTranslateX() + dx);
    ball.setTranslateY(ball.getTranslateY() - dy);
  }
Пример #6
0
 private void handleExplode() {
   if (ballBounds.getMinY() > areaBounds.getMaxY()) {
     isExploding = false;
     resetBall();
   } else {
     ball.setTranslateX(ball.getTranslateX() + dx);
     ball.setTranslateY(ball.getTranslateY() - dy);
   }
 }
  private static Bounds unionOfBounds(Bounds b1, Bounds b2) {
    final Bounds result;

    if (b1.isEmpty()) {
      result = b2;
    } else if (b2.isEmpty()) {
      result = b1;
    } else {
      final double minX = Math.min(b1.getMinX(), b2.getMinX());
      final double minY = Math.min(b1.getMinY(), b2.getMinY());
      final double minZ = Math.min(b1.getMinZ(), b2.getMinZ());
      final double maxX = Math.max(b1.getMaxX(), b2.getMaxX());
      final double maxY = Math.max(b1.getMaxY(), b2.getMaxY());
      final double maxZ = Math.max(b1.getMaxZ(), b2.getMaxZ());

      assert minX <= maxX;
      assert minY <= maxY;
      assert minZ <= maxZ;

      result = new BoundingBox(minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ);
    }

    return result;
  }
  /** Update the popup location below the anchor node. */
  @Override
  protected void updatePopupLocation() {
    final Bounds anchorBounds = getAnchor().getLayoutBounds();
    Point2D popupLocation;

    assert anchorBounds != null;

    // At exit time, closeRequestHandler() is not always called.
    // So this method can be invoked after the anchor has been removed the
    // scene. This looks like a bug in FX...
    // Anway we protect ourself by checking.
    if (getAnchor().getScene() != null) {
      popupLocation = getAnchor().localToScreen(anchorBounds.getMinX(), anchorBounds.getMaxY());
      getPopup().setX(popupLocation.getX());
      getPopup().setY(popupLocation.getY());
    }
  }
Пример #9
0
 public Pair<CoordinatePair, CoordinatePair> addAnchorLines(ComponentView componentView) {
   Bounds bounds = componentView.getBoundsInParent();
   // Left Anchor wire
   CoordinatePair pair1 =
       new CoordinatePair(bounds.getMinX() - Component.OFFSET, bounds.getMaxY() / 2);
   // Right Anchor wire
   CoordinatePair pair2 =
       new CoordinatePair(bounds.getMaxX() + Component.OFFSET, bounds.getMaxY() / 2);
   Line line1 =
       new Line(
           bounds.getMinX(),
           bounds.getMaxY() / 2,
           bounds.getMinX() - Component.OFFSET,
           bounds.getMaxY() / 2);
   Line line2 =
       new Line(
           bounds.getMaxX(),
           bounds.getMaxY() / 2,
           bounds.getMaxX() + Component.OFFSET,
           bounds.getMaxY() / 2);
   componentView.getChildren().addAll(line1, line2);
   return new Pair(pair1, pair2);
 }