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

我在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不能。 它像一股浪潮一样摆动,这是预期的(我确实使用了罪……),然而,我不知道如何改变我的数学来跟随周围的圈子。

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

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

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

 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 + px - (int) (innerDiameter / 2), y + py - (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); } } }