1

如何让带有双弹簧模拟的摆锤工作?我只有弹簧,但它不适用于钟摆;它只会向前移动。我的任务:我有两个弹簧,我必须用这两个弹簧模拟一个钟摆: 示例 我的代码:

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;
  }
}
4

0 回答 0