Java tutorial
/* * $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; } }