官术网_书友最值得收藏!

  • Game Physics Cookbook
  • Gabor Szauer
  • 591字
  • 2021-04-02 20:27:32

Axis angle rotation

As discussed earlier, we can combine yaw, pitch, and roll using matrix multiplication to create a complete rotation matrix. Creating a rotation matrix by performing each rotation sequentially introduces the possibility of a Gimbal Lock.

We can avoid that Gimbal Lock if we change how a rotation is represented. Instead of using three Euler angles to represent a rotation, we can use an arbitrary axis, and some angle to rotate around that axis.

Given axis Axis angle rotation, we can define a matrix that will rotate some angle Axis angle rotation around that axis:

Axis angle rotation

Where Axis angle rotation and XYZ = Arbitrary Axis (unit length). We will explore how this matrix is derived in the How it works… section.

Getting ready

Like before, we are going to implement two versions of this function. One version will return a 4 X 4 matrix; the other will return a 3 X 3 matrix. To avoid having to constantly calculate sin and cos, we're going to create local variables for c, s, and t. The axis being passed in does not have to be normalized. Because of this we have to check the length of the vector, and possibly normalize it.

How to do it…

Follow these steps to create a rotation matrix around an arbitrary axis:

  1. Add the declaration of the AxisAngle functions to matrices.h:
    mat4 AxisAngle(const vec3& axis, float angle);
    mat3 AxisAngle3x3(const vec3& axis, float angle);
  2. Implement the AxisAngle function in matrices.cpp:
    mat4 AxisAngle(const vec3& axis, float angle) {
       angle = DEG2RAD(angle);
       float c = cosf(angle);
       float s = sinf(angle);
       float t = 1.0f - cosf(angle);
    
       float x = axis.x;
       float y = axis.y;
       float z = axis.z;
       if (!CMP(MagnitudeSq(axis), 1.0f)) {
          floatinv_len = 1.0f / Magnitude(axis);
          x *= inv_len; // Normalize x
          y *= inv_len; // Normalize y
          z *= inv_len; // Normalize z
       } // x, y, and z are a normalized vector
    
       return mat4(
          t*(x*x) + c, t*x*y + s*z, t*x*z - s*y, 0.0f,
          t*x*y - s*z, t*(y*y) + c, t*y*z + s*x, 0.0f,
          t*x*z + s*y, t*y*z - s*x, t*(z*z) + c, 0.0f,
          0.0f, 0.0f, 0.0f, 1.0f
       );
    }
  3. Implement the AxisAngle3x3 function in matrices.cpp:
    mat3 AxisAngle3x3(const vec3& axis, float angle) {
       angle = DEG2RAD(angle);
       float c = cosf(angle);
       float s = sinf(angle);
       float t = 1.0f - cosf(angle);
    
       float x = axis.x;
       float y = axis.y;
       float z =axis.z;
       if (!CMP(MagnitudeSq(axis), 1.0f)) {
          float inv_len = 1.0f / Magnitude(axis);
          x *= inv_len; 
          y *= inv_len; 
          z *= inv_len;
       }
    
       return mat3(
          t * (x * x) + c,t * x * y + s * z,t * x * z - s * y, 
          t * x * y - s * z,t * (y * y) + c,t * y * z + s * x, 
          t * x * z + s * y,t * y * z - s * x,t * (z * z) + c
       );
    }

How it works…

Instead of rotating one axis at a time, then combining the rotation, axis angle rotation rotates by some angle around an arbitrary axis. This final rotation matrix is actually the sum of three other matrices:

  • The identity matrix
    • Multiplied by c, the cosine of theta
  • A matrix that is symmetrical about the main diagonal
    • Multiplied by t, 1 - the cosine of theta
  • A matrix that is anti-symmetrical about the main diagonal
    • Multiplied by s, the sine of theta

These matrices combine to form the final Axis-Angle rotation matrix:

How it works…
How it works…

The concept of symmetrical and anti-symmetrical matrices is outside the scope of this book. I recommend the following resources on both topics:

https://en.wikipedia.org/wiki/Symmetric_matrix

https://en.wikipedia.org/wiki/Skew-symmetric_matrix

主站蜘蛛池模板: 富阳市| 呼图壁县| 琼中| 晋州市| 宝应县| 灵丘县| 新晃| 墨脱县| 禹州市| 河津市| 岐山县| 上林县| 金坛市| 永宁县| 彭泽县| 礼泉县| 陆河县| 灌云县| 江城| 旺苍县| 苏尼特右旗| 延寿县| 西城区| 建阳市| 达州市| 庄河市| 桑植县| 昂仁县| 泊头市| 耒阳市| 竹溪县| SHOW| 克什克腾旗| 呼图壁县| 兴和县| 醴陵市| 邻水| 泰和县| 辉县市| 南陵县| 望都县|