将四元数拆分为轴旋转
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将四元数拆分为轴旋转相关的知识,希望对你有一定的参考价值。
我有一个四元数代表一个对象的方向(黄色框和球体)。我想知道是否可以将该四元数分割成其他四元数,使我们能够旋转每个局部轴(X,Y和Z)。
到目前为止我一直在做的是获取Euler表示并使用它,但它不是我特定情况的正确解决方案:
给定两个点(蓝色方框),我想限制我的对象的方向,使它无法指出灰色平面,即使我的四元数看出那个平面。 我想拆分(分解)四元数,因为当我的对象达到平面的极限(例如,右边)时,我想让它停留在那里(在那个组件中),然后在垂直组件中旋转我的对象,使用一个新的分裂四元数。
我正在与Unity合作。
我希望我的问题是可以理解的:)
答案
这是一种获得y轴局部旋转的方法。可以修改此函数以获取x或z轴。
/// <summary> isolate the y-Component of a rotation </summary>
private Quaternion yRotation(Quaternion q)
{
float theta = Mathf.Atan2(q.y, q.w);
// quaternion representing rotation about the y axis
return new Quaternion(0, Mathf.Sin(theta), 0, Mathf.Cos(theta));
}
您可以通过转换为Euler来验证Unity检查器中的结果:
public float yLocal;
void Update()
{
yLocal = yRotation(this.transform.rotation).eulerAngles.y;
}
另一答案
如果对象在IMU数据中作为四元数读取,那么我以前和我一起使用过IMU,并且我不会遇到gimbo锁定问题。因此,您确实可以创建对象旋转的引用并将其转换为euler天使,然后在将其应用于对象之前转换回Quaternions。
但是,如果你只是想限制旋转,我会做这样的事情:
//the last rotation was pointed at the grey zone.
private Quaternion prevAllowedRotation;
void FixedUpdate(){
if(!isValidRotation()){
this.transform.rotation = prevAllowedRotation;
}else{
this.transform.lookAt(lockToArea());
}
}
private bool isValidRotation(){
//I chose forward based on the image, find the direction that works for you
Ray ray = new Ray(this.transform.position, this.transform.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 10f){
if(hit.transform.tag == "wall"){
return true;
}
}
return false;
}
private Vector3 lockToArea(Gameobject grey){
Vector3 center = grey.transform.position;
//figure out how to get the position of the facing direction on the same plane as the grey area.
Vector3 pointerPosition = getPointerPosition();
RaycastHit hit;
if(Physics.Linecast(pointerPosition, center, hit)){
return hit.point;
}
return Vector3.zero;
}
private Vector3 getPointerOnPlane(){
Ray ray = new Ray(this.transform.position, this.transform.forward);
// you need to figure out how to dyanmically get the distance so that the ray lands on the same plane as the vector
float distance = 0;
return ray.GetPoint(distance);
}
这将其旋转锁定为仅指向灰色立方体。这应该对你有很大的帮助,你只需要得到IMU数据读入的点,并且与灰色立方体的中心位于同一平面上。
以上是关于将四元数拆分为轴旋转的主要内容,如果未能解决你的问题,请参考以下文章