2016-07-18 57 views
0

我正试图在旋转的矩形上移动左上角并固定右下角。但是在矩形的枢轴更新之后,矩形会跳转。我如何正确设置角落,以便在更新枢轴后不会发生跳跃?这个例子说明了这个问题。点击按钮后绿色和蓝色矩形不同!有没有一个想法?可以帮助'deltaTransform'程序?如何在旋转转换后为JavaFX中的形状设置枢轴?

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); 
    } 

} 

回答

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); 
     } 
    } 
}); 
+0

谢谢。 Sorra,但这很明显,而不是问题。问题是枢轴!但我现在找到了一个解决方案 - 请参阅我的答案。 – user1878143

+0

够公平的;目前还不清楚你的要求是什么(即你为什么需要移动数据中心?)。 –

+0

如果你想用x,y,with,height和angle对长方形进行序列化,将pivot设置到矩形的中心是不必要的。 – user1878143

1

现在我已经找到了解决办法。辅助临时旋转对象有帮助!现在看代码!绿色和红色矩形具有相同的右下角!

@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); 
      } 
     }