Reputation: 35
How can I restrict the motion of the blue circle (due to a mouse drag) only on the red circle path? Should I use polar coordinates? (x=rcos(θ), y=rsin(θ))?
The code I created till now let me drag the blue point all over the stage. I want the center of the blue point to follow the red circle.
package circlemouse;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class CircleMouse extends Application {
private double initY;
private double dragAnchorY;
private double initX;
private double dragAnchorX;
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
Scene scene = new Scene(pane, 500, 500);
primaryStage.setResizable(false);
//stage center
double x0 = pane.getWidth() / 2.0;
double y0 = pane.getHeight() / 2.0;
Line horizontalLine = new Line(0.0, y0, 2.0 * x0, y0);
Line vertical = new Line(x0, 0.0, x0, 2.0 * y0);
//red circle (path of point)
double r = 100.0;
Circle c = new Circle(x0, y0, r);
c.setFill(null);
c.setStroke(Color.RED);
//the point
double pointRadius = 15.0;
Circle point = new Circle(x0 + r, y0, pointRadius);
point.setFill(Color.BLUE);
point.setOnMousePressed((MouseEvent me) -> {
initY = point.getCenterY();
dragAnchorY = me.getSceneY();
initX = point.getCenterX();
dragAnchorX = me.getSceneX();
});
point.setOnMouseDragged((MouseEvent me) -> {
double dragY = me.getSceneY() - dragAnchorY;
double newY = initY + dragY;
point.setCenterY(newY);
double dragX = me.getSceneX() - dragAnchorX;
double newX = initX + dragX;
point.setCenterX(newX);
});
pane.getChildren().addAll(horizontalLine, vertical, c, point);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 0
Views: 1154
Reputation: 209319
If you draw a line from the center of the red circle to where the mouse is, and then draw a line from the center of the red circle to where you want the point, they are obviously in the same direction, and the length of the line from the center of the red circle to where you want the point is just the radius of the line.
So in vector terminology, the vector from the center of the circle to the new point position is the radius of the circle times the unit vector in the direction from the center of the circle to the mouse.
The Point2D
API allows you to interpret a Point2D
as a vector, and has useful methods for computing the unit vector (normalize()
), multiplying by a scalar, adding and subtracting other vectors, etc.
So:
point.setOnMouseDragged((MouseEvent me) -> {
Point2D redCenter = new Point2D(c.getCenterX(), c.getCenterY());
Point2D mouse = new Point2D(me.getX(), me.getY());
Point2D centerToMouse = mouse.subtract(redCenter);
Point2D centerToNewPoint = centerToMouse.normalize().multiply(c.getRadius());
Point2D newPoint = centerToNewPoint.add(redCenter);
point.setCenterX(newPoint.getX());
point.setCenterY(newPoint.getY());
});
Upvotes: 2