/// <summary> /// Calculates average movement time to the point /// </summary> /// <returns>The average time.</returns> /// <param name="velocity">Velocity.</param> /// <param name="maxVelocity">Max velocity.</param> /// <param name="position">Position.</param> /// <param name="target">Target.</param> public static float GetAverageMoveTime(Vector velocity, float maxVelocity, float damping, float acceleration, Vector position, Vector target, float epsilon) { Vector direction = (target - position); float distance = direction.Normalize(); float v = Vector.Dot(velocity, direction); float dampingDistance = maxVelocity * maxVelocity * s_oneMinusLog2 / damping; float t; if (distance > dampingDistance) { t = (distance - dampingDistance) / maxVelocity + (maxVelocity - v) / acceleration; // rought acceleration time, will be smaller than actual time } else { t = 0.1f; } float ndistance; float u; int iterations = 10; // limit the cycle do { float exp = (float)Math.Exp(-acceleration * t / maxVelocity); u = maxVelocity - (maxVelocity - v) * exp; ndistance = maxVelocity * (t - (u - v) / acceleration) + GetDampingDistance(u, maxVelocity, damping); if (ndistance >= distance + epsilon) // average goal { break; } t += 0.1f; } while(ndistance < distance && --iterations >= 0); return(t + maxVelocity * (float)Math.Log(1.0f + u / maxVelocity) / damping); }
/// <summary> /// Calculates the time untill full stop with specified speed and damping /// </summary> /// <returns>The damping time.</returns> /// <param name="velocity">Velocity.</param> /// <param name="maxVelocity">Max velocity.</param> /// <param name="damping">Damping.</param> public static float GetDampingTime(float velocity, float maxVelocity, float damping) { float speedPct = velocity / maxVelocity; return(maxVelocity * (speedPct - (float)Math.Log(1 + speedPct)) / Math.Abs(damping)); }