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); }
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); }
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); }
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); }
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()); } }
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); }