## February 12, 2011

### Uniform Motion Using llMoveToTarget

When an object is physical, the script function

$\bg_black \fn_phv llMoveToTarget( vector \vec{d}), float \tau );$

causes an object to drift smoothly toward a target position.  The drawback is that the motion is not uniform.  The velocity decreases toward zero as the target is approached.

This movement is approximated by

$\bg_black \fn_phv \vec{p}(t) - \vec{p}(0) = ( \vec{d} - \vec {p}(0) ) ( 1 - \exp {(- t / \tau) })$

The object is at position $\inline \bg_black \fn_phv \vec {p}(t)$ at time t.  Because of the exponential attenuation of the velocity, it will reach the position $\inline \bg_black \fn_phv \vec {d}$ after several intervals of the time interval $\inline \bg_black \tau$.

The object motion is made more uniform by using only an early portion of this exponential motion.

To create this effect, calculate a target position $\inline \bg_black \fn_phv \vec {D}$ which lays beyond $\inline \bg_black \fn_phv \vec {d}$, then terminate the movement at the time $\inline \bg_black \tau$.   In algebraic terms, solve this equation for $\inline \bg_black \fn_phv \vec {D}$:

$\inline \bg_black \vec{d} - \vec{p}(0) = (\vec{D} - \vec{p}(0))(1 - \exp{(-\tau / \tau )})$

The solution is

$\inline \bg_black \vec{D} = \vec{p}(0) + ( \vec{d} - \vec{p}(0))( e / ( e - 1))$

where e is the base of the natural logarithms, 2.7182818284....

For a target position d_target, a single step movement is shown below as code fragments.

float tau = 4;
vector d_target = <110,200,30>;
float e = 2.7182818284;

touch_start( integer nTouch ) {
float f = e / ( e - 1 );
vector D_target = llGetPos() + f *( d_target - llGetPos() );
llMoveToTarget( D_target, tau );
llSetTimerEvent( tau );
}

timer() {
llStopMoveToTarget();
llSetTimerEvent( 0 );
}

A more nuanced implementation would declare a list of d_target positions.  The timer event would move thought the list, calculating a series of D_targets, then using llMoveToTarget().  At the end of the list, the timer event would either return to the beginning of the list, or use llStopMoveToTarget().

Des.de.mona

[end]