My Problem

Suppose you have an object moving along the x-axis, wobbling up and down. Movement code might look like this:

x += 1;
y = Sin(x);
Move((x,y) * speed);

When I try to figure out a method to move my object along a sine wave, say diagonally, I run into trouble. I am not sure what kind of Vector math I use to calculate the appropriate Sine movement along a diagonal where both X and Y values must be altered.

The visual result would be the object bobbing up and down and sideways but still moving in its given direction.

How do I enable sine movement along a diagonal?


This can be achieved in multiple ways. The simplest is probably to calculate your vector as movement into the x-direction as you showed us in your question:

$$ v_x = \begin{bmatrix}x\\\sin(x)\end{bmatrix} $$

Now you simply multiply the vector with a rotation matrix: $$ v = \begin{bmatrix}\cos(\alpha)&-sin(\alpha)\\\sin(\alpha)&\cos(\alpha)\end{bmatrix} \cdot s \cdot v_x $$

Here, \$s\$ is the movement speed and \$\alpha\$ the angle between your x-axis and the vector pointing into the actual movement direction you want to move in.

However, it gets a little bit more complicated if you want the object to be able to change its direction. You can do this as follows:

$$ p_{N+1} = p_N + s \cdot v_d + a \cdot \sin(w)\cdot v_{offset} $$

\$p_N\$ is the current position and \$p_{N+1}\$ the next position. \$v_d\$ is your current movement direction vector. It must be of length 1! So always normalize this vector. \$v_{offset}\$ is a vector orthogonal to your movement direction. You can get it by multiplying it with a \$90°\$ rotation matrix. In 2d, you just need to exchange the x and y values of \$v_d\$ and add a minus sign to one of both values. The variable \$w\$ is an arbitrary value that changes over time or while moving and \$a\$ is the amplitude of the sine wave.

The part \$s \cdot v_d + a \cdot \sin(w)\cdot v_{offset}\$ is the velocity vector that you wan to use in your move function.

This is basically the same as DMGregorys answer.


Just change your coordinate system.

// Replace your "x" axis with a vector that points along your diagonal.
Vector2 alongAxis = (diagonal_x, diagonal_y);

// Replace your "y" axis with a vector that points perpendicular to that.
Vector2 crossAxis = (-diagonal_y, diagonal_x);

// Move as before, using this new rotated coordinate system.
x += (alongAxis.x + Sin(t) * crossAxis.x) * speed;
y += (alongAxis.y + Sin(t) * crossAxis.y) * speed;

Move((x, y));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.