A point-to-point move accelerates at a, runs at the top speed vmax, and decelerates at d. The area under the velocity–time profile is the distance s.
s_accel = v_max² / (2·a) distance the acceleration uses
s_decel = v_max² / (2·d) distance the deceleration uses
if s_accel + s_decel ≤ s (trapezoid — the top speed is reached)
t_accel = v_max / a
t_cruise = (s − s_accel − s_decel) / v_max
t_decel = v_max / d
else (triangle — the acceleration runs straight into the deceleration)
v_peak = √( 2·s·a·d / (a + d) )
t_accel = v_peak / a, t_cruise = 0, t_decel = v_peak / d
t_total = t_accel + t_cruise + t_decel
The inverse — the time is given, what speed and acceleration does it need? — splits the time into acceleration, cruise and deceleration by two fractions and reads the peak speed off the area:
t_accel = f_accel·t_total, t_decel = f_decel·t_total, t_cruise = the rest
v_peak = s / (t_accel/2 + t_cruise + t_decel/2)
a = v_peak / t_accel, d = v_peak / t_decel
Worked example. 100 mm at 0.5 m/s with 3.5 m/s²: accelerating and decelerating need 35.7 mm each, so the move is a trapezoid — 0.143 s accelerating, 0.057 s cruise, 0.143 s decelerating, 0.343 s in all. Halve the distance and it turns triangular, peaking at 0.418 m/s in 0.239 s.
On the cyclogram this whole move — all three phases — is the bar's ramp-up (the stroke out); the body is the stay at the end position, and the ramp-down is the move back. A bar is travel over time, not speed.
Package motion-time (calcpkg/1, open format) — pure functions with tests; the browser version is held against it number for number.