如何限制在一条线上拖动一个圆圈。 JavaFX的

时间:2017-11-16 19:48:20

标签: java javafx javafx-2

说我在窗格上有一个线条形状,我想在它上面有圆形。我如何限制圆圈的拖动,这样圆圈只能在线上左右拖动,但没有其他地方。

1 个答案:

答案 0 :(得分:0)

此实现遵循该行,并且不会通过行结束。

  

关注的关键是y = mx + bm = slope of lineb = y-intercept

     

这是一个粗略的实现:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication42 extends Application {

    @Override
    public void start(Stage primaryStage) {
        AnchorPane root = new AnchorPane();

        Line line = new Line(20, 120, 70, 170);
        line.setStrokeWidth(3);

        //When the line is clicked by the mouse add a circle
        line.setOnMouseClicked((mouseClickedEvent )->{
            Circle c1 = new Circle(mouseClickedEvent.getSceneX(), mouseClickedEvent.getSceneY(), 25, Color.BLUE);
            //When the circle is dragged follow the line
            c1.setOnMouseDragged(mouseDraggedEvent -> {
                double slope = lineSlope(line.getStartX(), line.getEndX(), line.getStartY(), line.getEndY());
                double yIntercept = yIntercept(slope, line.getStartX(), line.getStartY());
                c1.setCenterY(setCenterY(slope, mouseDraggedEvent.getSceneX(), yIntercept));
                c1.setCenterX(mouseDraggedEvent.getSceneX());

                //Bound checks to make sure circle does not go pass the line ends
                if(c1.getCenterX() > line.getEndX())
                {
                    c1.setCenterX(line.getEndX());
                }
                else if(c1.getCenterX() < line.getStartX())
                {
                    c1.setCenterX(line.getStartX());
                }

                if(c1.getCenterY() > line.getEndY())
                {
                    c1.setCenterY(line.getEndY());
                }
                else if(c1.getCenterY() < line.getStartY())
                {
                    c1.setCenterY(line.getStartY());
                }
            });
            root.getChildren().add(c1);
        });



        root.getChildren().add(line);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    double lineSlope(double x1, double x2, double y1, double y2)
    {
        if(x2 - x1 == 0)
        {
            return 0;
        }

        return (y2 - y1)/(x2 - x1);
    }

    double yIntercept(double slope, double x1, double y1)
    {
        return y1 - (slope * x1);
    }

    double setCenterY(double slope, double x, double  yIntercept)
    {
        return slope * x + yIntercept;
    }    
}