如何使用弧度移动对象?

时间:2014-11-21 23:25:43

标签: java animation graphics polar-coordinates

我有一个问题,我需要移动球,它只是静止不动。我已经成功地使用一个简单的函数(x = x + 1)来移动它,但是当涉及到弧度时它就不起作用了。我在这里看了一些帖子,我以为我是以正确的方式制作它,但显然我错过了一些东西:)

这是我的 Ball类

public class Ball {

int x = 0;
int y = 0;


int rightleft = 1;
int updown = 1;
private static final int sizeBall = 30;
float angle = 120;
float angleInRadians = (float) (angle*Math.PI/180);

private Main main;


public Ball(Main main){

 this.main=main;

}

// That function should move my ball 
void move() {


    x =  (int) (x + Math.cos(angleInRadians));
    y= (int)  (x+Math.sin(angleInRadians));

}
void paint(Graphics2D g) {
    g.setColor(Color.red);
    g.fillOval(x, y, sizeBall, sizeBall);
}

 public Rectangle getSize(){
    return new Rectangle(x,y,sizeBall,sizeBall);
}    
}

这是我的主要课程

  public class Main extends JPanel {

   Ball ball = new Ball(this);

 private void moveBall() throws InterruptedException{
    ball.move();
}

  public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ball.paint(g2d);
      }


public static void main(String[] args) throws InterruptedException {
    // TODO code application logic here

       JFrame okno = new JFrame("TEST");
    Main main = new Main();

    okno.add(main);
    okno.setSize(500,500);
    okno.setVisible(true);
    okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    while(true){

        main.moveBall();
        main.repaint();
        Thread.sleep(10);
    }

}

    }

你知道我的错误在哪里吗?

1 个答案:

答案 0 :(得分:3)

x和y将始终= 0.了解它们是0开始,然后向它们添加正弦或cose,保证< 1。

x = (int) (x + Math.cos(angleInRadians));
y = (int) (x+Math.sin(angleInRadians));

所以0 +数字< 1将是< 1.

然后当你转换为int时,数字< 1将变为0。

另外

  • 使用Swing Timer而不是while (true)循环。
  • 覆盖JPanel的paintComponent方法,而不是其绘制方法,以获得更流畅的动画。
  • 我会使用双数来表示我的x和y值,并且只能在使用它们时进行投射或舍入。
  • 我不确定你的目标是什么轨迹,但是你当前的代码(如果有效)不是以极地方式移动,而是始终与当前点成45%角。

例如,此GUI由以下代码创建:

enter image description here

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class MyPolar extends JPanel {
   private static final int BI_W = 400;
   private static final int BI_H = BI_W;
   private static final int CTR_X = BI_W / 2;
   private static final int CTR_Y = BI_H / 2;
   private static final Color AXIS_COLOR = Color.black;
   private static final Color GRID_LINE_COLOR = Color.LIGHT_GRAY;
   private static final Color DRAWING_COLOR = Color.RED;
   private static final float AXIS_LINE_WIDTH = 4f;
   private static final double SCALE = BI_W / (2 * 1.25);
   private static final float GRID_LINE_WIDTH = 2f;
   private static final float DRAWING_WIDTH = 2f;
   private static final double DELTA_THETA = Math.PI / (2 * 360);
   private static final int TIMER_DELAY = 20;
   private BufferedImage axiImg;
   private List<Point> ptList = new ArrayList<>();
   private double theta = 0;  

   public MyPolar() {
      axiImg = createAxiImg();

      int x = xEquation(theta);
      int y = yEquation(theta);
      ptList.add(new Point(x, y));

      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   private int xEquation(double theta) {
      double r = 2 * Math.sin(4 * theta);     
      return (int) (SCALE * 0.5 * r * Math.cos(theta)) + CTR_X;
   }

   private int yEquation(double theta) {
      double r = 2 * Math.sin(4 * theta);     
      return (int) (SCALE * 0.5 * r * Math.sin(theta)) + CTR_Y;
   }

   private BufferedImage createAxiImg() {
      BufferedImage img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(AXIS_COLOR);
      g2.setStroke(new BasicStroke(AXIS_LINE_WIDTH));
      int x1 = 0;
      int y1 = CTR_Y;
      int x2 = BI_W;
      int y2 = y1;
      g2.drawLine(x1, y1, x2, y2);

      x1 = CTR_X;
      y1 = 0;
      x2 = x1;
      y2 = BI_H;
      g2.drawLine(x1, y1, x2, y2);

      g2.setColor(GRID_LINE_COLOR);
      g2.setStroke(new BasicStroke(GRID_LINE_WIDTH));

      x1 = (int) (CTR_X - BI_H * 0.5 * Math.tan(Math.PI / 6));
      y1 = BI_H;
      x2 = (int) (CTR_X + BI_H * 0.5 * Math.tan(Math.PI / 6));
      y2 = 0;
      g2.drawLine(x1, y1, x2, y2);

      x1 = BI_W - x1;
      x2 = BI_W - x2;
      g2.drawLine(x1, y1, x2, y2);

      x1 = (int) (CTR_X - BI_H * 0.5 * Math.tan(Math.PI / 3));
      y1 = BI_H;
      x2 = (int) (CTR_X + BI_H * 0.5 * Math.tan(Math.PI / 3));
      y2 = 0;
      g2.drawLine(x1, y1, x2, y2);

      x1 = BI_W - x1;
      x2 = BI_W - x2;
      g2.drawLine(x1, y1, x2, y2);

      for (int i = 1; i < 4; i++) {
         int x = (int) (CTR_X - i * SCALE / 2.0);
         int y = x;
         int width = (int) (i * SCALE);
         int height = width;         
         g2.drawOval(x, y, width, height);
      }

      g2.dispose();
      return img;
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      if (axiImg != null) {
         g2.drawImage(axiImg, 0, 0, null);
      }
      g2.setColor(DRAWING_COLOR);
      g2.setStroke(new BasicStroke(DRAWING_WIDTH));
      Point prev = null;
      for (Point point : ptList) {
         if (prev != null) {
            int x1 = prev.x;
            int y1 = prev.y;
            int x2 = point.x;
            int y2 = point.y;
            g2.drawLine(x1, y1, x2, y2);
         }
         prev = point;
      }

   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(BI_W, BI_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         theta += DELTA_THETA;
         if (theta > 2 * Math.PI) {
            ((Timer) e.getSource()).stop();
         } else {
            int x = xEquation(theta);
            int y = yEquation(theta);
            ptList.add(new Point(x, y));
         }
         repaint();
      }
   }

   private static void createAndShowGui() {
      MyPolar mainPanel = new MyPolar();

      JFrame frame = new JFrame("MyPolar");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}