简单的圆圈旋转(模拟运动)

时间:2014-09-18 22:32:38

标签: java math trigonometry

我在Java中有一个简单的动画,它包含一个在窗口移动的轮子。它只是一个从左边开始离开屏幕的普通圆圈,进入并继续向右,直到它离开屏幕。然后它循环并重复这个过程。

X是一个包含方向盘位置的变量。它可以在 - (车轮宽度)和窗口尺寸+车轮宽度之间。

我想通过在这个轮子中画一个圆圈来模拟旋转,这个圆圈围绕圆圈旋转,好像它已经连接一样。

想象一下现实生活中的自行车车轮,车轮上有一面红旗。随着车轮的旋转,当车轮前进时,车轮边缘会出现红旗。这是我想要的行为。

我得到一个百分比可以像这样进入我的轮子类:

int percentage = x/windowWidth;

车轮移动的每个框架,我调用wheel.rotate(percentage)

这是实施:

private int diameter = 50;        
private final int SPOKE_DIAMETER = diameter/5;

    public void rotate(double percent){
        this.percent = percent;
        this.theta = percent*(PI*2);
        System.out.println(percent*PI);
    }

    public void paintComponent(Graphics canvas)
    {
        // wheel
        canvas.setColor(Color.gray);
        canvas.fillOval(0, 0, diameter, diameter);

        // spinning flag
        canvas.setColor(Color.red);
        canvas.fillOval((int)(percent*diameter),(int)((sin((percent*(PI*2)))*diameter)), SPOKE_DIAMETER,SPOKE_DIAMETER);
    }

x位置或多或少地起作用,但y不起作用。它像一股浪潮一样摆动,这是预期的(我使用罪......)但是,我不知道如何改变我的数学来跟随周围的圈子。

我的实施有什么问题? (我用三角函数绘图不是很好)

1 个答案:

答案 0 :(得分:5)

基本上,你需要根据物体出现的角度来计算圆上的点......

像大多数事情一样,我在某个地方从互联网上偷走了这个,但它确实有用......

protected Point getPointOnCircle(float degress, float radius) {

    int x = Math.round(getWidth() / 2);
    int y = Math.round(getHeight() / 2);

    double rads = Math.toRadians(degress - 90); // 0 becomes the top

    // Calculate the outter point of the line
    int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
    int yPosy = Math.round((float) (y + Math.sin(rads) * radius));

    return new Point(xPosy, yPosy);

}

根据天使(以度为单位)和圆的半径,这将返回沿圆周的x / y位置......

Rotate within

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RotateWheel {

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

    public RotateWheel() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private float degrees = 0;

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    degrees += 0.5f;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int diameter = Math.min(getWidth(), getHeight());
            int x = (getWidth() - diameter) / 2;
            int y = (getHeight() - diameter) / 2;

            g2d.setColor(Color.GREEN);
            g2d.drawOval(x, y, diameter, diameter);

            g2d.setColor(Color.RED);
            float innerDiameter = 20;

            Point p = getPointOnCircle(degrees, (diameter / 2f) - (innerDiameter / 2));
            g2d.drawOval(x + p.x - (int) (innerDiameter / 2), y + p.y - (int) (innerDiameter / 2), (int) innerDiameter, (int) innerDiameter);

            g2d.dispose();
        }

        protected Point getPointOnCircle(float degress, float radius) {

            int x = Math.round(getWidth() / 2);
            int y = Math.round(getHeight() / 2);

            double rads = Math.toRadians(degress - 90); // 0 becomes the top

            // Calculate the outter point of the line
            int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
            int yPosy = Math.round((float) (y + Math.sin(rads) * radius));

            return new Point(xPosy, yPosy);

        }

    }

}