Search code examples
pythonpygame3d

Combining Pitch and Yaw Rotations in 3D Engine


I am making a 3D engine and have everything worked out except the pitch and yaw rotation. These work perfectly when only one is implemented, but when I try to combine them something is off. My first clue of this was when I looked straight down on an object below me and tried to turn on the yaw axis. The result looked nothing like what it would in real life. Here is the code I'm using for rotation:

    global xAngle
    global yAngle
    global deltaX
    global deltaY
    global deltaZ
    
    xRel = x-camX
    yRel = y-camY
    zRel = z-camZ

    global pressed

    if xRel == 0:
        xAngle = 1.5708
    else:
        xAngle = math.atan(zRel/xRel)
    if xAngle < 0:
        xAngle+=3.14159
    
    if zRel == 0:
        yAngle = 1.5708
    else:
        yAngle = math.atan(yRel/zRel)


    #x and z are changed according the the yaw angle
    newXRel = math.sqrt(xRel*xRel+zRel*zRel) * math.cos(xAngle-math.radians(yaw)) 
    newZRel = math.sqrt(xRel*xRel+zRel*zRel) * math.sin(xAngle-math.radians(yaw))

    xRel = newXRel
    zRel = newZRel
    
    #y and z are changed according to the pitch angle        
    newYRel = math.sqrt(yRel*yRel+zRel*zRel) * math.sin(yAngle-math.radians(pitch)) 
    newZRel = math.sqrt(yRel*yRel+zRel*zRel) * math.cos(yAngle-math.radians(pitch))
    
    yRel = newYRel
    zRel = newZRel

This is using pygame, and I can add the full program if necessary.

Obviously, I am not combining the rotations in the correct manner. Could someone please give me a hint on where I am going wrong? Thanks.


Solution

  • When I first learned linear algebra, it wasn't clear how often I would need to use it to solve problems. You've found a problem that gets much easier with linear algebra, but it looks like you haven't learned the subject just yet. You're trying to apply tools that work well in 1d or 2d, but get really tricky in 3d.

    Your intuition is right that one rotation affects the others. And you can work around that problem by compensating for it -- up to a point. If you continue down this path, there will be certain object poses where your trig functions "blow up" (become numerically unstable).

    When modeling the pose of an object in 3D space, there are two commonly used approaches that overcome these challenges:

    1. Quaternions
    2. Transformation Matrices

    Quaternions are concise. They represent the rotation of an object with only 4 numbers. But they're a little hard to understand. But they're common in video games and spacecraft orientations.

    3D Transformation matrices are 3x3 matrices that can represent a diverse range of coordinate transformations (including not only rotation, but also scale, stretch, and shear.) They're a little easier to understand than quaternions but they require 9 numbers, and you have to be a little careful not to accidentally introduce other effects.

    There's a lot to learn in these areas -- more than I can fit into a SO response. These two topics should help you find the right documentation to read and YouTube videos to watch.

    Edit: I've added links to Wikipedia on the specific topics above. Given where you're starting from, I would suggest you start by looking at the Wikipedia article section on rotation matrices in two dimensions Once you can follow how those rotation matrices work, then move on to generalizing to 3D rotation matrices.