2016-11-15 68 views
0

後繪製箭頭額外的水平空間我有我的這部分代碼:的JavaFX - 旋轉

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

上面的代碼負責在一條線上,肚裏從startend中間畫一個箭頭(這些是作爲起點和終點的Circle)。箭頭必須朝正確的方向旋轉。下面是輸出爲多行這樣的箭頭:

output

正如你可以看到,有如果角度接近±90°到左的移位。

read說:

[...]如果變換和效果直接設置在這個 組的孩子,那些將被納入本集團的佈局界限。

但它並沒有真正幫助我解決這個問題。你有什麼想法如何解決這個問題?

+0

我很困惑,最後的翻譯是什麼?你確定箭頭沒有指向從頭到尾嗎?至於這種轉變,你有沒有看過layoutBounds?旋轉的關鍵是layoutBounds的中心,所以如果這不是三角形的中心,那可能就是這個轉變的原因。 – Lidae

+0

@Lidae箭頭被旋轉,然後移動到正確位置 - 線條的中間。因此翻譯。 – alex

+0

但他們已經在翻譯之前,在正確的地方,除非箭頭指向內,但是然後箭頭指向錯誤的方式... – Lidae

回答

1

首先3線形成的三角形是最容易使用Polygon

要解決樞軸點基礎上,佈局界限被選擇,你可以使用一個Rotate變換和Translate轉化爲transform S或簡單地計算你自己的2點矩陣級聯和使用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); 
}