弹簧行为模拟 [英] Spring behavior simulation
问题描述
基本上,我想模拟绘制图像上的弹簧行为。我想让它经历几次迭代上下缩放(就像在弹簧上修复一样)。
Basically, i want to simulate spring behavior on painted image. I want to make it run through a few iterations scaling it up and down (like it is fixed on a spring).
我在网络上找到的所有例子到这个班级 - FloatSpring.java
All of the examples i found on the net lead to this class - FloatSpring.java
它应该提供所需的计算,以便将A点移动到B点类似弹簧的效果取决于各种FloatSpring类设置。问题是我没有找到一个明确的例子如何正确使用它。
It should provide the needed calculations to move point A to point B applying spring-like effect which depends on various FloatSpring class settings. The problem is that i didn't find a single clear example how to use it properly.
我做了一个小例子来测试 FloatSpring
on:
I made this small example to test FloatSpring
on:
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倍变焦。像简单的动画过渡一样。
In this example zoom
property should bounce from 1f to 3f within the timer cycle and finally lead the displayed on component image to 3X zoom. Something like simple animated transition.
FloatSpring类应该没问题 - 我只是不明白如何正确使用它。确切地说 - 我应该指定什么作为 springK
和 dampingK
值以及时间
财产目的不明确......
FloatSpring class should be fine - i just don't understand how to use it properly. To be exact - what should i specify as the springK
and dampingK
values and also the time
property purpose is unclear...
我真的很感激那里有任何帮助。
I would really appreciate any help there.
推荐答案
这是一个有效的 sscce ,使用 FloatSpring
。
Here's a working sscce using FloatSpring
.
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();
}
}
}
这篇关于弹簧行为模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!