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 Answer 1

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\$

You must log in to answer this question.

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