当前位置: 首页 > 知识库问答 >
问题:

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

濮阳和泰
2023-03-14

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

X是一个包含轮子位置的变量。它可以在-(轮子宽度)和窗口大小轮子宽度之间。

我想通过在这个轮子里画一个圆来模拟旋转,这个圆绕着这个圆旋转,就好像它是连着的一样。

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

我将获得一个百分比,通过我的车轮课程,如下所示:

int percentage = x/windowWidth;

轮子移动的每一帧,我称为wheel.rotate(百分比)

以下是实施:

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不是。它像罪恶波一样摇摆,这是意料之中的(我确实使用了sin...),但是,我不知道如何改变我的数学来跟随圆圈。

我的实现有什么问题?(我不太擅长用三角函数作图)

共有1个答案

符修杰
2023-03-14

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

像大多数事情一样,我从网上偷了这个,但它有效...

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

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

        }

    }

}
 类似资料:
  • 我想在模拟器上测试手机的旋转,我看到我们必须使用CtrlF11的所有地方,但它只旋转模拟器的图像,不会启动配置更改事件或重新绘制活动。 下面是我用CtrlF11得到的: 那么,我必须用什么来模拟真实的旋转呢?

  • 所以基本上我想跟滑头做点这样的事...我想有正常的幻灯片,但事情是,是,我想有行动呼吁(按钮)在他们。这通常很容易将按钮与幻灯片一起放入,但有一个溢出:旋转式播放器上隐藏的样式无法取下,否则其他幻灯片会显示出来。我想知道如何才能做到这一点(按钮稍微往外走而不被切断)。 编辑:添加边框到旋转木马,这是真正的问题,我有...维护边框并使底部与边框重叠

  • 我正在尝试easyMock测试几个类/接口方法。方法,试图捕获参数,但得到一个或另一个错误。如果我只记录了一个期望值,它甚至不会捕获参数管道中的任何内容,如果我使用以下方法,我会得到如下错误代码。 结果是错误的 testFireChannelInitializer(com.obolus.generic.impl.DefaultChannelListenerTest)运行时间:3.812秒 你知道怎

  • 让我们从一个简单的模拟开始学习。Qt Quick使用简单的粒子渲染非常简单。下面是我们需要的: 绑定所有元素到一个模拟的粒子系统(ParticleSystem)。 一个向系统发射粒子的发射器(Emitter)。 一个ParticlePainter派生元素,用来实现粒子的可视化。 import QtQuick 2.0 import QtQuick.Particles 2.0 Rectangle {

  • 形状不一定始终沿着直线运动。如果你需要的动画效果是沿着圆周运动,例如,沿着圆形轨道运行(如图1所示)该如何实现呢?这是完全可以实现的,并且不需要使用太多代码,这里需要使用三角函数的相关知识,可能需要你稍微动一下脑筋。 使形状动画沿着圆形轨道运动 概念非常简单:将一个形状放在圆周的边缘处(它的周长上),以圆周的任意位置作为起点。但为了简单起见,可以将形状放在周长上角度为0弧度的位置,该位置位于右手边

  • 实现类似转盘电话中拨号转盘的旋转菜单效果。滑动菜单,菜单进行转动,转动的过程中,处于最前面的按钮按钮慢慢变大,处于后端的按钮变小。同样,点击转盘菜单上某个按钮,被点击的按钮会慢慢被转到最前面。由于转动的过程中,按钮会有大变小或者由小变大,所以这个动画有3D的效果。 [Code4App.com]