【发布时间】:2012-06-01 12:15:00
【问题描述】:
我在使用鼠标拖动事件在 javafx 中操作 Arc 形状时遇到问题
我有一个使用以下参数定义的 Arc:
- radiusX 和 radiusY : 整个椭圆的水平和垂直半径,该圆弧是其部分截面
- centerX,centerY : 圆弧的中心点
- startAngle:圆弧的起始角度(相对于水平轴)
- 长度:弧的角度范围,以度为单位
所以我需要的是在拖动时使弧的起始角度“跟随”鼠标移动:
当用户按下弧的起点(位于 startAngle 上)并拖动鼠标时,我需要计算由水平轴和从中心到鼠标位置的线形成的新起点角度
基本上问题是在给定一个点(鼠标位置)和其他给定参数(中心、长轴和短轴)的情况下计算圆弧的起始角度
我实际上在做的是用 Math.atan2 函数计算角度
newStartAngle = atan2(xMouse, yMouse)(假设中心 x, y 在 0,0)
但只有当圆弧是圆形时才有效(radiusX = radiusY)
另一种说法是:我需要弧的起点始终在从中心到鼠标位置的线上(所以我需要不断更新起点角度以使其跟随鼠标旋转移动)。 (我希望我已经说清楚了)
这里是示例的完整来源
import javafx.stage.Stage;
...
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
Group designer = createDesigner();
designer.setLayoutX(100);
designer.setLayoutY(200);
pane.getChildren().add(designer);
Scene sc = new Scene(pane, 600, 600);
primaryStage.setScene(sc);
primaryStage.show();
}
public static final double RX = 100;
public static final double RY = 50;
public static final double S_ANGLE = 45;
public static final double ARC_LENGTH = 90;
private Arc arc;
private Circle handle;
private Line connection;
double xMouse,yMouse;
public Group createDesigner() {
arc = new Arc();
arc.setRadiusX(RX);
arc.setRadiusY(RY);
arc.setStartAngle(S_ANGLE);
arc.setLength(ARC_LENGTH);
arc.setFill(Color.LIGHTBLUE);
arc.setType(ArcType.ROUND);
handle = new Circle();
handle.setRadius(5);
handle.setStroke(Color.BLACK);
handle.setFill(Color.TRANSPARENT);
handle.setCenterX(
RX * Math.cos(Math.toRadians(S_ANGLE))
);
handle.setCenterY(
-RY * Math.cos(Math.toRadians(S_ANGLE))
);
connection = new Line();
connection.startXProperty().bind(arc.centerXProperty());
connection.startYProperty().bind(arc.centerYProperty());
connection.endXProperty().bind(handle.centerXProperty());
connection.endYProperty().bind(handle.centerYProperty());
handle.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
xMouse = event.getX();
yMouse = event.getY();
handle.setCenterX(xMouse);
handle.setCenterY(yMouse);
double angleInRadians = Math.atan2(-yMouse, xMouse);
arc.setStartAngle(Math.toDegrees(angleInRadians));
}
});
return new Group(arc, connection, handle);
}
public static void main(String[] args) {
launch(args);
}
}
提前谢谢你
【问题讨论】: