# Move a distance with sine affect

This topic is 2944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi there! I've got a function that moves an object by a specified distance (moveAmt), at a speed of moveX, moveY, moveZ. I'd like to apply a sine effect to the movement. You know, starts out moving slowly, speeds up toward the middle, and slows down when reaching the destination. Given an internal game clock of 60Hz, how can I determine how much to modify useMoveX,useMoveY,useMoveZ at a particular tick during the movement? Or maybe I should always set the position relative to the origX,origY,origZ. I'm cool with either way, but don't know how to calculate. :) Assume that the game clock starts at counter 0 when this function is first run. Any ideas would be really helpful. Thanks so much!
//
// Move
//
// Moves an object in a specified direction
// by a specified distance, at a specified speed
//
// 0 - Move amount
// 1 - move X (per tic)
// 2 - move Y (per tic)
// 3 - move Z (per tic)
// 4 - tag of object to affect
// 5 - option:
//		1 - Use a sine effect
//
boolean Move(Object::object_t *obj, Object::object_t *hitobj, scriptparams_t *p)
{
#define moveAmt (p->numdata[0])
#define moveX (p->numdata[1])
#define moveY (p->numdata[2])
#define moveZ (p->numdata[3])
#define tag (p->numdata[4])
#define sine (p->numdata[5])
#define origX (p->numdata[8])
#define origY (p->numdata[9])
#define origZ (p->numdata[10])
#define first (p->numdata[11])

Object::object_t *object;

object = GetObjectFromParamTag(obj, hitobj, (int)tag);

if (!object)
return true;

// On first run, record our original position
// so we know when we've gone far enough.
if (first == 0.0f)
{
first = 1.0f;
origX = object->x;
origY = object->y;
origZ = object->z;
}

float useMoveX = moveX;
float useMoveY = moveY;
float useMoveZ = moveZ;

// Move using a sine effect,
// making it more smooth
if (sine == 1.0f)
{
// Here, we want to clamp
// the tics of our movement
// to a 0-180 range.
// But since the movement is going to be altered
// with a sine movement, how do we figure out
// how long it's going to take??
}

Blockmap::UnSetThingPosition(obj);
object->x += useMoveX;
object->y += useMoveY;
object->z += useMoveZ;

float dist = U_GetDistance(origX, origY, origZ, object->x, object->y, object->z);
boolean result = false;

// We've gone far enough, so snap to our destination
if (dist > moveAmt)
{
Vector::vector_t finalPos;
Vector::Normalize(&finalPos);
Vector::Mul(&finalPos, moveAmt);

object->x = origX + finalPos.x;
object->y = origY + finalPos.y;
object->z = origZ + finalPos.z;
result = true;
}

Blockmap::SetThingPosition(object);
return result;
#undef moveAmt
#undef moveX
#undef moveY
#undef moveZ
#undef tag
#undef sine
#undef origX
#undef origY
#undef origZ
#undef first
}


##### Share on other sites
Hi,

If you want the object to move in a sinusoidal path, just set the object's position to a given sample. E.g., for 70 frames, a full sine wave displacing [-1,1]:
X(frame) = sin(2.0*pi*(frame/70.0))

If you want to do this by altering the object's speed, take the derivative of X(frame) with respect to frame:
V(frame) = (1.0/35.0)*pi*cos(2.0*pi*(frame/70.0))

Sine and cosine are standard in basically any math library.

-G

##### Share on other sites
Quote:
 Original post by GeometrianHi,If you want the object to move in a sinusoidal path, just set the object's position to a given sample. E.g., for 70 frames, a full sine wave displacing [-1,1]:X(frame) = sin(2.0*pi*(frame/70.0))If you want to do this by altering the object's speed, take the derivative of X(frame) with respect to frame:V(frame) = (1.0/35.0)*pi*cos(2.0*pi*(frame/70.0))Sine and cosine are standard in basically any math library.-G
I think the OP is asking how to implement an 'ease in, ease out' animation effect rather than how to move an object along a sinusoidal path. (If I'm wrong about that, please ignore the rest of this post :)

@The OP: Say you have a starting point, a unit-length direction vector, a distance to be traveled, and a time interval in which to travel that distance.

One way to move an object to the goal with linear speed would be as follows (pseudocode typed into post, so no guarantee of correctness):
elapsed_time += time_step; // time_step would be 1/60 in your casefloat t = elapsed_time / travel_time;if (t >= 1) {    t = 1;    arrived_at_destination = true;}position = start_position + direction * travel_distance * t;
To get the 'sine effect' to which you refer, simply add the following lines (in bold):
float t = elapsed_time / travel_time;t = sin(-pi_over_2 + t * pi);t = .5 + t * .5;
This is an example of an 'ease in, ease out' function (you can find other, similar 'ease' functions if you look around online a bit).

• 10
• 17
• 9
• 14
• 41
• ### Forum Statistics

• Total Topics
631068
• Total Posts
2997741
×