2012-06-27 3 views
3

В принципе, я хочу моделировать поведение пружин на окрашенном изображении. Я хочу, чтобы он проходил через несколько итераций, масштабируя его вверх и вниз (как будто он закреплен на пружине).Моделирование поведения пружин

Все примеры, которые я нашел в сети приводят к этому классу - FloatSpring.java

Она должна обеспечивать необходимые расчеты для перемещения точки А в точку Б, применяя весеннему эффект, который зависит от различных параметров класса FloatSpring. Проблема в том, что я не нашел ни одного четкого примера, как правильно его использовать.

Я сделал этот небольшой пример, чтобы проверить FloatSpring на:

public static void main (String[] args) 
{ 
    // Some image to bounce 
    final ImageIcon icon = 
      new ImageIcon (WebProgressOverlayExample.class.getResource ("icons/ava1.jpg")); 

    // Component to paint image on 
    JComponent spring = new JComponent() 
    { 
     // Zoom value (1f = 100% = normal size) 
     float zoom = 1f; 

     { 
      // Basic spring settings 
      final FloatSpring fs = new FloatSpring (100); 
      fs.setPosition (zoom); 

      // Animation delay 
      final int delay = 1000/24; 

      // Animator 
      new Timer (delay, new ActionListener() 
      { 
       private float elapsed = 0f; 

       public void actionPerformed (ActionEvent e) 
       { 
        // Increasing elapsed time and updating spring 
        elapsed += delay; 
        fs.update (3f, elapsed); 

        // Updating zoom value and component 
        zoom = fs.getPosition(); 
        repaint(); 
       } 
      }).start(); 
     } 

     protected void paintComponent (Graphics g) 
     { 
      super.paintComponent (g); 

      // Scaled image 
      int width = Math.round (icon.getIconWidth() * zoom); 
      int height = Math.round (icon.getIconHeight() * zoom); 
      g.drawImage (icon.getImage(), getWidth()/2 - width/2, 
        getHeight()/2 - height/2, this); 
     } 

     public Dimension getPreferredSize() 
     { 
      return new Dimension (500, 500); 
     } 
    }; 

    JFrame frame = new JFrame(); 
    frame.add (spring); 
    frame.pack(); 
    frame.setLocationRelativeTo (null); 
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    frame.setVisible (true); 
} 

В этом примере zoom свойство должно отскакивать от 1f к 3f внутри цикла таймера и, наконец, привести отображаемое на компонент изображения в 3 раза масштабирования. Что-то вроде простого анимированного перехода.

Класс FloatSpring должен быть в порядке - я просто не понимаю, как правильно его использовать. Если быть точным - то, что я должен указать в качестве значений springK и dampingK, а также значение time цели неясно ...

Я бы очень признателен за любую помощь.

ответ

6

Работает sscce с использованием FloatSpring.

bungee

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.AbstractAction; 
import javax.swing.Icon; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.Timer; 
import javax.swing.UIManager; 

/** 
* @see http://stackoverflow.com/a/11233735/230513 
*/ 
public class Test { 

    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(); 
     } 
    } 
} 
+0

Спасибо, вот именно то, что я искал! –

Смежные вопросы