14static qreal lerp(qreal a, qreal b, qreal t)
16 return a * (1 - t) + b * t;
28 , m_timestep(1.0 / 100.0)
30 , m_springConstant(springConstant)
31 , m_dampingRatio(dampingRatio)
32 , m_dampingCoefficient(2 * std::sqrt(m_springConstant) * m_dampingRatio)
44 return m_springConstant;
49 return m_dampingRatio;
54 return lerp(m_prev.velocity, m_next.velocity, m_t);
68 return lerp(m_prev.position, m_next.position, m_t);
100SpringMotion::Slope SpringMotion::evaluate(
const State &state, qreal dt,
const Slope &slope)
103 .position = state.position + slope.dp * dt,
104 .velocity = state.velocity + slope.dv * dt,
108 const qreal springForce = (m_anchor - next.position) * m_springConstant;
109 const qreal dampingForce = -next.velocity * m_dampingCoefficient;
110 const qreal acceleration = springForce + dampingForce;
113 .dp = state.velocity,
118SpringMotion::State SpringMotion::integrate(
const State &state, qreal dt)
125 const Slope k1 = evaluate(state, 0.0, initial);
126 const Slope k2 = evaluate(state, 0.5 * dt, k1);
127 const Slope k3 = evaluate(state, 0.5 * dt, k2);
128 const Slope k4 = evaluate(state, dt, k3);
130 const qreal dpdt = 1.0 / 6.0 * (k1.dp + 2 * k2.dp + 2 * k3.dp + k4.dp);
131 const qreal dvdt = 1.0 / 6.0 * (k1.dv + 2 * k2.dv + 2 * k3.dv + k4.dv);
134 .position = state.position + dpdt * dt,
135 .velocity = state.velocity + dvdt * dt,
147 if (std::isinf(m_springConstant)) {
149 .position = m_anchor,
157 const qreal steps = (delta.count() / 1000.0) / m_timestep;
158 for (m_t += steps; m_t > 1.0; m_t -= 1.0) {
160 m_next = integrate(m_next, m_timestep);
qreal springConstant() const
void setEpsilon(qreal epsilon)
void advance(std::chrono::milliseconds delta)
void setPosition(qreal position)
void setAnchor(qreal anchor)
void setVelocity(qreal velocity)
qreal dampingRatio() const