JavaFX修改旋转支点后矩形跳动问题求助
解决JavaFX矩形拖动旋转支点后跳动问题
问题描述
我需要拖动矩形的旋转支点来进行旋转操作,目前已实现矩形围绕新支点旋转,但矩形会出现跳动现象。推测需要对矩形进行平移处理,但不知道具体如何操作,希望矩形在更换支点后能保持原有位置,以便进行后续旋转操作。
问题原因
当旋转支点(pivot)改变时,Rotate变换的基准点发生了变化,而矩形当前的视觉位置是基于旧支点旋转后的结果,直接切换新支点会导致旋转基准偏移,从而出现跳动。需要计算支点移动的偏移量,并将其转换为矩形的平移量,抵消位置变化。
解决方案
在拖动支点释放后,通过以下步骤调整矩形位置:
- 计算旧支点到新支点的偏移量
- 根据当前旋转角度,将偏移量转换为矩形局部坐标系下的平移量
- 应用平移量到矩形,保持视觉位置不变
修改后的完整代码
import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.scene.shape.Rectangle; import javafx.scene.transform.Rotate; import javafx.stage.Stage; import java.io.IOException; public class T5_4_Rotar_PivotXY_2 extends Application { double anguloFinal = 0; double pivoteX = 250; // initial rotate pivotX double pivoteY = 150; // initial rotate pivotY @Override public void start(Stage stage) throws IOException { Pane pane = new Pane(); Scene scene = new Scene(pane,500,500); double x0 = 50; double y0 = 50; double ancho = 200; // width double alto = 100; // height Rectangle r = new Rectangle(x0, y0, ancho, alto); r.setFill(Color.YELLOW); // pivot simbol Circle circle1 = new Circle(pivoteX,pivoteY,4); circle1.setFill(Color.TRANSPARENT); circle1.setStroke(Color.BLACK); Line line1 = new Line(pivoteX-6,pivoteY,pivoteX+6,pivoteY); Line line2 = new Line(pivoteX,pivoteY-6,pivoteX,pivoteY+6); Group centro = new Group(circle1,line1,line2); pane.getChildren().addAll(r,centro); Rotate rotacion = new Rotate(); rotacion.setPivotX(pivoteX); rotacion.setPivotY(pivoteY); r.getTransforms().add(rotacion); // Rotation event pane.setOnMousePressed(e1 -> { pane.setOnMouseDragged(e2 -> { double anguloPressed = Math.toDegrees(Math.atan2((e1.getSceneY() - pivoteY),(e1.getSceneX() - pivoteX))); double anguloDragged = Math.toDegrees(Math.atan2((e2.getSceneY() - pivoteY),(e2.getSceneX() - pivoteX))); double angulo = anguloDragged - anguloPressed + anguloFinal; rotacion.setAngle(angulo); pane.setOnMouseReleased(e3 -> { anguloFinal = angulo; }); }); }); // Dragging the pivot centro.setOnMousePressed(e1 -> { centro.setOnMouseDragged(e2 -> { centro.setTranslateX(e2.getSceneX() - e1.getSceneX()); centro.setTranslateY(e2.getSceneY() - e1.getSceneY()); e2.consume(); centro.setOnMouseReleased(e3 -> { centro.setLayoutX(centro.getLayoutX() + centro.getTranslateX()); centro.setLayoutY(centro.getLayoutY() + centro.getTranslateY()); centro.setTranslateX(0); centro.setTranslateY(0); // 记录旧支点位置 double oldPivotX = pivoteX; double oldPivotY = pivoteY; // 新支点 pivoteX = centro.getLayoutX() + 250; pivoteY = centro.getLayoutY() + 150; // 计算支点偏移量 double dx = pivoteX - oldPivotX; double dy = pivoteY - oldPivotY; // 当前旋转角度(弧度) double angleRad = Math.toRadians(rotacion.getAngle()); // 将偏移量旋转转换为矩形局部平移量,抵消支点变化影响 double translateX = dx * Math.cos(angleRad) + dy * Math.sin(angleRad); double translateY = -dx * Math.sin(angleRad) + dy * Math.cos(angleRad); // 应用平移保持矩形位置不变 r.setTranslateX(r.getTranslateX() + translateX); r.setTranslateY(r.getTranslateY() + translateY); // 更新旋转支点 rotacion.setPivotX(pivoteX); rotacion.setPivotY(pivoteY); }); }); }); stage.setTitle("T5 4 Rotate PivotXY 2"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } }
关键代码说明
- 记录旧支点位置,计算新支点与旧支点的偏移量
dx、dy - 将旋转角度转换为弧度,使用旋转矩阵计算矩形需要的平移量(适配当前旋转状态)
- 更新矩形的
translateX和translateY,抵消支点变化带来的位置偏移 - 最后更新旋转变换的支点参数
内容的提问来源于stack exchange,提问作者user23254466
相关产品推荐
相关产品推荐

