-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
P4
-
Affects Version/s: jfx25
-
Component/s: javafx
-
None
When a Scene or SubScene has its width or height set to 0, coordinate transformations stop working because the transformation matrix contains NaNs. This is a consequence of divisions by zero in both parallel and perspective projections.
Even though a 0x0 scene is mathematically degenerate, it is still desirable for coordinate transformation APIs to remain numerically well-behaved and return finite results whenever possible, rather than being poisoned by NaN/Infinity.
Here is an application that demonstrates the failing coordinate transformations. Click on the buttons to resize the SubScene and observe the console output:
public class ZeroSizeSubScene extends Application {
@Override
public void start(Stage stage) {
var rect = new Rectangle(50, 50, Color.RED);
var subScene = new SubScene(new Group(rect), 100, 100);
subScene.setFill(Color.GRAY);
// Also try a perspective camera:
//
// var camera = new PerspectiveCamera();
// camera.setRotate(45);
// camera.setTranslateX(-20);
// camera.setRotationAxis(new Point3D(0, 1, 0));
// subScene.setCamera(camera);
class MyButton extends Button {
public MyButton(String text, double width, double height) {
super(text);
setOnAction(_ -> {
var timeline = new Timeline(
new KeyFrame(Duration.seconds(1), new KeyValue(subScene.widthProperty(), width)),
new KeyFrame(Duration.seconds(1), new KeyValue(subScene.heightProperty(), height)));
timeline.setOnFinished(_ -> {
Point2D p0 = rect.localToScreen(0, 0);
System.out.println("rect.localToScreen(0, 0) = " + p0);
});
timeline.play();
});
}
}
VBox.setMargin(subScene, new Insets(0, 0, 20, 0));
var root = new VBox(5,
subScene,
new CheckBox("Rotate SubScene") {{ setOnAction(_ -> subScene.setRotate(isSelected() ? 45 : 0)); }},
new MyButton("Size: 100x100", 100, 100),
new MyButton("Size: 10x10", 10, 10),
new MyButton("Size: 100x0", 100, 0),
new MyButton("Size: 0x100", 0, 100),
new MyButton("Size: 0x0", 0, 0)
);
Scene scene = new Scene(root, 300, 300);
stage.setScene(scene);
stage.show();
}
}
Even though a 0x0 scene is mathematically degenerate, it is still desirable for coordinate transformation APIs to remain numerically well-behaved and return finite results whenever possible, rather than being poisoned by NaN/Infinity.
Here is an application that demonstrates the failing coordinate transformations. Click on the buttons to resize the SubScene and observe the console output:
public class ZeroSizeSubScene extends Application {
@Override
public void start(Stage stage) {
var rect = new Rectangle(50, 50, Color.RED);
var subScene = new SubScene(new Group(rect), 100, 100);
subScene.setFill(Color.GRAY);
// Also try a perspective camera:
//
// var camera = new PerspectiveCamera();
// camera.setRotate(45);
// camera.setTranslateX(-20);
// camera.setRotationAxis(new Point3D(0, 1, 0));
// subScene.setCamera(camera);
class MyButton extends Button {
public MyButton(String text, double width, double height) {
super(text);
setOnAction(_ -> {
var timeline = new Timeline(
new KeyFrame(Duration.seconds(1), new KeyValue(subScene.widthProperty(), width)),
new KeyFrame(Duration.seconds(1), new KeyValue(subScene.heightProperty(), height)));
timeline.setOnFinished(_ -> {
Point2D p0 = rect.localToScreen(0, 0);
System.out.println("rect.localToScreen(0, 0) = " + p0);
});
timeline.play();
});
}
}
VBox.setMargin(subScene, new Insets(0, 0, 20, 0));
var root = new VBox(5,
subScene,
new CheckBox("Rotate SubScene") {{ setOnAction(_ -> subScene.setRotate(isSelected() ? 45 : 0)); }},
new MyButton("Size: 100x100", 100, 100),
new MyButton("Size: 10x10", 10, 10),
new MyButton("Size: 100x0", 100, 0),
new MyButton("Size: 0x100", 0, 100),
new MyButton("Size: 0x0", 0, 0)
);
Scene scene = new Scene(root, 300, 300);
stage.setScene(scene);
stage.show();
}
}
- links to
-
Review(master)
openjdk/jfx/1992