简单的圆圈旋转(模拟运动) [英] Simple circle rotation (simulate motion)

查看:161
本文介绍了简单的圆圈旋转(模拟运动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple animation in Java that consists of a wheel moving across a window. It is just a plain circle that starts off of the screen from the left, enters and continues to the right until it goes off of the screen. Then it loops and repeats this process.

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

X is a variable that contains the position of the wheel. It can be between -(wheel width) and the window size + the wheel width.

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

I would like to simulate rotation by drawing a circle within this wheel, that rotates around the circle as if it were attached.

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

Imagine a bike wheel in real life with a red flag on the wheel. As the wheel rotates, the red flag would be on the edge on the wheel moving as the wheel progresses. This is the behavior I want.

我得到一个百分比来传递到我的轮子类这样:

I am getting a percentage to pass into my wheel class like this:

int percentage = x/windowWidth;

车轮移动的每一帧,我调用 wheel.rotate(百分比)

Each frame that the wheel moves, I call 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不会。它像一股浪潮一样摆动,这是预期的(我做了使用罪......)但是,我不知道如何改变我的数学来跟随周围的圈子。

The x location works more or less how I wanted, but the y does not. It wiggles like a sin wave, which is expected (I did use sin...), however, I'm not sure how to alter my math to follow the circle around.

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

What is wrong with my implementation? (I'm not very good with drawing with trigonometric functions)

推荐答案

基本上,你需要计算圆上的点,基于对象应该出现的角度...

Basically, you need to calculate the point on the circle, based on an angle that the object should appear...

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

Like most things, I stole this off the internet somewhere, but it works...

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位置......

Based on an angel (in degrees) and the radius of the circle, this will return the x/y position along the circumference of the circle...

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

        }

    }

}

这篇关于简单的圆圈旋转(模拟运动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆