如何在旋转变换后在JavaFX中设置形状的透视?

时间:2016-07-18 18:11:55

标签: javafx rotation pivot transform shape

我正在尝试在旋转的矩形上移动左上角并保持右下角固定。但是在更新矩形的枢轴之后,矩形会跳跃。如何正确设置角落,以便在更新枢轴后不会发生跳跃?该示例说明了该问题。单击按钮后绿色和蓝色矩形不同!有没有想法?可以帮助'deltaTransform'程序吗?

import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.NonInvertibleTransformException;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class RotateTest extends Application {

    Rectangle rect0,rect1, rect2;

    @Override
    public void start(Stage primaryStage) {

        rect0 = new Rectangle(100, 100, 200, 100); //start rect to compare
        rect0.setFill(Color.TRANSPARENT);
        rect0.setStroke(Color.GREEN);
        rect0.setStrokeWidth(1.5); 
        rect0.setRotate(20);

        rect1 = new Rectangle(100, 100, 200, 100); // moved rect
        rect1.setFill(Color.TRANSPARENT);
        rect1.setStroke(Color.RED);
        rect1.setStrokeWidth(1.5);
        rect2 = new Rectangle(100, 100, 200, 100);// unmoved rect
        rect2.setFill(Color.TRANSPARENT);
        rect2.setStrokeWidth(1.5);
        rect2.setStroke(Color.BLUE);

        Rotate rotate = new Rotate(20, rect1.getX() + rect1.getWidth() / 2., rect1.getY() + rect1.getHeight() / 2.);
        rect1.getTransforms().add(rotate);
        rect2.getTransforms().add(rotate);

        Button btn = new Button();
        btn.setText("Move to target");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                try {
                    Point2D p1ns = new Point2D(150, 50); //target for upper left corner in transformed system
                    Point2D p1n = rotate.inverseTransform(p1ns);//target for upper left corner in nontransformed system
                    Point2D p2 = new Point2D(rect1.getX()+rect1.getWidth(), rect1.getY()+rect1.getHeight());
                                                    //bottom right corner in nontransformed system
                    Point2D p2s = rotate.transform(p2);//bottom right corner in transformed system

                    rect1.setX(p1n.getX());
                    rect1.setY(p1n.getY());
                    rect1.setWidth(p2.getX()-p1n.getX());
                    rect1.setHeight(p2.getY()-p1n.getY());

                    //this make the problem:
                    rotate.setPivotX(rect1.getX() + rect1.getWidth() / 2.);
                    rotate.setPivotY(rect1.getY() + rect1.getHeight() / 2.);                    

                } catch (NonInvertibleTransformException ex) {
                    Logger.getLogger(RotateTest.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        Group root = new Group();
        for (int i = 0; i < 10; i++) {
            Line l1 = new Line(i * 100, 0, i * 100, 400);
            Line l2 = new Line(0, i * 100, 1000, i * 100);
            root.getChildren().addAll(l1, l2);
        }

        root.getChildren().addAll(btn, rect0, rect1, rect2);

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

        primaryStage.setTitle("Rotation");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

2 个答案:

答案 0 :(得分:1)

现在我找到了解决方案。辅助临时Rotate-object有帮助!立即查看代码!绿色和红色矩形的右下角相同!

 @Override
            public void handle(ActionEvent event) {
                try {
                    Point2D p1s = new Point2D(150, 50); //target for upper left corner in transformed system
                    Point2D p2s = rotate.transform(rect1.getX()+rect1.getWidth(), rect1.getY()+rect1.getHeight());//bottom right corner in transformed system

                    Rotate rotTemp=new Rotate(rotate.getAngle(), (p1s.getX() + p2s.getX() )/ 2., (p1s.getY() + p2s.getY() )/ 2.);

                Point2D q1 = rotTemp.inverseTransform(p1s);
                Point2D q2 = rotTemp.inverseTransform(p2s);

                rect1.setX(q1.getX());
                rect1.setY(q1.getY());
                rect1.setWidth(q2.getX()-q1.getX());
                rect1.setHeight(q2.getY()-q1.getY());
                rotate.setPivotX(rotTemp.getPivotX());
                rotate.setPivotY(rotTemp.getPivotY());
            } catch (NonInvertibleTransformException ex) {
                Logger.getLogger(RotateTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

答案 1 :(得分:0)

您可以随时修改矩形的右下角,并更改表单的属性:

x      -> x + deltaX ;
y      -> y + deltaY ;
width  -> width - deltaX ;
height -> height - deltaY ;

所以你可以做到

btn.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        try {

            Point2D targetAbsolute = new Point2D(150, 50);
            Point2D targetLocal = rotate.inverseTransform(targetAbsolute);
            double newX = targetLocal.getX() ;
            double newY = targetLocal.getY() ;

            double deltaX = newX - rect1.getX();
            double deltaY = newY - rect1.getY();

            rect1.setX(newX);
            rect1.setY(newY);
            rect1.setWidth(rect1.getWidth() - deltaX);
            rect1.setHeight(rect1.getHeight() - deltaY);

        } catch (NonInvertibleTransformException ex) {
            Logger.getLogger(RotateTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
});