# Math: determining a proper procedural vector for sine-movement

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.

// Replace your "x" axis with a vector that points along your diagonal.