2015-04-25 42 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 работают в радианах, хотя вращение 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

Смежные вопросы