0
\$\begingroup\$

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?

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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));
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .