1
\$\begingroup\$

I have a 2-dimensional image of smiley face in a 3-dimensional space. I want it to rotate like a fan, so the smiley would look as if it's rolling like a wheel in place. Since the smiley is placed in a 3D space it can face any direction, but I always want it to rotate around like a wheel.

I use Minecraft so the Z and Y have the opposite jobs. (Y is the height).

I use these 3 functions for rotating around the x, y and z axis.

public static final Vector rotateAroundAxisX(Vector v, double angle) {
    double y, z, cos, sin;
    cos = Math.cos(angle);
    sin = Math.sin(angle);
    y = v.getY() * cos - v.getZ() * sin;
    z = v.getY() * sin + v.getZ() * cos;
    return v.setY(y).setZ(z);
}

public static final Vector rotateAroundAxisY(Vector v, double angle) {
    double x, z, cos, sin;
    cos = Math.cos(angle);
    sin = Math.sin(angle);
    x = v.getX() * cos + v.getZ() * sin;
    z = v.getX() * -sin + v.getZ() * cos;
    return v.setX(x).setZ(z);
}

public static final Vector rotateAroundAxisZ(Vector v, double angle) {
    double x, y, cos, sin;
    cos = Math.cos(angle);
    sin = Math.sin(angle);
    x = v.getX() * cos - v.getY() * sin;
    y = v.getX() * sin + v.getY() * cos;
    return v.setX(x).setY(y);
}

Sometimes I spawn the smiley facing the negative/positive X direction so to make it look like a wheel I have to rotate it around the X axis. But sometimes I spawn the smiley facing the negative/positive Z direction so I have to rotate it around the Z axis.

I searched online and found a term for an object's axes, and the one I was looking for is called "Roll".

Is there any way to rotate this smiley like a wheel regardless of where it's facing? a.k.a rotate it around its own "roll axis"?

\$\endgroup\$
1
\$\begingroup\$

I got you. Classic dynamics question right here. The three types are called 'roll', 'pitch', and 'yaw', corresponding to rotation about the x-y-z axes (respectively).
First, some vocabulary:

  1. Frame - same thing as a coordinate system, but it doesn't have to be located at the origin, so it has both an orientation and a position (also called a 'transform'). Ex: 2 frame system

  2. Directional Cosine Matrix (DCM) - 3x3 matrix describing how to transform vectors between frames.

What you want to do is place a frame at the base of the fan, with the x-axis pointed toward the front of the fan (such that rotation about the fan's x-axis, 'roll', forms the desired motion).

A frame is defined by a DCM (orientation) and a position vector.
Let's say you have a vector which defines the location of a point in the global frame. To express this vector in the 'fan' frame you must multiply by the frame's orientation, and subtract the frame's position.
f_A_b = frame.orientation
v_f = f_A_b * v_b - frame.position
My notation means this: v_f is the vector 'v' expressed in the 'f' frame (for fan). Uppercase letters are matrices. f_A_b is the DCM, 'A', which transforms from the 'b' frame to the 'f' frame.

By transposing the DCM, we get the opposite transform.
f_A_b = frame.orientation
b_A_f = (f_A_b)^T
v_b = b_A_f * v_f + frame.position
Check out this python source that shows how rotation about a frame's own x-axis is performed: link

So what you need to do is define the DCM for your fan (can be created from 3 rotations about the base coordinates and multiplied together - found here), and then update the fan frame during your game tick. Then, you can write a 'fromFanToBase' function to get your vector in the base frame.

\$\endgroup\$

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.