Вы можете изменить arcWidth
/ arcHeight
свойства 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();
}