2016-11-15 4 views
0

후 도면의 화살표에 여분의 수평 공간 내 코드의이 부분이 있습니다자바 FX 회전

Group g = new Group(); 

double xMid = (end.getCenterX() - start.getCenterX())/2; 
double yMid = (end.getCenterY() - start.getCenterY())/2; 
Line a = new Line(xMid, yMid-4, xMid, yMid+4); 
Line b = new Line(xMid, yMid-4, xMid-10, yMid); 
Line c = new Line(xMid, yMid+4, xMid-10, yMid); 

g.getChildren().add(a); 
g.getChildren().add(b); 
g.getChildren().add(c); 

g.setRotate(getAngle(start, end)); 
g.setTranslateX(start.getCenterX()); 
g.setTranslateY(start.getCenterY()); 

위의 코드는 start에서 end에가는 라인의 중간에 화살표를 그리기에 대한 책임 (이들은 시작 지점과 종료 지점으로 작용하는 Circle입니다). 화살표는 올바른 방향으로 회전해야합니다. 다음은 이러한 여러 화살표 라인 출력이다 : 보시

output

는 각도가 ± 90 °에 가까운 경우, 왼쪽으로 시프트있다. 변환 및 효과이 그룹의 아이들에 직접 설정되어있는 경우

가 [...] 그이 그룹의 레이아웃 범위에 포함됩니다 :

나는 것을 read.

하지만 실제로이 문제를 해결하는 데 도움이되지 않았습니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

+0

혼란 스럽 습니다만, 결국 번역은 무엇입니까? 화살표가 끝에서 시작을 가리키고 있지 않습니까? 변화에 관해서는 layoutBounds를 보셨습니까? 회전의 피벗은 layoutBounds의 중심이므로 삼각형의 중심이 아닌 경우 교대를 설명 할 수 있습니다. – Lidae

+0

@Lidae 화살표가 회전 된 다음 올바른 위치 (선의 중간)로 이동합니다. 그러므로 번역. – alex

+0

하지만 화살표가 안쪽으로 향하지 않는 한 그들은 번역하기 전에 이미 올바른 위치에 있지만 화살표 머리가 잘못된 방향으로 향하고 있습니다. – Lidae

답변

1

먼저 삼각형을 형성 3 개 라인이 가장 쉬운 있습니다 Polygon을 사용하십시오.

당신이 Rotate 변환을 사용할 수, 레이아웃 경계를 기반으로 선택되는 피벗 점을 해결하려면하고 Translatetransform들로 변환하거나 자신의 두 행렬의 연결을 계산하고 사용 Affine :

private static final double[] POLYGON_POINTS = { 
    -5, -4, 
    -5, 4, 
    5, 0 
}; 

private static void makeArrow(Pane parent, Circle start, Circle end, double t) { 
    Polygon arrow = new Polygon(POLYGON_POINTS); 
    arrow.setFill(null); 
    arrow.setStroke(Color.BLACK); 
    double dx = end.getCenterX() - start.getCenterX(); 
    double dy = end.getCenterY() - start.getCenterY(); 

    double d = Math.hypot(dx, dy); 

    double sin = dy/d; 
    double cos = dx/d; 

    // matrix: 
    // [ cos  -sin  0 t * dx + start.getCenterX() ]   
    // [ sin  cos  0 t * dy + start.getCenterY() ]   
    // [ 0  0  1     0   ]   
    // [ 0  0  0     1   ] 
    Affine affine = new Affine(cos, -sin, t * dx + start.getCenterX(), sin, cos, t * dy + start.getCenterY()); 

    arrow.getTransforms().add(affine); 
    parent.getChildren().add(arrow); 
} 

@Override 
public void start(Stage primaryStage) { 
    Circle end = new Circle(200, 20, 5); 
    Circle start = new Circle(20, 200, 5); 
    Line line = new Line(start.getCenterX(), start.getCenterY(), end.getCenterX(), end.getCenterY()); 

    Pane root = new Pane(line, start, end); 

    makeArrow(root, start, end, 0.5); 

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

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

좋고 간단합니다. 감사! – alex

0

상향선과 화살표가 함께있는 그룹을 만든 다음이 그룹을 가운데로 회전하는 것이 더 쉽다고 생각합니다.

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 
     try { 
      Pane root = createPane(); 
      root.setTranslateX(200); 
      root.setTranslateY(200); 
      Scene scene = new Scene(root,400,400); 
      primaryStage.setScene(scene); 
      primaryStage.show(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private Pane createPane() { 
     BorderPane root = new BorderPane(); 
     ArrowFactory arrowfactory = new ArrowFactory(); 
     double lineLength = 100; 
     double centerX = 0; 
     double centerY = 0; 
     root.getChildren().addAll(
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 0), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 30), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 45), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 60), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 90), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 135), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 180), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 225), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 270), 
      arrowfactory.createLineAndArrow(centerX, centerY, lineLength, 315) 
      ); 
     return root; 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

} 

ArrayFactory.java : 당신이 사용할 수있는 입력으로 원 센터를 사용

public class ArrowFactory { 
    private final int arrowWidth = 10; 
    private final int arrowHeight = 10; 

    public Group createLineAndArrow(double centerX, double centerY, double lineLength, double rotation) { 
     Group group = new Group(); 

     Line line = new Line(centerX, centerY, centerX, centerY - lineLength); 
     Polygon upwardArrow = createUpwardArrow(centerX, centerY - lineLength/2); 

     group.getChildren().addAll(line, upwardArrow); 
     group.getTransforms().add(new Rotate(rotation, centerX, centerY)); 
     return group; 
    } 

    private Polygon createUpwardArrow(double centerX, double centerY) { 
     Polygon arrow = new Polygon(
       createUpwardArrowPoints(centerX, centerY + arrowHeight/2)); 
     arrow.setFill(Color.TRANSPARENT); 
     arrow.setStroke(Color.BLACK); 
     return arrow; 
    } 

    private double[] createUpwardArrowPoints(double centerX, double centerY) { 
     return new double[] { 
      centerX - arrowWidth/2, centerY, // left 
      centerX + arrowWidth/2, centerY, // right 
      centerX, centerY - arrowHeight,  // top 
       }; 
    } 
} 

enter image description here

:

private Group createLineAndArrow(double x1, double y1, double x2, double y2) { 
     double distance = Math.hypot(x1-x2, y1-y2); 
     double angle = Math.toDegrees(Math.atan2(x2 - x1, y2 - y1)); 
     return arrowfactory.createLineAndArrow(x1, y1, distance, angle); 
}