2015-04-25 51 views
-2

我正在制作一些动画,其中有许多三角形物体在屏幕上移动。为了确保每个人都面临着旅行的方向,我需要以合适的角度旋转图像。查找表示从原点坐标移动方向的角度

我的问题是我的代码返回的角度不能准确地做到这一点。返回的值不会改变超过几度。

/** 
* Accepts two grid positions are arguments. The current position 
* of the object and the next grid position. Returns an angle representing 
* the direction of travel from the current position towards the next position. By converting the Cartesian coordinates into polar coordinates. 
* 
*/ 
public void setAngle(Vector2d currentPos, Vector2d nextPos) { 
    Double delta_x = current.xPos - next.xPos; 
    Double delta_y = current.yPos - next.yPos; 
    Double theta = Math.atan2(delta_y, delta_x); 
    this.angle = theta; 
} 


Example: 

|| current: 1031.1438073417544 , 268.3133503758045 || next: 1033.101761841174 , 269.0819944286846 || Angle: 0.0 

|| current: 1033.1901579769194 , 242.19363555578593 || next: 1035.1281222295695 , 243.08778242413436 || Angle: 0.0 

|| current: 1022.1577455080815 , 255.24422527831163 || next: 1024.0301966330894 , 256.19078788718997 || Angle: 0.0 
+0

你的问题是不可能的,没有看到一些代码来回答。请注意,Math trig函数以弧度为单位,但JavaFX旋转以度为单位。 –

+0

我已添加代码。希望这可以帮助。 –

+0

你知道,输出中当前的pos和next pos值是相同的吗? – Roland

回答

1
// calc the deltas as next minus current 
double delta_x = next.xPos - current.xPos; 
double delta_y = next.yPos - current.yPos; 

// Calc the angle IN RADIANS using the atan2 
double theta = Math.atan2(delta_y, delta_x); 

// this.angle is now in degrees 
// or leave off *180/Math.PI if you want radians 
this.angle = theta*180/Math.PI; 
+0

当做这样的计算时,应该使用“double”而不是“Double”。如果你不这样做,那么一旦你做了更复杂的计算,你将会遭受巨大的性能损失。 – mipa

+0

@mipa感谢您的领导。我从'Double'编辑为'double'。 :-) – markE

+0

为什么要乘以180/PI? –

0

下面是如何创建一个完整的例如

一个节点(三角形)移动到的路径(由Uluk椭圆路径)。在每次移动期间,节点的旋转被计算和调整。

public class Main extends Application { 

    double prevX = 0; 
    double prevY = 0; 

    double radiusX = 200; 
    double radiusY = 100; 

    double centerX = 600; 
    double centerY = 200; 

    @Override 
    public void start(Stage primaryStage) { 

     try { 

      // race track 
      Path path = new Path(); 

      MoveTo moveTo = new MoveTo(centerX - radiusX, centerY - radiusY); 

      ArcTo arcTo = new ArcTo(); 
      arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celsius circle. 
      arcTo.setY(centerY - radiusY); 
      arcTo.setSweepFlag(false); 
      arcTo.setLargeArcFlag(true); 
      arcTo.setRadiusX(radiusX); 
      arcTo.setRadiusY(radiusY); 

      path.getElements().add(moveTo); 
      path.getElements().add(arcTo); 
      path.getElements().add(new ClosePath()); 

      path.setFill(Color.TRANSPARENT); 
      path.setStroke(Color.LIGHTGRAY); 
      path.setStrokeWidth(40); 


      Pane root = new Pane(); 

      // car: arrow pointing right 
      Polygon arrow = new Polygon(0, 0, 20, 10, 0, 20); 

      root.getChildren().addAll(path, arrow); 

      // lawn 
      Scene scene = new Scene(root, 800, 400, Color.GREEN); 
      primaryStage.setScene(scene); 
      primaryStage.show(); 

      // movement: car path on race track 
      PathTransition pathTransition = new PathTransition(); 
      pathTransition.setDuration(Duration.millis(4000)); 
      pathTransition.setPath(path); 
      pathTransition.setNode(arrow); 
      pathTransition.setCycleCount(Timeline.INDEFINITE); 
      pathTransition.setAutoReverse(true); 

      // rotate car during movement 
      pathTransition.currentTimeProperty().addListener(e -> { 

       double rad = angle(new Point2D(prevX, prevY), new Point2D(arrow.getTranslateX(), arrow.getTranslateY())); 
       double deg = Math.toDegrees(rad); 

       arrow.setRotate(deg); 

       prevX = arrow.getTranslateX(); 
       prevY = arrow.getTranslateY(); 

      }); 

      pathTransition.play(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

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

    /** 
    * Calculate angle between source and target point in radians. 
    * @param source 
    * @param target 
    * @return 
    */ 
    public static double angle(Point2D source, Point2D target) { 

     double dx = target.getX() - source.getX(); 
     double dy = target.getY() - source.getY(); 

     double angle = Math.atan2(dy, dx); 

     return angle; 

    } 

} 

enter image description here