【问题标题】:Rotate a polygon around its center using Rotate使用 Rotate 围绕其中心旋转多边形
【发布时间】:2021-06-19 15:34:26
【问题描述】:

我想在转换后在 Polygon 类中跟踪我的点。我在使用 JavaFX 中的 Rotate 类时遇到的问题是通过在 Piece 类中执行类似操作来获取旋转后的点位置:

double x = this.getPoints().get(0) + this.getLocalToParentTransform().getTx()
double y = this.getPoints().get(1) + this.getLocalToParentTransform().getTy()

它使用Translate 类工作,但是当我旋转时,坐标会随着旋转而以一个奇怪的枢轴点旋转,并且根本不跟随多边形,除非它旋转 360 度。 PiecePolygon 的子类。

    private double originalX;
    private double originalY;
    private double centerX;
    private double centerY;

    private void initializePiece(Piece piece, Pane pane, int i) {
        piece.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                originalX = event.getSceneX();
                originalY = event.getSceneY();
                centerX = piece.getCenterX();
                centerY = piece.getCenterY();
            }
        });

        piece.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (event.getButton() == MouseButton.PRIMARY) {
                    // Position of piece wrt. picked up position
                    double deltaX = event.getSceneX() - originalX;
                    double deltaY = event.getSceneY() - originalY;

                    Translate translate = new Translate();
                    translate.setX(deltaX);
                    translate.setY(deltaY);
                    piece.getTransforms().addAll(translate);

                    originalX = event.getSceneX();
                    originalY = event.getSceneY();
                }

                if (event.getButton() == MouseButton.SECONDARY) {
                    double deltaY = event.getSceneY() - originalY;
                    Rotate rotation = new Rotate(deltaY, centerX, centerY);
                    piece.getTransforms().add(rotation);
                    originalY = event.getSceneY();
                }
            }
        });
    }

这是来自Piececlass 的sn-p。

    public double getCenterX() {
        double avg = 0;
        for (int i = 0; i < this.getPoints().size(); i += 2) {
            avg += this.getPoints().get(i) + this.getLocalToParentTransform().getTx();
        }
        avg = avg / (this.getPoints().size() / 2);
        
        return avg;
    }

    public double getCenterY() {
        double avg = 0;
        for (int i = 1; i < this.getPoints().size(); i += 2) {
            avg += this.getPoints().get(i) + this.getLocalToParentTransform().getTy();
        }
        avg = avg / (this.getPoints().size() / 2);
        return avg;
    }

【问题讨论】:

    标签: javafx rotation polygon


    【解决方案1】:

    所有变换都在局部坐标系中应用,因此轴心点应在多边形的局部坐标系中给出,这“不知道”应用于它的变换。 IE。你应该只在它自己的坐标系中计算多边形的中心,而不是它的父坐标系。

    鼠标事件的getX()getY() 方法将给出事件源节点坐标系中的坐标,因此使用这些方法可以使计算相对容易。这是一个简单的例子(我计算了鼠标按下和多边形中心之间的当前角度,然后是拖动时的角度变化,而不是只使用y坐标;这感觉更自然。)

    import javafx.application.Application;
    import javafx.geometry.Point2D;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseButton;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Polygon;
    import javafx.scene.transform.Rotate;
    import javafx.scene.transform.Translate;
    import javafx.stage.Stage;
    
    public class DraggingTransforms extends Application {
        
        public static void main(String[] args) {
            Application.launch(args);
        }
        
        private double pressX ;
        private double pressY ;
        private double angle ;
    
        @Override
        public void start(Stage stage) throws Exception {
            Polygon poly = new Polygon(10, 10, 50, 10, 50, 0, 70, 20, 50, 40, 50, 30, 10, 30, 10, 10);
            poly.setFill(Color.web("#00b140"));
            Pane root = new Pane(poly);
            
            poly.setOnMousePressed(e -> {
                pressX = e.getX();
                pressY = e.getY();
                angle = computeAngle(poly, e);
            });
            
            poly.setOnMouseDragged(e -> {
                if (e.getButton() == MouseButton.PRIMARY) {
                    poly.getTransforms().add(new Translate(e.getX() - pressX, e.getY()-pressY));
                } else {
                    double delta = computeAngle(poly, e) - angle;
                    Rotate rotation = new Rotate(delta, computeCenterX(poly), computeCenterY(poly));
                    poly.getTransforms().add(rotation);
                }
            });
            
            Scene scene = new Scene(root, 800, 800);
            stage.setScene(scene);
            stage.show();
        }
    
        private double computeAngle(Polygon poly, MouseEvent e) {
            return new Point2D(computeCenterX(poly), computeCenterY(poly))
                       .angle(new Point2D(e.getX(), e.getY()));
        }
        
        private double computeCenter(int offset, Polygon poly) {
            double total = 0 ;
            for (int i = offset ; i < poly.getPoints().size(); i+=2) {
                total += poly.getPoints().get(i);
            }
            return total / (poly.getPoints().size() / 2);
        }
        
        private double computeCenterX(Polygon poly) {
            return computeCenter(0, poly);
        }
        private double computeCenterY(Polygon poly) {
            return computeCenter(1, poly);
        }
    
    }
    

    请注意,如果您确实需要将形状中的某个点的坐标转换为父坐标系,那么您所需要做的就是,例如,

    poly.getLocalToParentTransform()
         .transform(
              poly.getPoints().get(0), 
              poly.getPoints().get(1)
         )
    

    【讨论】:

    • 谢谢,这真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 2016-07-30
    • 2013-12-18
    • 2014-02-08
    • 2012-04-08
    • 1970-01-01
    • 2018-05-17
    相关资源
    最近更新 更多