Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

A simple spring simulation in one dimension

/*  *  $Id: FloatSpring.java,v 1.4 2007/06/25 23:00:10 shingoki Exp $  *  *  Copyright (c) 2005-2006 shingoki  *  *  This file is part of AirCarrier, see http://aircarrier.dev.java.net/  *  *    AirCarrier is free software; you can redistribute it and/or modify  *    it under the terms of the GNU General Public License as published by  *    the Free Software Foundation; either version 2 of the License, or  *    (at your option) any later version.  *    AirCarrier is distributed in the hope that it will be useful,  *    but WITHOUT ANY WARRANTY; without even the implied warranty of  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *    GNU General Public License for more details.  *    You should have received a copy of the GNU General Public License  *    along with AirCarrier; if not, write to the Free Software  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  *  */ /**  * A simple spring simulation in one dimension Useful for getting a property  * (for example a position) to move from one value to another, in a smooth  * looking way. To use, create a spring with appropriate constants (e.g. new  * FloatSpring(100) is a reasonable value) Then set spring position to the  * initial value, and update each frame with target parameter as your desired  * value. The position parameter will "snap to" the desired value.  *   * @author goki  */ public class FloatSpring {   float position;   float springK;   float dampingK;   float velocity;   /**    * Make a spring with given spring constant and damping constant    *     * @param springK    *          Spring constant, the higher this is the "tighter" the spring, and    *          the more force it will exert for a given extension    * @param dampingK    *          Damping constant, the higher this is the stronger the damping, and    *          the more "soggy" the movement.    */   public FloatSpring(float springK, float dampingK) {     super();     this.position = 0;     this.springK = springK;     this.dampingK = dampingK;     this.velocity = 0;   }   /**    * Create a critically damped spring (or near to critically damped) This    * spring will quickly move to its target without overshooting    *     * @param springK    *          The spring constant - the higher this is, the more quickly the    *          spring will reach its target. A value of 100 gives a reasonable    *          response in about a second, a higher value gives a faster    *          response.    */   public FloatSpring(float springK) {     this(springK, (float) (2 * Math.sqrt(springK)));   }   /**    * Update the position of the spring. This updates the "position" as if there    * were a damped spring stretched between the current position and the target    * position. That is, the spring will tend to pull the position towards the    * target, and if the spring is damped the position will eventually settle    * onto the target.    *     * @param target    *          The target towards which the spring is pulling the position    * @param time    *          The elapsed time in seconds    */   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 position at the new velocity, for elapsed time     position += velocity * time;   }   /**    * @return Damping constant, the higher this is the stronger the damping, and    *         the more "soggy" the movement.    */   public float getDampingK() {     return dampingK;   }   /**    * @param dampingK    *          Damping constant, the higher this is the stronger the damping, and    *          the more "soggy" the movement.    */   public void setDampingK(float dampingK) {     this.dampingK = dampingK;   }   /**    * @return The current position of the simulated spring end point, changes as    *         simulation is updated    */   public float getPosition() {     return position;   }   /**    * @param position    *          A new position for simulated spring end point    */   public void setPosition(float position) {     this.position = position;   }   /**    * @return The spring constant - the higher this is, the more quickly the    *         spring will reach its target    */   public float getSpringK() {     return springK;   }   /**    * @param springK    *          The spring constant - the higher this is, the more quickly the    *          spring will reach its target    */   public void setSpringK(float springK) {     this.springK = springK;   }   /**    * @return The current velocity of the position    */   public float getVelocity() {     return velocity;   }   /**    * @param velocity    *          A new value for the current velocity of the position    */   public void setVelocity(float velocity) {     this.velocity = velocity;   } }