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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值