gecko/gfx/layers/AxisPhysicsMSDModel.cpp

94 lines
3.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AxisPhysicsMSDModel.h"
#include <math.h> // for sqrt and fabs
namespace mozilla {
namespace layers {
/**
* Constructs an AxisPhysicsMSDModel with initial values for state.
*
* @param aInitialPosition sets the initial position of the simulated spring,
* in AppUnits.
* @param aInitialDestination sets the resting position of the simulated spring,
* in AppUnits.
* @param aInitialVelocity sets the initial velocity of the simulated spring,
* in AppUnits / second. Critically-damped and over-damped systems are
* guaranteed not to overshoot aInitialDestination if this is set to 0;
* however, it is possible to overshoot and oscillate if not set to 0 or
* the system is under-damped.
* @param aSpringConstant sets the strength of the simulated spring. Greater
* values of mSpringConstant result in a stiffer / stronger spring.
* @param aDampingRatio controls the amount of dampening force and determines
* if the system is under-damped, critically-damped, or over-damped.
*/
AxisPhysicsMSDModel::AxisPhysicsMSDModel(double aInitialPosition,
double aInitialDestination,
double aInitialVelocity,
double aSpringConstant,
double aDampingRatio)
: AxisPhysicsModel(aInitialPosition, aInitialVelocity)
, mDestination(aInitialDestination)
, mSpringConstant(aSpringConstant)
, mSpringConstantSqrtXTwo(sqrt(mSpringConstant) * 2.0)
, mDampingRatio(aDampingRatio)
{
}
AxisPhysicsMSDModel::~AxisPhysicsMSDModel()
{
}
double
AxisPhysicsMSDModel::Acceleration(const State &aState)
{
// Simulate a Mass-Damper-Spring Model; assume a unit mass
// Hookes Law: http://en.wikipedia.org/wiki/Hooke%27s_law
double spring_force = (mDestination - aState.p) * mSpringConstant;
double damp_force = -aState.v * mDampingRatio * mSpringConstantSqrtXTwo;
return spring_force + damp_force;
}
double
AxisPhysicsMSDModel::GetDestination()
{
return mDestination;
}
void
AxisPhysicsMSDModel::SetDestination(double aDestination)
{
mDestination = aDestination;
}
bool
AxisPhysicsMSDModel::IsFinished(double aSmallestVisibleIncrement)
{
// In order to satisfy the condition of reaching the destination, the distance
// between the simulation position and the destination must be less than
// aSmallestVisibleIncrement while the speed is simultaneously less than
// finishVelocity. This enables an under-damped system to overshoot the
// destination when desired without prematurely triggering the finished state.
// If finishVelocity is set too low, the animation may end long after
// oscillation has finished, resulting in unnecessary processing.
// If set too high, the animation may prematurely terminate when expected
// to overshoot the destination in an under-damped system.
// aSmallestVisibleIncrement * 2 was selected through experimentation that
// revealed that a critically damped system will terminate within 100ms.
const double finishVelocity = aSmallestVisibleIncrement * 2;
return fabs(mDestination - GetPosition ()) < aSmallestVisibleIncrement
&& fabs(GetVelocity()) <= finishVelocity;
}
} // namespace layers
} // namespace mozilla