如何让带有双弹簧模拟的摆锤工作?我只有弹簧,但它不适用于钟摆;它只会向前移动。我的任务:我有两个弹簧,我必须用这两个弹簧模拟一个钟摆: 示例 我的代码:
public class Springs {
private static Spring spring = new Spring();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(spring);
frame.add(new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent e) {
spring.start();
}
}), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
spring.start();
}
});
}
private static class Spring extends JComponent {
private static final int SIZE = 500;
private static final int DELAY = 1000 / 20; // ~20Hz
private final Icon icon = UIManager.getIcon("OptionPane.informationIcon");
private final FloatSpring fs = new FloatSpring(42);
private final int target = 0;
private final float delta = 1f / SIZE;
private float elapsed = 0f;
private Timer timer = new Timer(DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ((int) fs.getPosition() < (target + 1)) {
timer.stop();
return;
}
elapsed += delta;
fs.update(target, elapsed);
repaint();
}
});
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - icon.getIconWidth()) / 2;
int y = (int) fs.getPosition();
icon.paintIcon(this, g, x, y);
int xc = x + icon.getIconWidth() / 2;
g.drawLine(xc, 0, xc, y);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE / 2, SIZE);
}
public void start() {
timer.stop();
elapsed = 0;
fs.setPosition(SIZE - icon.getIconHeight());
fs.setVelocity(0);
timer.start();
}
}
}
和浮动弹簧:
public class FloatSpring {
float position;
float springK;
float dampingK;
float velocity;
public FloatSpring(float springK, float dampingK) {
super();
this.position = 0;
this.springK = springK;
this.dampingK = dampingK;
this.velocity = 0;
}
public FloatSpring(float springK) {
this (springK, (float)(2 * Math.sqrt(springK)));
}
public void update(float target, float time) {
//Set v to target - position, this is the required movement
float v = position - target;
//Multiply displacement by spring constant to get spring force,
//then subtract damping force
v = v * -springK - velocity * dampingK;
//v is now a force, so assuming unit mass is is also acceleration.
//multiply by elapsed time to get velocity change
velocity += v * time;
//If velocity isn't valid, zero it
if (Float.isNaN(velocity) || Float.isInfinite(velocity)) {
velocity = 0;
}
//Change the roll at the new velocity, for elapsed time
position += velocity * time;
}
public float getDampingK() {
return dampingK;
}
public void setDampingK(float dampingK) {
this.dampingK = dampingK;
}
public float getPosition() {
return position;
}
public void setPosition(float position) {
this.position = position;
}
public float getSpringK() {
return springK;
}
public void setSpringK(float springK) {
this.springK = springK;
}
public float getVelocity() {
return velocity;
}
public void setVelocity(float velocity) {
this.velocity = velocity;
}
}