Issue
I'm trying to find a JavaFX method to detect if a coordinate lies within a closed Path.
I've created the following example, and researched various methods, however nothing works as I wish, that is only returns true when inside the non-rectangular shape.
- Node.contains() -- only works on edge of shape, not the inside
- Node.intersect() -- only works on rectangular bounding box
- Shape.intersects() -- only works on edge of shape, not the inside
I could just use the JTS library, but I can't help but think there must be a JavaFX native method for this.
public class ShapeContainsTest extends Application {
public static void main(String[] args) {
Application.launch(ShapeContainsTest.class);
}
@Override
public void start(Stage primaryStage) throws Exception {
Path path = new Path();
path.getElements().add(new MoveTo(100, 100));
path.getElements().add(new LineTo(200, 100));
path.getElements().add(new LineTo(150, 200));
path.getElements().add(new ClosePath());
Pane pane = new Pane(path);
pane.setPrefSize(300, 300);
pane.setOnMouseMoved(event -> {
System.out.println("Contains? " + path.contains(event.getX(), event.getY()));
System.out.println("Intersect? " + path.intersects(event.getX(), event.getY(), 1, 1));
Circle point = new Circle(event.getX(), event.getY(), 1);
System.out.println("Intersects() " + Shape.intersect(path, point));
});
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
}
Solution
Construct a path with a fill, any fill value will work, it doesn't matter the color or even the opacity of the fill color.
As noted by mipa in comments:
The important point is that the Shape must have a color set. Otherwise it is considered as hollow and you will not get a hit when you are fully inside the outline.
Shape.intersect(path, point)
will function like a contains only when the shape is filled, otherwise, it will return an empty shape when calculating an intersection with the unfilled interior of the shape.
If you don't want the fill to visible you can write:
path.setFill(Color.TRANSPARENT);
The intersection will still work inside the shape when it is filled with a transparent color.
There are different algorithms that could be used to determine the fill. JavaFX defines a couple of preset rules that can be used to adjust the fill algorithm, if needed, using path.setFillRule().
Answered By - jewelsea
Answer Checked By - Gilberto Lyons (JavaFixing Admin)