package efruchter.particles.integrators; import efruchter.particles.datatypes.Particle; import efruchter.particles.integrators.NewtonianIntegrators.RKState; import efruchter.vectorutils.Vector3; /** * State based functions for common force setups. * * @author toriscope * */ public class CommonForceFunctions { private CommonForceFunctions() { } /** * Calculate the force effect on a particle in a given state, when it is * rigged to a circle and held in place by a virtual restoring force. * * @param state * the state of the particle on the circle. * @param anchor * the particle that anchors the center. * @param prexistingForces * the forces that will be cancelled by the restoring force. * @param particleMass * the mass of the particle on circle. * @return the restoring force. */ public static Vector3 radialVirtual(final RKState state, final Particle anchor, final Vector3 prexistingForces, final float particleMass) { Vector3 x = state.x.sub(anchor.x); Vector3 v = state.v; float lambda = (-prexistingForces.dot(x) - v.scale(particleMass).dot(v)) / x.dot(x); return x.scale(lambda); } /** * * @param state * the state of the particle on the circle. * @param anchor * the particle that anchors the stabel side of spring. * @param particleMass * the mass of the particle on circle. * @param springConstant * the k * @param restLength * the rest length of the spring. * @return spring force. */ public static Vector3 anchoredSpring(final RKState state, final Particle anchor, final float particleMass, final float springConstant, final float restLength) { float x = anchor.x.distance(state.x) - restLength; Vector3 springForce = state.x.sub(anchor.x).unit(); return springForce.scale(-springConstant * x / particleMass); } }