0

我的应用程序有问题。我在鼠标的帮助下画线和点,我需要检测我是否与线相交或得到点。用点它工作得很好,但用线条它不起作用。我在 AnchorPane 中添加行。然后我发现,当光标位于 3 行(三角形)内时 - 它总是相交。这是我的例子:

ArrayList<Line> lines = new ArrayList<Line>();
    Line l1 = new Line(10, 150, 50, 10);
    Line l2 = new Line(10, 150, 100, 150);
    Line l3 = new Line(100, 150, 50, 10);
    lines.add(l1);
    lines.add(l2);
    lines.add(l3);

    for (int i=0; i<lines.size();++i) {
        if (lines.get(i).intersects(48, 48, 4, 4)) {
            System.out.println("found a bug!" + " line #"+i);
        }
    }

如果有人知道答案——那就太好了!

4

1 回答 1

1

我会想象您的问题是:如何通过单击线条的两个像素内的任意位置来选择线条?

在下面的示例输出中,用户刚刚在非常靠近三角形右侧的线处单击,导致该线被突出显示。

样本输出

下面的代码通过测试窗格中的每个形状并查看该形状是否与鼠标按下位置两侧 2 像素的矩形框相交来工作。该解决方案与解决方案中使用的解决方案非常相似:Checking Collision of Shapes with JavaFX

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class LinePicker extends Application {
  public static void main(String[] args) { Application.launch(LinePicker.class); }

  @Override public void start(final Stage stage) throws Exception {
    final Pane pane = new Pane();

    pane.getChildren().setAll(
      new Line( 10, 150,  50,  10),
      new Line( 10, 150, 100, 150),
      new Line(100, 150,  50,  10)
    );

    pane.setPrefSize(
      200, 200
    );

    Scene scene = new Scene(addPickHandler(pane));
    stage.setScene(scene);
    stage.show();
  }

  private Pane addPickHandler(final Pane pane) {
    pane.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent event) {
        final Rectangle hotspot = new Rectangle(
          event.getX() - 2, 
          event.getY() - 2, 
          4, 
          4
        );

        for (Node child : pane.getChildren()) {
          if (child instanceof Shape) {
            final Shape shape = (Shape) child;

            Shape intersect = Shape.intersect(shape, hotspot);
            if (intersect.getBoundsInLocal().getWidth() != -1) {
              shape.setStyle("-fx-stroke: red;");
            } else {
              shape.setStyle("-fx-stroke: black;");
            }
          }
        }
      }
    });

    return pane;
  }
}

评论

为什么 shved90 无法在他的应用程序中为他提供上述解决方案,这让我有点困惑。

Shev 评论说:“在 Line 中,据我了解,它会检查所有边界,如果线有某个角度,它的边界会像矩形,因此我检查是否发现了它(不仅在线和最近的点)。但我需要几何运算。

然而,这里提出的解决方案是基于几何的解决方案,因为点击热点必须与实际线相交,而不是与包围线的矩形边界相交。这是因为解决方案中使用的Shape.intersect方法适用于所涉及的实际形状的交集,而不是所涉及的形状的边界。

但是请注意,在 shved90 的原始问题中,他使用的是Node intersects方法而不是该Shape.intersect方法。Node intersects 的文档指出“此函数的默认行为只是检查给定坐标是否与局部边界相交。”,从他的评论来看,这显然不是 shved90 想要的。

Shev 确实注意到“我在 javaFx 中找到了 Line2d 类,就像在 Java2D 中一样,我转换为这条线并使用它的交集”。我不建议使用与 JavaFX 捆绑在一起的Line2D类,因为它是一个私有的 com.sun api,不能保证在未来的 JavaFX 版本中存在或具有二进制向后兼容的 API。

于 2013-05-18T02:01:21.717 回答