如何在javafx中将形状从圆形变为矩形

问题描述 投票:0回答:1

我想使用javafx形状在javafx scene中将形状从圆形变为矩形。

Circle c = new Circle();
Rectangle r = new Rectangle();
javafx shapes
1个回答
1
投票

您可以将arcWidtharcHeight / Rectangle属性在0和矩形宽度/高度之间更改为在圆和矩形之间进行转换的一种方法:

@Override
public void start(Stage primaryStage) throws Exception {
    final double size = 100;

    Slider slider = new Slider(0, size, 0);
    Rectangle rect = new Rectangle(size, size);
    rect.arcHeightProperty().bind(slider.valueProperty());
    rect.arcWidthProperty().bind(slider.valueProperty());

    VBox vbox = new VBox(slider, rect);

    Scene scene = new Scene(vbox);
    primaryStage.setScene(scene);
    primaryStage.show();
}

编辑:对于任意正多边形,您需要使用带有ArcTo的路径。以下示例中的转换看起来与上面代码产生的转换不同。 (有关半径计算的数学详细信息,请参阅https://en.wikipedia.org/wiki/Circular_segment

/**
 * Create a regular "polygon" that can be transformed to a circle using the
 * circleliness property
 * 
 * @param sides       the number of sides of the polygon
 * @param centerX     the x coordinate of the center of mass of the polygon
 * @param centerY     the y coordinate of the center of mass of the polygon
 * @param radius      the distance of the corners of the polygon from the center
 *                    of mass
 * @param circeliness a property indiating approximately straight lines (value =
 *                    0) or circle (value = 1)
 * @return The path
 */
public static Path createPolygon(int sides, final double centerX, final double centerY, final double radius,
        final DoubleProperty circeliness) {
    if (sides < 3 || radius <= 0) {
        throw new IllegalArgumentException();
    }
    Path path = new Path(new MoveTo(centerX, centerY + radius));

    final double angleStep = Math.PI * 2 / sides;

    // side length
    final double c = 2 * radius * Math.sin(0.5 * angleStep);

    // max value for radius -> circle
    final double hMax = radius * (1 - Math.cos(0.5 * angleStep));

    final DoubleBinding radiusBinding = Bindings.createDoubleBinding(() -> {
        double h = hMax * circeliness.get();
        double result = c * c / (8 * h) + 0.5 * h;

        return Math.min(result, 500 * radius); // limit result, since for too large radii ArcTo stops working
    }, circeliness);

    for (int i = 1; i <= sides; i++) {
        double angle = angleStep * i;
        ArcTo arc = new ArcTo();
        arc.setX(centerX + radius * Math.sin(angle));
        arc.setY(centerY + radius * Math.cos(angle));
        arc.setLargeArcFlag(false);
        arc.radiusXProperty().bind(radiusBinding);
        arc.radiusYProperty().bind(radiusBinding);
        path.getElements().add(arc);
    }

    path.getElements().add(new ClosePath());

    return path;
}

@Override
public void start(Stage primaryStage) throws Exception {
    Slider slider = new Slider(0, 1, 0);

    StackPane layout = new StackPane(createPolygon(6, 0, 0, 50, slider.valueProperty()));

    Scene scene = new Scene(new VBox(slider, layout), 300, 250);
    primaryStage.setScene(scene);
    primaryStage.show();
}
© www.soinside.com 2019 - 2024. All rights reserved.