2016-07-18 3 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

감사합니다. 소라,하지만 그건 분명하고 문제는 아닙니다. 문제는 피벗입니다! 하지만 이제 해결책을 찾았습니다. 제 대답을보십시오. – user1878143

+0

충분히 공정하게; 요구 사항이 무엇인지 명확하지 않습니다 (즉 피봇을 이동해야하는 이유). –

+0

x, y, with, height 및 angle을 사용하여 사각형을 직렬화하려면 피벗을 사각형의 중심으로 설정하는 것이 중요합니다. – user1878143

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); 
      } 
     } 
관련 문제