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 */publicclassFloatSpring {floatposition;floatspringK;floatdampingK;floatvelocity; /** * 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. */publicFloatSpring(floatspringK,floatdampingK) {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. */publicFloatSpring(floatspringK) {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 */publicvoidupdate(floattarget,floattime) { // Set v to target - position, this is the required movementfloatv = 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 itif(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. */publicfloatgetDampingK() {returndampingK; } /** * @param dampingK * Damping constant, the higher this is the stronger the damping, and * the more "soggy" the movement. */publicvoidsetDampingK(floatdampingK) { this.dampingK = dampingK; } /** * @return The current position of the simulated spring end point, changes as * simulation is updated */publicfloatgetPosition() {returnposition; } /** * @param position * A new position for simulated spring end point */publicvoidsetPosition(floatposition) { this.position = position; } /** * @return The spring constant - the higher this is, the more quickly the * spring will reach its target */publicfloatgetSpringK() {returnspringK; } /** * @param springK * The spring constant - the higher this is, the more quickly the * spring will reach its target */publicvoidsetSpringK(floatspringK) { this.springK = springK; } /** * @return The current velocity of the position */publicfloatgetVelocity() {returnvelocity; } /** * @param velocity * A new value for the current velocity of the position */publicvoidsetVelocity(floatvelocity) { this.velocity = velocity; } }