我在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不起作用。它像一股浪潮一样摆动,这是预期的(我做使用罪......)但是,我不知道如何改变我的数学来跟随周围的圈子。
我的实施有什么问题? (我用三角函数绘图不是很好)
答案 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位置......
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);
}
}
}