1.6.8矢量函數


DirectX Math提供以下功能來執行各種矢量操作。 我們用3D版本來說明,但是2D和4D有類似的版本; 2D和4D版本與3D版本具有相同的名稱,除了2和4分別替代3。

XMVECTOR XM_CALLCONV XMVector3Length( // Returns||v||
FXMVECTOR V); // Input v
XMVECTOR XM_CALLCONV XMVector3LengthSq( // Returns||v||2
FXMVECTOR V); // Input v
XMVECTOR XM_CALLCONV XMVector3Dot( // Returns v1·v2
FXMVECTOR V1, // Input v1
FXMVECTOR V2); // Input v2
XMVECTOR XM_CALLCONV XMVector3Cross( // Returns v1 ×v2
FXMVECTOR V1, // Input v1
FXMVECTOR V2); // Input v2
XMVECTOR XM_CALLCONV XMVector3Normalize( // Returns v/||v||
FXMVECTOR V); // Input v
XMVECTOR XM_CALLCONV XMVector3Orthogonal( // Returns a vector orthogonal to v
FXMVECTOR V); // Input v
XMVECTOR XM_CALLCONV XMVector3AngleBetweenVectors( // Returns the angle between v1 and v2
FXMVECTOR V1, // Input v1
FXMVECTOR V2); // Input v2
void XM_CALLCONV XMVector3ComponentsFromNormal(XMVECTOR* pParallel, // Returns projn(v)
XMVECTOR* pPerpendicular, // Returns perpn(v)
FXMVECTOR V, // Input v
FXMVECTOR Normal); // Input n
bool XM_CALLCONV XMVector3Equal( // Returns v1 = v2
FXMVECTOR V1, // Input v1
FXMVECTOR V2); // Input v2
bool XM_CALLCONV XMVector3NotEqual( // Returns v1 ≠ v2
FXMVECTOR V1, // Input v1

FXMVECTOR V2); // Input v2


請注意,即使對數學運算返回標量的操作(例如點積k = v1·v2),這些函數也會返回XMVECTOR。 標量結果被複制到XMVECTOR的每個組件中。 例如,對於點積,返回的矢量將是(v1·v2,v1·v2,v1·v2,v1·v2)。 其中一個原因是最小化標量和SIMD向量操作的混合;在您完成計算之前,保持SIMD的一切都更爲有效。

下面的演示程序演示瞭如何使用大多數這些函數以及一些重載操作符:



#include <windows.h> // for XMVerifyCPUSupport
#include <DirectXMath.h>
#include <DirectXPackedVector.h>
#include <iostream>
using namespace std;
using namespace DirectX;
using namespace DirectX::PackedVector;


// Overload the  "<<" operators so that we can use cout to 
// output XMVECTOR objects.
ostream& XM_CALLCONV operator << (ostream& os, FXMVECTOR v)
{
    XMFLOAT3 dest;
    XMStoreFloat3(&dest, v);


    os << "(" << dest.x << ", " << dest.y << ", " << dest.z << ")";
    return os;
}


int main()
{
    cout.setf(ios_base::boolalpha);


    // Check support for SSE2 (Pentium4, AMD K8, and above).
    if (!XMVerifyCPUSupport())
    {
        cout << "directx math not supported" << endl;
        return 0;
    }


    XMVECTOR n = XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f);
    XMVECTOR u = XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
    XMVECTOR v = XMVectorSet(-2.0f, 1.0f, -3.0f, 0.0f);
    XMVECTOR w = XMVectorSet(0.707f, 0.707f, 0.0f, 0.0f);


    // Vector addition: XMVECTOR operator + 
    XMVECTOR a = u + v;


    // Vector subtraction: XMVECTOR operator - 
    XMVECTOR b = u - v;


    // Scalar multiplication: XMVECTOR operator * 
    XMVECTOR c = 10.0f*u;


    // ||u||
    XMVECTOR L = XMVector3Length(u);


    // d = u / ||u||
    XMVECTOR d = XMVector3Normalize(u);


    // s = u dot v
    XMVECTOR s = XMVector3Dot(u, v);


    // e = u x v
    XMVECTOR e = XMVector3Cross(u, v);


    // Find proj_n(w) and perp_n(w)
    XMVECTOR projW;
    XMVECTOR perpW;
    XMVector3ComponentsFromNormal(&projW, &perpW, w, n);


    // Does projW + perpW == w?
    bool equal = XMVector3Equal(projW + perpW, w) != 0;
    bool notEqual = XMVector3NotEqual(projW + perpW, w) != 0;


    // The angle between projW and perpW should be 90 degrees.
    XMVECTOR angleVec = XMVector3AngleBetweenVectors(projW, perpW);
    float angleRadians = XMVectorGetX(angleVec);
    float angleDegrees = XMConvertToDegrees(angleRadians);


    cout << "u                   = " << u << endl;
    cout << "v                   = " << v << endl;
    cout << "w                   = " << w << endl;
    cout << "n                   = " << n << endl;
    cout << "a = u + v           = " << a << endl;
    cout << "b = u - v           = " << b << endl;
    cout << "c = 10 * u          = " << c << endl;
    cout << "d = u / ||u||       = " << d << endl;
    cout << "e = u x v           = " << e << endl;
    cout << "L  = ||u||          = " << L << endl;
    cout << "s = u.v             = " << s << endl;
    cout << "projW               = " << projW << endl;
    cout << "perpW               = " << perpW << endl;
    cout << "projW + perpW == w  = " << equal << endl;
    cout << "projW + perpW != w  = " << notEqual << endl;
    cout << "angle               = " << angleDegrees << endl;


    return 0;

}



DirectX Math庫還包含一些估算方法,這些方法精確度較低但計算速度較快。 如果你願意犧牲一些速度的準確性,那麼就使用估計方法。 以下是兩個估算函數的例子:

XMVECTOR XM_CALLCONV XMVector3LengthEst( // Returnsestimated ||v||
FXMVECTOR V); // Input v
XMVECTOR XM_CALLCONV XMVector3NormalizeEst( //Returns estimated v/||v||
FXMVECTOR V); // Input v

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章