3D数学 欧拉角类源代码(附中文注释)
来源:互联网 发布:c语言库函数查询工具 编辑:程序博客网 时间:2024/06/12 00:27
欧拉角类源代码(附中文注释)
///////////////////////////////////////////////////////////////////////////////// 3D数学基础:游戏与图形开发// 3D Math Primer for Games and Graphics Development//// EulerAngles.h - 欧拉角类声明// EulerAngles.h - Declarations for class EulerAngles// // 登录gamemath.com来获得该文件的最新版本// Visit gamemath.com for the latest version of this file.//// 更多细节,请参见EulerAngles.cpp// For more details, see EulerAngles.cpp///////////////////////////////////////////////////////////////////////////////#ifndef __EULERANGLES_H_INCLUDED__#define __EULERANGLES_H_INCLUDED__// 前向声明// Forward declarationsclass Quaternion;class Matrix4x3;class RotationMatrix;//---------------------------------------------------------------------------// class EulerAngles//// 这个类呈现了heading-pitch-bank欧拉角三数// This class represents a heading-pitch-bank Euler angle triple.class EulerAngles {public:// 公有数据// Public data // 直接表示。储存三个度数,以弧度形式 // Straightforward representation. Store the three angles, in // radians float heading; float pitch; float bank;// 公有操作// Public operations // 默认构造器不做任何工作 // Default constructor does nothing EulerAngles() {} // 用三个数值构造 // Construct from three values EulerAngles(float h, float p, float b) : heading(h), pitch(p), bank(b) {} // 设置单位三数(均为0) // Set to identity triple (all zeros) void identity() { pitch = bank = heading = 0.0f; } // 确定“标准”欧拉角三数 // Determine "canonical" Euler angle triple void canonize(); // 转换四元数到欧拉角形式。 // 这个四元数输入明确假定执行从物体坐标系到惯性坐标系还是惯性坐标系到物体坐标系。 // Convert the quaternion to Euler angle format. The input quaternion // is assumed to perform the rotation from object-to-inertial // or inertial-to-object, as indicated. void fromObjectToInertialQuaternion(const Quaternion &q); void fromInertialToObjectQuaternion(const Quaternion &q); // 转换这个转化矩阵到欧拉角形式。这个输入矩阵明确假定执行从物体坐标系到惯性坐标系还是惯性坐标系到物体坐标系。 // 这个矩阵的平移部分被忽略。这个矩阵假定是正交矩阵。 // Convert the transform matrix to Euler angle format. The input // matrix is assumed to perform the transformation from // object-to-world, or world-to-object, as indicated. The // translation portion of the matrix is ignored. The // matrix is assumed to be orthogonal. void fromObjectToWorldMatrix(const Matrix4x3 &m); void fromWorldToObjectMatrix(const Matrix4x3 &m); // 从旋转矩阵到欧拉角形式的转换。 // Convert a rotation matrix to Euler Angle form. void fromRotationMatrix(const RotationMatrix &m);};// 全局“单位”欧拉角常量// A global "identity" Euler angle constantextern const EulerAngles kEulerAnglesIdentity;/////////////////////////////////////////////////////////////////////////////#endif // #ifndef __EULERANGLES_H_INCLUDED__
///////////////////////////////////////////////////////////////////////////////// 3D数学基础:游戏与图形开发// 3D Math Primer for Games and Graphics Development//// EulerAngles.cpp - 欧拉角类实现// EulerAngles.cpp - Implementation of class EulerAngles//// 登录gamemath.com来获得该文件的最新版本// Visit gamemath.com for the latest version of this file.///////////////////////////////////////////////////////////////////////////////#include <math.h>#include "EulerAngles.h"#include "Quaternion.h"#include "MathUtil.h"#include "Matrix4x3.h"#include "RotationMatrix.h"///////////////////////////////////////////////////////////////////////////////// 注意:// Notes://// 参见第11章来获得关于这个类的更多设计决策。// See Chapter 11 for more information on class design decisions.//// 参见10.3获得欧拉角约定的更多信息。// See section 10.3 for more information on the Euler angle conventions// assumed.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 全局数据// global data///////////////////////////////////////////////////////////////////////////////// 全局“单位”欧拉角常量。现在我们不能正确地知道这个物体可能被构建和其他物体的关系,// 所以这个物体很有可能在初始化之前被参考。然而,在大部分的实现,在程序开始的时候是非零初始化,// 在任何物体被构建之前。// The global "identity" Euler angle constant. Now we may not know exactly// when this object may get constructed, in relation to other objects, so// it is possible for the object to be referenced before it is initialized.// However, on most implementations, it will be zero-initialized at program// startup anyway, before any other objects are constructed.const EulerAngles kEulerAnglesIdentity(0.0f, 0.0f, 0.0f);///////////////////////////////////////////////////////////////////////////////// 欧拉角类实现// class EulerAngles Implementation/////////////////////////////////////////////////////////////////////////////////---------------------------------------------------------------------------// EulerAngles::canonize//// 设置欧拉角三数为“标准”值。这不会改变欧拉角呈现的3D方位,//但是如果角度是出于其他目的(例如角速度等),这个操作是不可用的。// Set the Euler angle triple to its "canonical" value. This does not change// the meaning of the Euler angles as a representation of Orientation in 3D,// but if the angles are for other purposes such as angular velocities, etc,// then the operation might not be valid.//// 参见10.3节来获得更多信息。// See section 10.3 for more information.void EulerAngles::canonize() { // 首先,回绕pitch到-pi到pi // First, wrap pitch in range -pi ... pi pitch = wrapPi(pitch); // 现在,检查矩阵的“后面”,pitch超出标准范围-pi/2到pi/2 // Now, check for "the back side" of the matrix, pitch outside // the canonical range of -pi/2 ... pi/2 if (pitch < -kPiOver2) { pitch = -kPi - pitch; heading += kPi; bank += kPi; } else if (pitch > kPiOver2) { pitch = kPi - pitch; heading += kPi; bank += kPi; } // 好了,现在检查万向锁情况(需要一点容忍度) // OK, now check for the gimbel lock case (within a slight // tolerance) if (fabs(pitch) > kPiOver2 - 1e-4) { // 我们遇到了万向锁。将所有竖直轴的旋转交给heading // We are in gimbel lock. Assign all rotation // about the vertical axis to heading heading += bank; bank = 0.0f; } else { // 没有遇到万向锁。回绕到标准范围的bank角度。 // Not in gimbel lock. Wrap the bank angle in // canonical range bank = wrapPi(bank); } // 将heading回绕到标准范围 // Wrap heading in canonical range heading = wrapPi(heading);}//---------------------------------------------------------------------------// EulerAngles::fromObjectToInertialQuaternion//// 构建欧拉角,给定物体坐标系->惯性坐标系旋转四元数// Setup the Euler angles, given an object->inertial rotation quaternion//// 参见10.6.6来获得更多信息。// See 10.6.6 for more information.void EulerAngles::fromObjectToInertialQuaternion(const Quaternion &q) { // 提取sin(pitch) // Extract sin(pitch) float sp = -2.0f * (q.y*q.z - q.w*q.x); // 检查万向锁,需要容忍一些数值上的不精确 // Check for Gimbel lock, giving slight tolerance for numerical imprecision if (fabs(sp) > 0.9999f) { // 直接设为垂直向上或垂直向下 // Looking straight up or down pitch = kPiOver2 * sp; // 计算heading,将bank置为0 // Compute heading, slam bank to zero heading = atan2(-q.x*q.z + q.w*q.y, 0.5f - q.y*q.y - q.z*q.z); bank = 0.0f; } else { // 计算角度。我们不需要使用“安全”asin函数,因为但我们检查万向锁时,已经检查范围错误 // Compute angles. We don't have to use the "safe" asin // function because we already checked for range errors when // checking for Gimbel lock pitch = asin(sp); heading = atan2(q.x*q.z + q.w*q.y, 0.5f - q.x*q.x - q.y*q.y); bank = atan2(q.x*q.y + q.w*q.z, 0.5f - q.x*q.x - q.z*q.z); }}//---------------------------------------------------------------------------// EulerAngles::fromInertialToObjectQuaternion//// 构建欧拉角,从惯性坐标系->物体坐标系旋转四元数// Setup the Euler angles, given an inertial->object rotation quaternion//// 参见10.6.6节来获得更多信息。// See 10.6.6 for more information.void EulerAngles::fromInertialToObjectQuaternion(const Quaternion &q) { // 提取sin(pitch) // Extract sin(pitch) float sp = -2.0f * (q.y*q.z + q.w*q.x); // 检查万向锁,需要容忍一些数值上的不精确 // Check for Gimbel lock, giving slight tolerance for numerical imprecision if (fabs(sp) > 0.9999f) { // 直接设为垂直向上或垂直向下 // Looking straight up or down pitch = kPiOver2 * sp; // 计算heading,将bank置为0 // Compute heading, slam bank to zero heading = atan2(-q.x*q.z - q.w*q.y, 0.5f - q.y*q.y - q.z*q.z); bank = 0.0f; } else { // 计算角度。我们不需要使用“安全”asin函数,因为但我们检查万向锁时,已经检查范围错误 // Compute angles. We don't have to use the "safe" asin // function because we already checked for range errors when // checking for Gimbel lock pitch = asin(sp); heading = atan2(q.x*q.z - q.w*q.y, 0.5f - q.x*q.x - q.y*q.y); bank = atan2(q.x*q.y - q.w*q.z, 0.5f - q.x*q.x - q.z*q.z); }}//---------------------------------------------------------------------------// EulerAngles::fromObjectToWorldMatrix//// 构建欧拉角,给定物体坐标系->世界坐标系矩阵。// Setup the Euler angles, given an object->world transformation matrix.//// 这个矩阵假定是正交的。平移部分被忽略。// The matrix is assumed to be orthogonal. The translation portion is// ignored.//// See 10.6.2 for more information.void EulerAngles::fromObjectToWorldMatrix(const Matrix4x3 &m) { // 从m32提取sin(pitch) // Extract sin(pitch) from m32. float sp = -m.m32; // 检查万向锁 // Check for Gimbel lock if (fabs(sp) > 9.99999f) { // 直接设为垂直向上或垂直向下 // Looking straight up or down pitch = kPiOver2 * sp; // 计算heading,将bank置为0 // Compute heading, slam bank to zero heading = atan2(-m.m23, m.m11); bank = 0.0f; } else { // 计算角度。我们不需要使用“安全”asin函数,因为但我们检查万向锁时,已经检查范围错误 // Compute angles. We don't have to use the "safe" asin // function because we already checked for range errors when // checking for Gimbel lock heading = atan2(m.m31, m.m33); pitch = asin(sp); bank = atan2(m.m12, m.m22); }}//---------------------------------------------------------------------------// EulerAngles::fromWorldToObjectMatrix//// 构建欧拉角,给定世界坐标系->物体坐标系变换矩阵。// Setup the Euler angles, given a world->object transformation matrix.//// 这个矩阵假定是正交的。这个平移部分会被忽略。// The matrix is assumed to be orthogonal. The translation portion is// ignored.//// 参见10.6.2来获得更多信息。// See 10.6.2 for more information.void EulerAngles::fromWorldToObjectMatrix(const Matrix4x3 &m) { // 从m23提取sin(pitch) // Extract sin(pitch) from m23. float sp = -m.m23; // 检查万向锁 // Check for Gimbel lock if (fabs(sp) > 9.99999f) { // 直接设为垂直向上或垂直向下 // Looking straight up or down pitch = kPiOver2 * sp; // 计算heading,将bank置为0 // Compute heading, slam bank to zero heading = atan2(-m.m31, m.m11); bank = 0.0f; } else { // 计算角度。我们不需要使用“安全”asin函数,因为但我们检查万向锁时,已经检查范围错误 // Compute angles. We don't have to use the "safe" asin // function because we already checked for range errors when // checking for Gimbel lock heading = atan2(m.m13, m.m33); pitch = asin(sp); bank = atan2(m.m21, m.m22); }}//---------------------------------------------------------------------------// EulerAngles::fromRotationMatrix//// 构建欧拉角,给定一个旋转矩阵。// Setup the Euler angles, given a rotation matrix.//// 参见10.6.2来获得更多信息。// See 10.6.2 for more information.void EulerAngles::fromRotationMatrix(const RotationMatrix &m) { // 从m23提取sin(pitch) // Extract sin(pitch) from m23. float sp = -m.m23; // 检查万向锁 // Check for Gimbel lock if (fabs(sp) > 9.99999f) { // 直接设为垂直向上或垂直向下 // Looking straight up or down pitch = kPiOver2 * sp; // 计算heading,将bank置为0 // Compute heading, slam bank to zero heading = atan2(-m.m31, m.m11); bank = 0.0f; } else { // 计算角度。我们不需要使用“安全”asin函数,因为但我们检查万向锁时,已经检查范围错误 // Compute angles. We don't have to use the "safe" asin // function because we already checked for range errors when // checking for Gimbel lock heading = atan2(m.m13, m.m33); pitch = asin(sp); bank = atan2(m.m21, m.m22); }}
0 0
- 3D数学 欧拉角类源代码(附中文注释)
- 3D数学 数学通用函数库源代码(附中文注释)
- 3D数学 4x3矩阵类源代码(附中文注释)
- J2ME 3D编程——第一个3D程序(附源代码)
- 算法基础(七):二叉排序树基本操作-插入、删除(附源代码加注释)
- (转)DirectShow中写push模式的source filter流程 + 源代码(内附详细注释)
- 使用TCP协议实现一个可以上传文件的客户端源代码(附详细注释)
- 使用TCP协议写一个可以上传文件的服务器端源代码(附详细注释)
- linux 0.11源代码完全中文注释
- python源代码中需要加入中文注释
- 源代码jar包中的中文注释乱码
- 源代码jar包中中文注释乱码
- 源代码jar包中中文注释乱码
- 【数学】3D数学基础
- 微软ping程序源代码完整版(附详细的注释)
- 微软ping程序源代码完整版(附详细的注释)
- 【转】微软ping程序源代码完整版(附详细的注释)
- mybatis-generator 自动生成带中文注释方法(附实体类)
- 普通java类获取 spring中的bean方法
- Idea配置svn
- android intent跳转时传参
- nyoj 众数问题 95 (数学)
- Android内存优化(4)
- 3D数学 欧拉角类源代码(附中文注释)
- CodeForces 339B (贪心模拟)
- 安装PIL等库出现Python version2.7 required,which was not found in the registry.
- WebP 探寻之路 --- SDWebImage支持webp格式的图片
- 数据库查询
- 谈谈乐观锁和悲观锁
- 用 WinPcap 获取网络接口列表
- Android发送短信验证码
- Java Integer问题