Math 如何创建从头部到尾部的旋转? 我正在做一个C++物理模拟(弹簧物理学)。我成功地实现了基本的绳索运动,它由几个“骨骼”(只是一些带有位置、重量等的粒子[质量])组成。当计算每个粒子的位置时,我将它们分别指定给蒙皮网格的对应骨骼。 我想要的是计算粒子的旋转,以便将其旋转为子粒子(圆是骨骼的头部[粒子的位置],黑点是尾巴,应该连接到子粒子的头部,依此类推): 我查找了一些线程,得出了以下结论:并尝试实现我的项目的公认答案,因此我得到了以下结论: XMVECTOR q; XMVECTOR a = XMVector3Cross(head,tail); XMVECTOR lh=XMVector3Length(head),lt=XMVector3Length(tail),dot=XMVector3Dot(head,tail); q.m128_f32[0] = a.m128_f32[0]; //assigning the x coordinate q.m128_f32[1] = a.m128_f32[1]; //assigning the y coordinate q.m128_f32[2] = a.m128_f32[2]; //assigning the z coordinate q.m128_f32[3] = sqrt(pow(lh.m128_f32[0],2)*pow(lt.m128_f32[0],2)) + dot.m128_f32[0]; //assigning the w coordinate return XMQuaternionNormalize(q);

Math 如何创建从头部到尾部的旋转? 我正在做一个C++物理模拟(弹簧物理学)。我成功地实现了基本的绳索运动,它由几个“骨骼”(只是一些带有位置、重量等的粒子[质量])组成。当计算每个粒子的位置时,我将它们分别指定给蒙皮网格的对应骨骼。 我想要的是计算粒子的旋转,以便将其旋转为子粒子(圆是骨骼的头部[粒子的位置],黑点是尾巴,应该连接到子粒子的头部,依此类推): 我查找了一些线程,得出了以下结论:并尝试实现我的项目的公认答案,因此我得到了以下结论: XMVECTOR q; XMVECTOR a = XMVector3Cross(head,tail); XMVECTOR lh=XMVector3Length(head),lt=XMVector3Length(tail),dot=XMVector3Dot(head,tail); q.m128_f32[0] = a.m128_f32[0]; //assigning the x coordinate q.m128_f32[1] = a.m128_f32[1]; //assigning the y coordinate q.m128_f32[2] = a.m128_f32[2]; //assigning the z coordinate q.m128_f32[3] = sqrt(pow(lh.m128_f32[0],2)*pow(lt.m128_f32[0],2)) + dot.m128_f32[0]; //assigning the w coordinate return XMQuaternionNormalize(q);,math,linear-algebra,directx-11,Math,Linear Algebra,Directx 11,不幸的是,由于某些原因,它对我不起作用,因此尝试了另一种方法,但也失败了: XMVECTOR Head = XMVector3Normalize( head ); XMVECTOR Tail = XMVector3Normalize( tail ); float angle = acos(XMVector3Dot(Head,Tail).m128_f32[0]); //acos(dot(Head,Tail)) XMVECTOR axis = XMVector3Normalize(XMVector

不幸的是,由于某些原因,它对我不起作用,因此尝试了另一种方法,但也失败了:

XMVECTOR Head = XMVector3Normalize( head );
XMVECTOR Tail = XMVector3Normalize( tail );

float angle = acos(XMVector3Dot(Head,Tail).m128_f32[0]); //acos(dot(Head,Tail))
XMVECTOR axis = XMVector3Normalize(XMVector3Cross(Head,Tail));

XMVECTOR q = XMQuaternionRotationAxis(axis,angle);

如果有人能给我发一个替代方案,我将不胜感激,并为拙劣的绘画技巧感到抱歉。

不要直接使用XMVECTOR的成员。。。XMStore/XMLoad函数就是出于这个原因而存在的。底部解决方案应如下所示:

XMVECTOR Head = XMVectorNormalize(head);
XMVECTOR Tail = XMVectorNormalize(tail);

float angle = 0.0f;
XMStoreFloat(&angle,XMVector3AngleBetweenVectors(Head,Tail));
XMVECTOR axis = XMVectorCross(Head,Tail);

return XMQuaternionAxisAngle(axis,angle);
这样可以避免直接访问XMVECTOR,这可能有助于解决问题

您拥有的第一个解决方案也应该可以工作,但同样,应该使用XMStore/XMLoad函数,而不是直接访问

XMFLOAT3 a;
XMStoreFloat3(&a,XMVector3Cross(head,tail));
float lh2, lt2, dot;
XMStoreFloat(&lh2,XMVector3Dot(head,head)); //this calculates the length squared.
XMStoreFloat(&lt2,XMVector3Dot(tail,tail)); //same as above
XMStoreFloat(&dot,XMVector3Dot(head,tail));

XMFLOAT4 q;
q.x = a.x; //assigning the x coordinate
q.y = a.y; //assigning the y coordinate
q.z = a.z; //assigning the z coordinate
q.w = sqrt(lh2*lt2) + dot; //assigning the w coordinate
return XMQuaternionNormalize(XMLoadFloat4(&q));
更新:

如果仔细使用上述解决方案,它们会起作用,但通常情况下,它们会产生以原点为中心的结果。这是因为参考文献的变化。要生成所需的行为,需要执行以下操作(假设点由结构/类点表示):

这将把层次中每个先前骨骼的运动组合在一起,形成传递给函数的点的最终变换矩阵


上述解决方案适用于小型模型(感谢您的回答,我尝试过了,但输出仍然不正确(实际上与以前一样),骨骼看起来只是随机旋转,但很高兴知道问题出在其他地方。如果我直接访问XMVECTOR,我也不明白会发生什么问题。:)知道XMFLOAT4结构的结构后,XMVECTOR成员的内容并不像人们所期望的那样排列。此外,XMVECTOR实现的细节可能会随着版本和平台的不同而变化。最后,直接访问通常会导致性能下降。有关这方面的更多详细信息,请参见。我只需要设置两点之间的旋转,而不必关注其父点,因为在模拟完成后,我拥有每个骨骼/粒子/质量的绝对世界坐标。更不用说,即使是第一块骨骼也会发生不正确的旋转(当它空闲时会绕X轴旋转,奇怪的是,每一块骨骼都是如此)。我想问题还在其他地方。所以,如果我理解正确的话,你想要一个旋转,从粒子方向的当前正向向量映射到由粒子与其下一行子粒子之间的位置差给出的新向量?是的,没错。我不完全理解前面提到的两个旋转公式,我认为应该是这样的:如果(head.x=tail.x和head.z=tail.z和head.y>=tail.y),那么{旋转的恒等四元数},否则{有旋转}。
XMMATRIX CalculateTransform(Point p)
{
    XMVECTOR pos=XMLoadFloat3(&p.GetPosition());
    //Get your new rotation quaternion using the methods above
    XMMATRIX r=XMMatrixRotationQuaternion(CalculateRotation(p.GetHead(),p.GetTail()));
    XMMATRIX t=XMMatrixTranslationFromVector(pos);
    if(p.HasParent())
        return CalculateTransform(p.GetParent())*r*t;
    else
        return r*t;
}