3D数学基础:Matrix4*3类代码清单
生活随笔
收集整理的這篇文章主要介紹了
3D数学基础:Matrix4*3类代码清单
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Matrix4×3矩陣和RotationMatrix矩陣是《3D數(shù)學(xué)基礎(chǔ)》中的兩大矩陣。相比于只能運(yùn)用于旋轉(zhuǎn)功能的RotationMatrix矩陣,Matrix 4×3矩陣更加一般化,能夠支持更加復(fù)雜的變換。以下給出代碼清單。
程序清單:Matrix4×3.h
///////////////////////////////////////////////////////////////////////////// // // 3D數(shù)學(xué)基礎(chǔ):游戲與圖形開(kāi)發(fā) // 3D Math Primer for Games and Graphics Development // // Matrix4x3.h - Matrix4x3類(lèi)聲明 // Matrix4x3.h - Declarations for class Matrix4x3 //// 更多細(xì)節(jié),請(qǐng)看Matrix4x3.cpp // For more details, see Matrix4x3.cpp // /////////////////////////////////////////////////////////////////////////////#ifndef __MATRIX4X3_H_INCLUDED__ #define __MATRIX4X3_H_INCLUDED__class Vector3; class EulerAngles; class Quaternion; class RotationMatrix; //--------------------------------------------------------------------------- // Matrix4x3類(lèi) // class Matrix4x3 // // 實(shí)現(xiàn)4x3轉(zhuǎn)化矩陣。這個(gè)類(lèi)可以表現(xiàn)任何仿射變化。 // Implement a 4x3 transformation matrix. This class can represent // any 3D affine transformation.class Matrix4x3 { public:// 公有數(shù)據(jù) // Public data// 這個(gè)矩陣的值。上面3x3部分基本上包括了所有線性變換,最后一行是平移部分。// 查看Matrix4x3.cpp來(lái)獲得更多細(xì)節(jié)。// The values of the matrix. Basically the upper 3x3 portion// contains a linear transformation, and the last row is the// translation portion. See the Matrix4x3.cpp for more// details.float m11, m12, m13;float m21, m22, m23;float m31, m32, m33;float tx, ty, tz;// 公有操作 // Public operations// 設(shè)為單位矩陣// Set to identityvoid identity();// 直接使用矩陣平移部分// Access the translation portion of the matrix directlyvoid zeroTranslation();void setTranslation(const Vector3 &d);void setupTranslation(const Vector3 &d);// 構(gòu)造矩陣來(lái)表現(xiàn)一個(gè)從父空間到局部空間或相反方向的特定的轉(zhuǎn)換,// 假定本地空間是父空間的具體指定位置和朝向。// 這個(gè)朝向可能是被歐拉角或者旋轉(zhuǎn)矩陣來(lái)指定的。// Setup the matrix to perform a specific transforms from parent <->// local space, assuming the local space is in the specified position// and orientation within the parent space. The orientation may be// specified using either Euler angles, or a rotation matrixvoid setupLocalToParent(const Vector3 &pos, const EulerAngles &orient);void setupLocalToParent(const Vector3 &pos, const RotationMatrix &orient);void setupParentToLocal(const Vector3 &pos, const EulerAngles &orient);void setupParentToLocal(const Vector3 &pos, const RotationMatrix &orient);// 構(gòu)建矩陣執(zhí)行關(guān)于主要軸的旋轉(zhuǎn)// Setup the matrix to perform a rotation about a cardinal axisvoid setupRotate(int axis, float theta);// 構(gòu)建關(guān)于任意軸的旋轉(zhuǎn)矩陣。// Setup the matrix to perform a rotation about an arbitrary axisvoid setupRotate(const Vector3 &axis, float theta);// 構(gòu)建矩陣來(lái)執(zhí)行旋轉(zhuǎn),給定一個(gè)四元數(shù)形式的角位移。// Setup the matrix to perform a rotation, given// the angular displacement in quaternion formvoid fromQuaternion(const Quaternion &q);// 構(gòu)建矩陣來(lái)執(zhí)行每根軸上的縮放。使用向量形式的Vector3(k,k,k)來(lái)統(tǒng)一縮放k倍。// Setup the matrix to perform scale on each axisvoid setupScale(const Vector3 &s);// 構(gòu)建矩陣來(lái)執(zhí)行沿著任意軸的縮放。// Setup the matrix to perform scale along an arbitrary axisvoid setupScaleAlongAxis(const Vector3 &axis, float k);// 構(gòu)建矩陣來(lái)執(zhí)行切變// Setup the matrix to perform a shearvoid setupShear(int axis, float s, float t);// 構(gòu)建矩陣來(lái)執(zhí)行投影到一個(gè)通過(guò)原點(diǎn)的平面。// Setup the matrix to perform a projection onto a plane passing// through the originvoid setupProject(const Vector3 &n);// 構(gòu)建矩陣關(guān)于一個(gè)平行于基本平面的反射。// Setup the matrix to perform a reflection about a plane parallel// to a cardinal planevoid setupReflect(int axis, float k = 0.0f);// 設(shè)置矩陣執(zhí)行關(guān)于任意通過(guò)原點(diǎn)的平面的反射。// Setup the matrix to perform a reflection about an arbitrary plane// through the originvoid setupReflect(const Vector3 &n); };// 操作*用來(lái)變換點(diǎn),也用來(lái)連接矩陣。 // 從左到右相乘的順序和變換的順序是一樣的。 // Operator* is used to transforms a point, and also concatonate matrices. // The order of multiplications from left to right is the same as // the order of transformationsVector3 operator*(const Vector3 &p, const Matrix4x3 &m); Matrix4x3 operator*(const Matrix4x3 &a, const Matrix4x3 &b);// 操作*=使得和C++標(biāo)準(zhǔn)一致 // Operator *= for conformance to C++ standardsVector3 &operator*=(Vector3 &p, const Matrix4x3 &m); Matrix4x3 &operator*=(const Matrix4x3 &a, const Matrix4x3 &m);// 計(jì)算3x3矩陣部分的行列式 // Compute the determinant of the 3x3 portion of the matrixfloat determinant(const Matrix4x3 &m);// 計(jì)算矩陣的逆 // Compute the inverse of a matrixMatrix4x3 inverse(const Matrix4x3 &m);// 從矩陣中提取平移部分 // Extract the translation portion of the matrixVector3 getTranslation(const Matrix4x3 &m);// 從局部坐標(biāo)系->父坐標(biāo)系或父坐標(biāo)系->局部坐標(biāo)系提取位置/方位 // Extract the position/orientation from a local->parent matrix, // or a parent->local matrixVector3 getPositionFromParentToLocalMatrix(const Matrix4x3 &m); Vector3 getPositionFromLocalToParentMatrix(const Matrix4x3 &m);///////////////////////////////////////////////////////////////////////////// #endif // #ifndef __ROTATIONMATRIX_H_INCLUDED__程序清單:Matrix4×3.cpp
///////////////////////////////////////////////////////////////////////////// // // 《3D數(shù)學(xué)基礎(chǔ):游戲與圖形開(kāi)發(fā)》 // 3D Math Primer for Games and Graphics Development // // Matrix4x3.cpp - Matrix4x3實(shí)現(xiàn) // Matrix4x3.cpp - Implementation of class Matrix4x3 //// 更多細(xì)節(jié)請(qǐng)看11.5節(jié) // For more details see section 11.5. // /////////////////////////////////////////////////////////////////////////////#include <assert.h> #include <math.h>#include "Vector3.h" #include "EulerAngles.h" #include "Quaternion.h" #include "RotationMatrix.h" #include "Matrix4x3.h" #include "MathUtil.h"///////////////////////////////////////////////////////////////////////////// // // 注意: // Notes: // // 請(qǐng)看11章獲得類(lèi)設(shè)計(jì)決策的更多信息。 // See Chapter 11 for more information on class design decisions. // //--------------------------------------------------------------------------- // // 矩陣組織 // MATRIX ORGANIZATION // // 這個(gè)類(lèi)的目的是為了用戶可能執(zhí)行轉(zhuǎn)換操作,而不用擺弄加號(hào)、減號(hào)或者轉(zhuǎn)置矩陣直到輸出“看起來(lái)是正確的”。 // 不過(guò)當(dāng)然,這個(gè)內(nèi)部表述的詳細(xì)情況是很重要的。不單是為了這個(gè)文件的實(shí)現(xiàn)是正確的, // 而且偶爾直接進(jìn)入矩陣變量也是必須的,或者有益于優(yōu)化。因此,這里我們記錄我們的矩陣約定。 // The purpose of this class is so that a user might perform transformations // without fiddling with plus or minus signs or transposing the matrix // until the output "looks right." But of course, the specifics of the // internal representation is important. Not only for the implementation // in this file to be correct, but occasionally direct access to the // matrix variables is necessary, or beneficial for optimization. Thus, // we document our matrix conventions here. // // 我們使用行向量,所以跟矩陣相乘看起來(lái)是這樣的: // We use row vectors, so multiplying by our matrix looks like this: // // | m11 m12 m13 | // [ x y z ] | m21 m22 m23 | = [ x' y' z' ] // | m31 m32 m33 | // | tx ty tz | // // 嚴(yán)格執(zhí)行線性代數(shù)規(guī)則規(guī)定了這個(gè)乘法實(shí)際是未定義的。 // 為了繞過(guò)這個(gè)問(wèn)題,我們可以假定輸入和輸出向量有第四個(gè)坐標(biāo)為1。 // 同樣,我們不可以根據(jù)線性代數(shù)規(guī)則以學(xué)術(shù)形式地反轉(zhuǎn)4x3矩陣,我們也會(huì)假設(shè) // 最右列是[ 0 0 0 1 ]。它看起來(lái)像如下這樣的: // Strict adherance to linear algebra rules dictates that this // multiplication is actually undefined. To circumvent this, we can // consider the input and output vectors as having an assumed fourth // coordinate of 1. Also, since we cannot technically invert a 4x3 matrix // according to linear algebra rules, we will also assume a rightmost // column of [ 0 0 0 1 ]. This is shown below: // // | m11 m12 m13 0 | // [ x y z 1 ] | m21 m22 m23 0 | = [ x' y' z' 1 ] // | m31 m32 m33 0 | // | tx ty tz 1 | // // 萬(wàn)一你忘了矩陣乘法的線性代數(shù)規(guī)則(在第7.1.6和7.1.7節(jié)中描述過(guò)),查看操作*的擴(kuò)展計(jì)算定義。 // In case you have forgotten your linear algebra rules for multiplying // matrices (which are described in section 7.1.6 and 7.1.7), see the // definition of operator* for the expanded computations. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Matrix4x3類(lèi)成員 // Matrix4x3 class members // ///////////////////////////////////////////////////////////////////////////////--------------------------------------------------------------------------- // Matrix4x3::identity // // 設(shè)置矩陣為單位矩陣 // Set the matrix to identityvoid Matrix4x3::identity() {m11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;tx = 0.0f; ty = 0.0f; tz = 1.0f; }//--------------------------------------------------------------------------- // Matrix4x3::zeroTranslation // // 將矩陣的第四行都置為0,該行包含了平移部分 // Zero the 4th row of the matrix, which contains the translation portion.void Matrix4x3::zeroTranslation() {tx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setTranslation // // 用向量形式設(shè)置矩陣的平移部分 // Sets the translation portion of the matrix in vector formvoid Matrix4x3::setTranslation(const Vector3 &d) {tx = d.x; ty = d.y; tz = d.z; }//--------------------------------------------------------------------------- // Matrix4x3::setupTranslation // // 用向量形式設(shè)置矩陣的平移部分,并設(shè)置線性變換部分為單位矩陣 // Sets the translation portion of the matrix in vector formvoid Matrix4x3::setupTranslation(const Vector3 &d) {// 設(shè)置線性變換部分為單位矩陣// Set the linear transformation portion to identitym11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;// 設(shè)置平移部分// Set the translation portiontx = d.x; ty = d.y; tz = d.z; }//--------------------------------------------------------------------------- // Matrix4x3::setupLocalToParent // // 給定一個(gè)父參考幀中的局部參考幀的位置和朝向,構(gòu)造矩陣來(lái)執(zhí)行從局部空間->父空間的轉(zhuǎn)換。 // Setup the matrix to perform a local -> parent transformation, given // the position and orientation of the local reference frame within the // parent reference frame. // // 一個(gè)非常常見(jiàn)的用法是構(gòu)造從物體->世界矩陣。 // 作為一個(gè)示例,這種情況的轉(zhuǎn)換是很直接的。 // 我們首先從物體坐標(biāo)系到慣性坐標(biāo)系的轉(zhuǎn)換,然后平移到世界空間。 // A very common use of this will be to construct a object -> world matrix. // As an example, the transformation in this case is straightforward. We // first rotate from object space into inertial space, then we translate // into world space. // // 我們?cè)试S通過(guò)歐拉角或者旋轉(zhuǎn)矩陣來(lái)指定方位。 // We allow the orientation to be specified using either euler angles, // or a RotationMatrixvoid Matrix4x3::setupLocalToParent(const Vector3 &pos, const EulerAngles &orient) {// 創(chuàng)建旋轉(zhuǎn)矩陣// Create a rotation matrix.RotationMatrix orientMatrix;orientMatrix.setup(orient);// 構(gòu)造4x3矩陣。注意:如果我們真的關(guān)心速度,我們可以直接創(chuàng)建這個(gè)矩陣到各個(gè)變量,// 而不用使用臨時(shí)的旋轉(zhuǎn)矩陣。這會(huì)節(jié)約函數(shù)調(diào)用和一些的拷貝操作開(kāi)銷(xiāo)。// Setup the 4x3 matrix. Note: if we were really concerned with// speed, we could create the matrix directly into these variables,// without using the temporary RotationMatrix object. This would// save us a function call and a few copy operations.setupLocalToParent(pos, orientMatrix); }void Matrix4x3::setupLocalToParent(const Vector3 &pos, const RotationMatrix &orient) {// 復(fù)制矩陣的旋轉(zhuǎn)部分。根據(jù)RotationMatrix.cpp的注釋,這個(gè)旋轉(zhuǎn)矩陣通常是慣性坐標(biāo)系->物體坐標(biāo)系的矩陣,// 也就是從父空間->局部空間。我們想要局部空間->父空間旋轉(zhuǎn),復(fù)制的時(shí)候必須要轉(zhuǎn)置。// Copy the rotation portion of the matrix. According to// the comments in RotationMatrix.cpp, the rotation matrix// is "normally" an inertial->object matrix, which is// parent->local. We want a local->parent rotation, so we// must transpose while copyingm11 = orient.m11; m12 = orient.m21; m13 = orient.m31;m21 = orient.m12; m22 = orient.m22; m23 = orient.m32;m31 = orient.m13; m32 = orient.m23; m33 = orient.m33;// 現(xiàn)在設(shè)置平移部分。平移發(fā)生在3x3部分之后,所以我們可以簡(jiǎn)單直接地復(fù)制位置。// Now set the translation portion. Translation happens "after"// the 3x3 portion, so we can simply copy the position// field directlytx = pos.x; ty = pos.y; tz = pos.z; }//--------------------------------------------------------------------------- // Matrix4x3::setupParentToLocal // // 給定在父空間參考幀下的局部坐標(biāo)的位置和方向參考幀,構(gòu)造矩陣來(lái)執(zhí)行父空間->局部空間。 // Setup the matrix to perform a parent -> local transformation, given // the position and orientation of the local reference frame within the // parent reference frame. // // 它的一個(gè)非常常見(jiàn)的用法就是從世界坐標(biāo)系->物體坐標(biāo)系。 // 為了執(zhí)行這個(gè)轉(zhuǎn)換,我們通常首先會(huì)從世界坐標(biāo)系到慣性坐標(biāo)系的轉(zhuǎn)換,然后從慣性坐標(biāo)系到物體坐標(biāo)系的旋轉(zhuǎn)。 // 然而4x3矩陣可以完成后一個(gè)轉(zhuǎn)換。所以我們可以創(chuàng)建兩個(gè)矩陣T和R,然后連接M = TR。 // A very common use of this will be to construct a world -> object matrix. // To perform this transformation, we would normally FIRST transform // from world to inertial space, and then rotate from inertial space into // object space. However, out 4x3 matrix always translates last. So // we think about creating two matrices T and R, and then concatonating // M = TR. // // 我們?cè)试S使用歐拉角或者旋轉(zhuǎn)矩陣來(lái)指定朝向。 // We allow the orientation to be specified using either euler angles, // or a RotationMatrixvoid Matrix4x3::setupParentToLocal(const Vector3 &pos, const EulerAngles &orient) {// 創(chuàng)建一個(gè)旋轉(zhuǎn)矩陣。// Create a rotation matrix.RotationMatrix orientMatrix;orientMatrix.setup(orient);// 構(gòu)造4x3矩陣。// Setup the 4x3 matrix.setupParentToLocal(pos, orientMatrix); }void Matrix4x3::setupParentToLocal(const Vector3 &pos, const RotationMatrix &orient) {// 復(fù)制矩陣的旋轉(zhuǎn)部分。我們根據(jù)RotationMatrix.cpp注釋中的布局,可以直接復(fù)制元素(不用轉(zhuǎn)置)// Copy the rotation portion of the matrix. We can copy the// elements directly (without transposing) according// to the layout as commented in RotationMatrix.cppm11 = orient.m11; m12 = orient.m12; m13 = orient.m13;m21 = orient.m21; m22 = orient.m22; m23 = orient.m23;m31 = orient.m31; m32 = orient.m32; m33 = orient.m33;// 現(xiàn)在設(shè)置平移部分。通常地,我們通過(guò)取位置的負(fù)號(hào)來(lái)實(shí)現(xiàn)從世界到慣性坐標(biāo)系。// 然而,我們必須修正這個(gè)事實(shí)——旋轉(zhuǎn)是先發(fā)生的。所以必須先旋轉(zhuǎn)平移部分。// 這和創(chuàng)建一個(gè)平移矩陣T來(lái)平移-pos,和旋轉(zhuǎn)矩陣R,并且創(chuàng)建一個(gè)連接矩陣TR是一樣的。// Now set the translation portion. Normally, we would// translate by the negative of the position to translate// from world to inertial space. However, we must correct// for the fact that the rotation occurs "first." So we// must rotate the translation portion. This is the same// as create a translation matrix T to translate by -pos,// and a rotation matrix R, and then creating the matrix// as the concatenation of TRtx = -(pos.x*m11 + pos.y*m21 + pos.z*m31);ty = -(pos.x*m12 + pos.y*m22 + pos.z*m32);tz = -(pos.x*m13 + pos.y*m23 + pos.z*m33); }//--------------------------------------------------------------------------- // Matrix4x3::setupRotate // // 構(gòu)建矩陣執(zhí)行關(guān)于主要軸的旋轉(zhuǎn) // Setup the matrix to perform a rotation about a cardinal axis // // 使用基于1的索引指定旋轉(zhuǎn)軸 // The axis of rotation is specified using a 1-based index: // // 1 => 關(guān)于x軸旋轉(zhuǎn) // 2 => 關(guān)于y軸旋轉(zhuǎn) // 3 => 關(guān)于z軸旋轉(zhuǎn) // 1 => rotate about the x-axis // 2 => rotate about the y-axis // 3 => rotate about the z-axis // // theta是以弧度計(jì)的旋轉(zhuǎn)量。使用左手法則定義正方向的旋轉(zhuǎn)。 // theta is the amount of rotation, in radians. The left-hand rule is // used to define "positive" rotation. // // 平移部分被重設(shè)。 // The translation portion is reset. // // 參見(jiàn)8.2.2獲得更多信息。 // See 8.2.2 for more info.void Matrix4x3::setupRotate(int axis, float theta) {// 獲得旋轉(zhuǎn)角的sin和cos值// Get sin and cosine of rotation anglefloat s, c;sinCos(&s, &c, theta);// 檢查關(guān)于哪根軸旋轉(zhuǎn)// Check which axis they are rotating aboutswitch (axis) {// 關(guān)于x軸旋轉(zhuǎn)case 1: // Rotate about the x-axism11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = c; m23 = s;m31 = 0.0f; m32 = -s; m33 = c;break;// 關(guān)于y軸旋轉(zhuǎn)case 2: // Rotate about the y-axism11 = c; m12 = 0.0f; m13 = -s;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = s; m32 = 0.0f; m33 = c;break;// 關(guān)于z軸旋轉(zhuǎn)case 3: // Rotate about the z-axism11 = c; m12 = s; m13 = 0.0f;m21 = -s; m22 = c; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;break;default:// 不存在的軸索引// bogus axis indexassert(false);}// 重設(shè)平移部分// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupRotate // // 構(gòu)建關(guān)于任意軸的旋轉(zhuǎn)矩陣。 // 該軸必須通過(guò)原點(diǎn)。 // Setup the matrix to perform a rotation about an arbitrary axis. // The axis of rotation must pass through the origin. // // axis定義了哪根旋轉(zhuǎn)軸,并且必須是單位向量。 // axis defines the axis of rotation, and must be a unit vector. // // theta是旋轉(zhuǎn)量,以弧度計(jì)。左手法則定義了旋轉(zhuǎn)的正方向。 // theta is the amount of rotation, in radians. The left-hand rule is // used to define "positive" rotation. // // 平移部分會(huì)被重置。 // The translation portion is reset. // // 查看8.2.3來(lái)獲得更多信息。 // See 8.2.3 for more info.void Matrix4x3::setupRotate(const Vector3 &axis, float theta) {// 快速清楚檢查確保axis是單位向量// Quick sanity check to make sure they passed in a unit vector// to specify the axisassert(fabs(axis*axis - 1.0f) < .01f);// 獲得旋轉(zhuǎn)角的sin和cos值// Get sin and cosine of rotation anglefloat s, c;sinCos(&s, &c, theta);// 計(jì)算1 - cos(theta) 和一些公共的子表達(dá)式// Compute 1 - cos(theta) and some common subexpressionsfloat a = 1.0f - c;float ax = a * axis.x;float ay = a * axis.y;float az = a * axis.z;// 設(shè)置矩陣元素。這里仍然有一些機(jī)會(huì)去優(yōu)化,出于許多公共的子表達(dá)式。// 我們會(huì)讓編譯器來(lái)處理它..// Set the matrix elements. There is still a little more// opportunity for optimization due to the many common// subexpressions. We'll let the compiler handle that...m11 = ax*axis.x + c;m12 = ax*axis.y + axis.z*s;m13 = ax*axis.z - axis.y*s;m21 = ay*axis.x - axis.z*s;m22 = ay*axis.y + c;m23 = ay*axis.z + axis.x*s;m31 = az*axis.x + axis.y*s;m32 = az*axis.y - axis.x*s;m33 = az*axis.z + c;// 重置平移部分// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::fromQuaternion // // 構(gòu)建矩陣來(lái)執(zhí)行旋轉(zhuǎn),給定一個(gè)四元數(shù)形式的角位移。 // Setup the matrix to perform a rotation, given the angular displacement // in quaternion form. // // 平抑部分會(huì)被重置。 // The translation portion is reset. // // 查看10.6.3來(lái)獲得更多信息。 // See 10.6.3 for more info.void Matrix4x3::fromQuaternion(const Quaternion &q) {// 計(jì)算一些值來(lái)優(yōu)化公共子表達(dá)式// Compute a few values to optimize common subexpressionsfloat ww = 2.0f * q.w;float xx = 2.0f * q.x;float yy = 2.0f * q.y;float zz = 2.0f * q.z;// 設(shè)置矩陣元素。這里仍然有一些機(jī)會(huì)去優(yōu)化,出于許多公共的子表達(dá)式。// 我們會(huì)讓編譯器來(lái)處理它..// Set the matrix elements. There is still a little more// opportunity for optimization due to the many common// subexpressions. We'll let the compiler handle that...m11 = 1.0f - yy*q.y - zz*q.z;m12 = xx*q.y + ww*q.z;m13 = xx*q.z - ww*q.x;m21 = xx*q.y - ww*q.z;m22 = 1.0f - xx*q.x - zz*q.z;m23 = yy*q.z + ww*q.x;m31 = xx*q.z + ww*q.y;m32 = yy*q.z - ww*q.x;m33 = 1.0f - xx*q.x - yy*q.y;// 重置平移部分。// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupScale // // 構(gòu)建矩陣來(lái)執(zhí)行每根軸上的縮放。使用向量形式的Vector3(k,k,k)來(lái)統(tǒng)一縮放k倍。 // Setup the matrix to perform scale on each axis. For uniform scale by k, // use a vector of the form Vector3(k,k,k) // // 這個(gè)平移部分會(huì)被重置。 // The translation portion is reset. // // 查看8.3.1來(lái)獲得更多信息。 // See 8.3.1 for more info.void Matrix4x3::setupScale(const Vector3 &s) {// 設(shè)置矩陣元素。相當(dāng)直接// Set the matrix elements. Pretty straightforwardm11 = s.x; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = s.y; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = s.z;// 重置平移部分。// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupScaleAlongAxis // // 構(gòu)建矩陣來(lái)執(zhí)行沿著任意軸的縮放。 // Setup the matrix to perform scale along an arbitrary axis. // // 這根軸被單位向量指定。 // The axis is specified using a unit vector. // // 平移部分會(huì)被重置。 // The translation portion is reset. // // 查看8.3.2節(jié)來(lái)獲得更多信息。 // See 8.3.2 for more info.void Matrix4x3::setupScaleAlongAxis(const Vector3 &axis, float k) {// 快速清楚檢查確保axis是單位向量// Quick sanity check to make sure they passed in a unit vector// to specify the axisassert(fabs(axis*axis - 1.0f) < .01f);// 計(jì)算k-1和一些公共子表達(dá)式// Compute k-1 and some common subexpressionsfloat a = k - 1.0f;float ax = a * axis.x;float ay = a * axis.y;float az = a * axis.z;// 填充矩陣元素。我們會(huì)完成我們的公共子表達(dá)式的優(yōu)化,因?yàn)閷?duì)角相應(yīng)的矩陣元素是相等的// Fill in the matrix elements. We'll do the common// subexpression optimization ourselves here, since diagonally// opposite matrix elements are equalm11 = ax*axis.x + 1.0f;m22 = ay*axis.y + 1.0f;m32 = az*axis.z + 1.0f;m12 = m21 = ax*axis.y;m13 = m31 = ax*axis.z;m23 = m32 = ay*axis.z;// 重設(shè)平移部分// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupShear // // 構(gòu)建矩陣來(lái)執(zhí)行切變 // Setup the matrix to perform a shear // // 切變類(lèi)型被基于1的軸索引指定。通過(guò)一個(gè)矩陣變換一個(gè)點(diǎn)的效果如下面的偽代碼所示: // The type of shear is specified by the 1-based "axis" index. The effect // of transforming a point by the matrix is described by the pseudocode // below: // // axis == 1 => y += s*x, z += t*x // axis == 2 => x += s*y, z += t*y // axis == 3 => x += s*z, y += t*z // // 平移部分會(huì)被重置。 // The translation portion is reset. // // 查看8.6來(lái)獲得更多信息。 // See 8.6 for more info.void Matrix4x3::setupShear(int axis, float s, float t) {// 檢查它們想要那種切變類(lèi)型// Check which type of shear they wantswitch (axis) {// 使用x切變y和zcase 1: // Shear y and z using xm11 = 1.0f; m12 = s; m13 = t;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;break;//使用y切變x和zcase 2: // Shear x and z using ym11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = s; m22 = 1.0f; m23 = t;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;break;// 使用z來(lái)切變x和ycase 3: // Shear x and y using zm11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = s; m32 = t; m33 = 1.0f;break;default:// 不存在的軸索引// bogus axis indexassert(false);}// 重設(shè)平移部分// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupProject // // 構(gòu)建矩陣來(lái)執(zhí)行投影到一個(gè)通過(guò)原點(diǎn)的平面。這個(gè)平面垂直于單位向量n。 // Setup the matrix to perform a projection onto a plane passing // through the origin. The plane is perpendicular to the // unit vector n. // // 查看8.4.2來(lái)獲得更多的信息。 // See 8.4.2 for more info.void Matrix4x3::setupProject(const Vector3 &n) {// 快速清楚檢查確保axis是單位向量// Quick sanity check to make sure they passed in a unit vector// to specify the axisassert(fabs(n*n - 1.0f) < .01f);// 填充矩陣元素。我們會(huì)完成我們的公共子表達(dá)式的優(yōu)化,因?yàn)閷?duì)角相應(yīng)的矩陣元素是相等的// Fill in the matrix elements. We'll do the common// subexpression optimization ourselves here, since diagonally// opposite matrix elements are equalm11 = 1.0f - n.x*n.x;m22 = 1.0f - n.y*n.y;m33 = 1.0f - n.z*n.z;m12 = m21 = -n.x*n.y;m13 = m31 = -n.x*n.z;m23 = m32 = -n.y*n.z;// 重置平移部分// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Matrix4x3::setupReflect // // 構(gòu)建矩陣關(guān)于一個(gè)平行于基本平面的反射。 // Setup the matrix to perform a reflection about a plane parallel // to a cardinal plane. // // axis軸是基于1的索引,指定了關(guān)于哪個(gè)平面的投影: // axis is a 1-based index which specifies the plane to project about: // // 1 => 關(guān)于平面 x=k 的反射 // 2 => 關(guān)于平面 y=k 的反射 // 3 => 關(guān)于平面 z=k 的反射 // 1 => reflect about the plane x=k // 2 => reflect about the plane y=k // 3 => reflect about the plane z=k // // 平移部分會(huì)被恰當(dāng)?shù)卦O(shè)置,因?yàn)槿绻鹝!=0的時(shí)候平移必須會(huì)發(fā)生。 // The translation is set appropriately, since translation must occur if // k != 0 // // See 8.5 for more info.void Matrix4x3::setupReflect(int axis, float k) {// 檢查關(guān)于哪個(gè)平面的反射// Check which plane they want to reflect aboutswitch (axis) {// 關(guān)于平面x=k平面的反射case 1: // Reflect about the plane x=km11 = -1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;tx = 2.0f * k;ty = 0.0f;tz = 0.0f;break;// 關(guān)于y=k平面的反射case 2: // Reflect about the plane y=km11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = -1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;tx = 0.0f;ty = 2.0f * k;tz = 0.0f;break;// 關(guān)于z=k平面的反射case 3: // Reflect about the plane z=km11 = 1.0f; m12 = 0.0f; m13 = 0.0f;m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;m31 = 0.0f; m32 = 0.0f; m33 = -1.0f;tx = 0.0f;ty = 0.0f;tz = 2.0f * k;break;default:// 不存在的軸索引// bogus axis indexassert(false);}}//--------------------------------------------------------------------------- // Matrix4x3::setupReflect // // 設(shè)置矩陣執(zhí)行關(guān)于任意通過(guò)原點(diǎn)的平面的反射。這個(gè)單位向量n垂直于平面。 // Setup the matrix to perform a reflection about an arbitrary plane // through the origin. The unit vector n is perpendicular to the plane. // // 平移部分會(huì)被重置。 // The translation portion is reset. // // 查看8.5節(jié)來(lái)獲得更多的信息。 // See 8.5 for more info.void Matrix4x3::setupReflect(const Vector3 &n) {// 快速清楚檢查確保axis是單位向量// Quick sanity check to make sure they passed in a unit vector// to specify the axisassert(fabs(n*n - 1.0f) < .01f);// 計(jì)算公共子表達(dá)式// Compute common subexpressionsfloat ax = -2.0f * n.x;float ay = -2.0f * n.y;float az = -2.0f * n.z;// 填充矩陣元素。我們會(huì)完成我們的公共子表達(dá)式的優(yōu)化,因?yàn)閷?duì)角相應(yīng)的矩陣元素是相等的// Fill in the matrix elements. We'll do the common// subexpression optimization ourselves here, since diagonally// opposite matrix elements are equalm11 = 1.0f + ax*n.x;m22 = 1.0f + ay*n.y;m32 = 1.0f + az*n.z;m12 = m21 = ax*n.y;m13 = m31 = ax*n.z;m23 = m32 = ay*n.z;// 重置平移部分。// Reset the translation portiontx = ty = tz = 0.0f; }//--------------------------------------------------------------------------- // Vector * Matrix4x3 // // 變換頂點(diǎn)。這會(huì)使得向量類(lèi)看起來(lái)和線性代數(shù)紙上記號(hào)是一致的。 // Transform the point. This makes using the vector class look like it // does with linear algebra notation on paper. // // 我們也會(huì)提供*=操作,作為C語(yǔ)言的習(xí)慣約定。 // We also provide a *= operator, as per C convention. // // 參見(jiàn)7.1.7節(jié) // See 7.1.7Vector3 operator*(const Vector3 &p, const Matrix4x3 &m) {// 通過(guò)線性代數(shù)磨合// Grind through the linear algebra.return Vector3(p.x*m.m11 + p.y*m.m21 + p.z*m.m31 + m.tx,p.x*m.m12 + p.y*m.m22 + p.z*m.m32 + m.ty,p.x*m.m13 + p.y*m.m23 + p.z*m.m33 + m.tz); }Vector3 &operator*=(Vector3 &p, const Matrix4x3 &m) {p = p * m;return p; }//--------------------------------------------------------------------------- // Matrix4x3 * Matrix4x3 // // 矩陣連接。這會(huì)使得矩陣類(lèi)看起來(lái)和線性代數(shù)紙上記號(hào)是一致的。 // Matrix concatenation. This makes using the vector class look like it // does with linear algebra notation on paper. // // 我們也會(huì)提供*=操作,作為C語(yǔ)言的習(xí)慣約定。 // We also provide a *= operator, as per C convention. // // 參見(jiàn)7.1.6節(jié) // See 7.1.6Matrix4x3 operator*(const Matrix4x3 &a, const Matrix4x3 &b) {Matrix4x3 r;// 計(jì)算上面3x3(線性變換)部分// Compute the upper 3x3 (linear transformation) portionr.m11 = a.m11*b.m11 + a.m12*b.m21 + a.m13*b.m31;r.m12 = a.m11*b.m12 + a.m12*b.m22 + a.m13*b.m32;r.m13 = a.m11*b.m13 + a.m12*b.m23 + a.m13*b.m33;r.m21 = a.m21*b.m11 + a.m22*b.m21 + a.m23*b.m31;r.m22 = a.m21*b.m12 + a.m22*b.m22 + a.m23*b.m32;r.m23 = a.m21*b.m13 + a.m22*b.m23 + a.m23*b.m33;r.m31 = a.m31*b.m11 + a.m32*b.m21 + a.m33*b.m31;r.m32 = a.m31*b.m12 + a.m32*b.m22 + a.m33*b.m32;r.m33 = a.m31*b.m13 + a.m32*b.m23 + a.m33*b.m33;// 計(jì)算平移部分// Compute the translation portionr.tx = a.tx*b.m11 + a.ty*b.m21 + a.tz*b.m31 + b.tx;r.ty = a.tx*b.m12 + a.ty*b.m22 + a.tz*b.m32 + b.ty;r.tz = a.tx*b.m13 + a.ty*b.m23 + a.tz*b.m33 + b.tz;// 返回它。哎呀 - 會(huì)調(diào)用了構(gòu)造函數(shù)。如果速度是至關(guān)重要的,我們可能需要// 一個(gè)不同的函數(shù)在我們想要的地方放置它...// Return it. Ouch - involves a copy constructor call. If speed// is critical, we may need a seperate function which places the// result where we want it...return r; }Matrix4x3 &operator*=(Matrix4x3 &a, const Matrix4x3 &b) {a = a * b;return a; }//--------------------------------------------------------------------------- // determinant // // 計(jì)算3x3部分的矩陣行列式 // Compute the determinant of the 3x3 portion of the matrix. // // 參見(jiàn)9.1.1節(jié)獲得更多信息。 // See 9.1.1 for more info.float determinant(const Matrix4x3 &m) {returnm.m11 * (m.m22*m.m33 - m.m23*m.m32)+ m.m12 * (m.m23*m.m31 - m.m21*m.m33)+ m.m13 * (m.m21*m.m32 - m.m22*m.m31); }//--------------------------------------------------------------------------- // inverse // // 計(jì)算矩陣的逆。我們使用傳統(tǒng)的用伴隨矩陣除以行列式來(lái)的方法計(jì)算。 // Compute the inverse of a matrix. We use the classical adjoint divided // by the determinant method. // // 參見(jiàn)9.2.1來(lái)獲得更多信息。 // See 9.2.1 for more info.Matrix4x3 inverse(const Matrix4x3 &m) {// 計(jì)算行列式// Compute the determinantfloat det = determinant(m);// 如果是奇異矩陣,行列式是零,并且沒(méi)有逆矩陣// If we're singular, then the determinant is zero and there's// no inverseassert(fabs(det) > 0.000001f);// 計(jì)算一除以行列式,所以我們只需要除一次,然后乘去每一個(gè)元素。// Compute one over the determinant, so we divide once and// can *multiply* per elementfloat oneOverDet = 1.0f / det;// 計(jì)算3x3部分的逆矩陣,通過(guò)伴隨矩陣除以行列式。// Compute the 3x3 portion of the inverse, by// dividing the adjoint by the determinantMatrix4x3 r;r.m11 = (m.m22*m.m33 - m.m23*m.m32) * oneOverDet;r.m12 = (m.m13*m.m32 - m.m12*m.m33) * oneOverDet;r.m13 = (m.m12*m.m23 - m.m13*m.m22) * oneOverDet;r.m21 = (m.m23*m.m31 - m.m21*m.m33) * oneOverDet;r.m22 = (m.m11*m.m33 - m.m13*m.m31) * oneOverDet;r.m23 = (m.m13*m.m21 - m.m11*m.m23) * oneOverDet;r.m31 = (m.m21*m.m32 - m.m22*m.m31) * oneOverDet;r.m32 = (m.m12*m.m31 - m.m11*m.m32) * oneOverDet;r.m33 = (m.m11*m.m22 - m.m12*m.m21) * oneOverDet;// 計(jì)算逆矩陣的平移部分// Compute the translation portion of the inverser.tx = -(m.tx*r.m11 + m.ty*r.m21 + m.tz*r.m31);r.ty = -(m.tx*r.m12 + m.ty*r.m22 + m.tz*r.m32);r.tz = -(m.tx*r.m13 + m.ty*r.m23 + m.tz*r.m33);// 返回它。哎呀 - 會(huì)調(diào)用了構(gòu)造函數(shù)。如果速度是至關(guān)重要的,我們可能需要// 一個(gè)不同的函數(shù)在我們想要的地方放置它...// Return it. Ouch - involves a copy constructor call. If speed// is critical, we may need a seperate function which places the// result where we want it...return r; }//--------------------------------------------------------------------------- // getTranslation // // 以向量形式返回矩陣的平移部分 // Return the translation row of the matrix in vector formVector3 getTranslation(const Matrix4x3 &m) {return Vector3(m.tx, m.ty, m.tz); }//--------------------------------------------------------------------------- // getPositionFromParentToLocalMatrix // // 提取從父空間->局部空間變換矩陣的平移部分(就像世界坐標(biāo)系->物體坐標(biāo)系矩陣) // Extract the position of an object given a parent -> local transformation // matrix (such as a world -> object matrix) // // 我們假定矩陣呈現(xiàn)的是堅(jiān)固的變換。(沒(méi)有縮放、傾斜、或者鏡像) // We assume that the matrix represents a rigid transformation. (No scale, // skew, or mirroring)Vector3 getPositionFromParentToLocalMatrix(const Matrix4x3 &m) {// 通過(guò)轉(zhuǎn)置3x3部分乘以負(fù)平移值。通過(guò)矩陣的轉(zhuǎn)置,我們假定矩陣是正交的。(這個(gè)函數(shù)對(duì)于非堅(jiān)固變換的變換是沒(méi)有意義的)// Multiply negative translation value by the// transpose of the 3x3 portion. By using the transpose,// we assume that the matrix is orthogonal. (This function// doesn't really make sense for non-rigid transformations...)return Vector3(-(m.tx*m.m11 + m.ty*m.m12 + m.tz*m.m13),-(m.tx*m.m21 + m.ty*m.m22 + m.tz*m.m23),-(m.tx*m.m31 + m.ty*m.m32 + m.tz*m.m33)); }//--------------------------------------------------------------------------- // getPositionFromLocalToParentMatrix // // 提取給定局部坐標(biāo)系->父坐標(biāo)系的位置變換矩陣(例如物體坐標(biāo)系->世界坐標(biāo)系矩陣) // Extract the position of an object given a local -> parent transformation // matrix (such as an object -> world matrix)Vector3 getPositionFromLocalToParentMatrix(const Matrix4x3 &m) {// 位置簡(jiǎn)明地是平移部分// Position is simply the translation portionreturn Vector3(m.tx, m.ty, m.tz); }總結(jié)
以上是生活随笔為你收集整理的3D数学基础:Matrix4*3类代码清单的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c语言智能家居安防系统,智能家居之安防智
- 下一篇: 运维人员常用到的 11 款服务器监控工具