java钟摆模拟只执行一个周期
我正在模拟一个钟摆,但它只执行一次摆动,然后发送接近随机位置的摆锤。本质上,它不会倒退
我曾尝试使用goingForward布尔值来改变方向,但仍然不起作用
public class AnimationPane extends JPanel {
// START CHANGEABLE VARIABLES
private double startAngle = -60.0; // degrees
private double mass = 1; // kilogrammes
private int radius = 10; // m
private double gravity = 9.80665; // m/s^2 // on earth: 9.80665
// END CHANGEABLE VARIABLEs
private BufferedImage ball;
private BufferedImage rope;
private int pointX = 180;
private int pointY = 50;
private double endAngle = Math.abs(startAngle); // absolute value of startAngle
private double angle = startAngle; // current angle
private double circum = (2 * Math.PI * radius); // m
private double distance = 0; // m
private double velocity = 0; // m/s
private double totalEnergy = ((radius) - (Math.cos(Math.toRadians(angle)) * radius)) * gravity * mass + 0.00001;
private double previousE;
private int xPos = 0; // for program
private int yPos = 0; // for program
private boolean goingForward = true;
private double height = 0;
public AnimationPane() {
try {
ball = ImageIO.read(new File("rsz_black-circle-mask-to-fill-compass-outline.png"));
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
double angleRad = Math.toRadians(Math.abs(angle));
double potentialE = ((radius) - (Math.cos(angleRad) * radius)) * gravity * mass;
Double pE = new Double(potentialE);
height = (radius - (Math.cos(angleRad) * radius));
double kineticE = totalEnergy - pE;
if (kineticE <= 0 || angle >= endAngle) {
if (goingForward == true) {
goingForward = false;
}
else
{
goingForward = true;
}
kineticE = 0.1;
angle = 60;
}
velocity = Math.sqrt(2 * kineticE / mass);
double ratio = distance / circum;
if (goingForward == true) {
distance = distance + (velocity / 10);
angle = startAngle + (360 * ratio);
}
else {
distance = distance - (velocity / 10);
angle = startAngle - (360 * ratio);
}
double angles = Math.toRadians(angle);
double xDouble = Math.sin(angles) * (radius * 10);
Double x = new Double(xDouble);
xPos = x.intValue() + 150;
double yDouble = Math.cos(angles) * (radius * 10);
Double y = new Double(yDouble);
yPos = y.intValue() + 50;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
} catch (IOException ex) {
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(xPos + 20, yPos + 20, pointX, pointY);
g.drawImage(ball, xPos, yPos, this);
}
}
我真的很感激你能帮我把这件事做好。 谢谢!
# 1 楼答案
我无法调试您的代码,这很难使用,有时也很难理解(您的代码中使用了大量整数文本,这隐藏了它们的语义,我不知道您对某些语句的意图是什么)
因此,我用小振动微分方程的解重写了它。它是有效的,你可以把它作为一个干净的基础,以你想要的方式再次实现它。请注意,正如安迪·特纳(Andy Turner)所指出的,你不必担心前进或后退的事实。你有一个方程,你解了它,它给出了球在任何时候的位置。如果你想要大角度的精确数据,我建议你去维基百科看看这个例子中的运动方程。最后一个选项,你可以用数值方法求解微分方程,尽管我个人一眼就不知道怎么做