# Looping an object to move between two positions

I've search a bit and tried to find a decent answer to this but have failed majorly. Basically I'm trying to loop an AI object between two points. Heres some of the code I have so far:

class Object
{
Vector3 startPos;
Vector3 endPos;

Vector3 curPos;
Vector3 curVel;
};

struct Vector3
{
float x;
float y;
float z;
}

Start()
{
startPos = Vector3( 1, 0, 0 );
endPos = Vector3( -1, 0, 0 );
curPos = Vector3( 0, 0, 0 )

Generate();
}

Generate()
{
// Standard code to generate angular velocity
// Calculate angle between two points
// Calculate velocity based on angle
}

Update()
{
curPos += curVel;

// If the position has reached the end point
if( curPos == endPos )
{
// Reverse movement positions
Vector3 temp = endPos;
startPos = endPos;
endPos = temp;

// Recalculate velocity
Generate();
}
}


I'm now stuck, as you can see from the comments, the velocity could take the position of the object to something like (-1.5, 0, 0) which would mean the if statement wouldn't work. For the initial movement, it could be fixed using

if( curPos <= endPos )
{
// Reverse
}


However, when I then reverse the positions, problems arise and it won't work. Any ideas?

One approach is to use distance as it will always be a positive number so you don't need to account for sign.

When at startPos, compute the distance from startPos to endPos and store this is a float called distanceToTravel (or similar). Each tick of Update() compute the distance traveled so far (this is startPos to currPos), call this distanceTraveledSoFar (or similar). Then compare distanceTraveledSoFar to distanceToTravel:

if (distanceTraveledSoFar >= distanceToTravel)
{
// You've arrived!
}


A potential optimization is to use distance squared values rather than distance as sqrt is relatively costly to call each tick.

• Excellent! Using distance hadn't crossed my mind, silly me! Thanks! – user2990037 May 5 '14 at 21:28

Define a function that takes care of not overshooting the target, like this:

template<typename T, typename D>
T Approach(T from, T to, D limit)
{
D diff = Abs(from - to);
limit = Abs(limit);
if(diff > limit)
{
if(from < to)
return from + limit;
else
return from - limit;
}
else
};


Now replace this

curPos += curVel;


with

curPos = Approach(curPos, endPos, curVel);


And you can just check for equality.

Edit:
Above works well if the movement is limited and straight forward. But movement is often not that predictable. The alternative is checking for proximity rather than the exact position. This will become necessary if the movement is physics based.

// If the position is very near the end point
if((endPos-curPos).length() < 25)
{
// Reverse movement positions