首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从四元数中获取类似指南针的行为

从四元数中获取类似指南针的行为
EN

Stack Overflow用户
提问于 2017-07-25 00:50:39
回答 2查看 1K关注 0票数 1

假设你有一个相机投影矩阵,即相机平移矢量+旋转四元数,就像每一个典型的相机一样,它能够在任意方向移动和旋转。不管它是向前的,向上的还是向下的,它的旋转都是独立的,我需要显示一个指南针一样的量规指向相机瞄准的地方。

问题是,当摄像机向下指向时,摄像机围绕其光学中心的旋转决定了指南针的值,但当摄像机指向前方时,摄像机围绕其中心的旋转不再影响罗盘的值,在这种情况下,摄像机的方向决定了指南针的值。

当相机只向下倾斜45度时,它会变得更加丑陋,在这种情况下,甚至不清楚围绕摄像机中心的旋转是否会影响罗盘的旋转。

那么,是否有一种基于任意摄像机投影矩阵/四元数计算罗盘值的优雅方法?

提前谢谢你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-25 14:17:13

如果您只想要一个指向目标的箭头,那么它:

代码语言:javascript
复制
Transform camera = Camera.main.transform;
Transform target = Target.transform;
Vector3 relativePosition = target.position - camera.position;

Vector3 targetRelative = Vector3.ProjectOnPlane(relativePosition, camera.forward);

float angle = Angle360(camera.up, targetRelative, camera.forward);  

Compass.transform.rotation = Quaternion.Euler(0, 0, angle);

角度函数是:

代码语言:javascript
复制
float Angle360(Vector3 from, Vector3 to, Vector3 normal)
{
    float dot = Vector3.Dot(from, to);
    float det = Vector3.Dot(normal, Vector3.Cross(from, to));
    return Mathf.Atan2(det, dot)*Mathf.Rad2Deg;
}

以下是在worldspace中获取指南针方向的方法:

在XZ平面上投影摄像机方向和目标位置

代码语言:javascript
复制
Transform camera = Camera.main.transform;
Transform target = Target.transform;

Vector3 cameraWorldDirXZ = Vector3.ProjectOnPlane(camera.forward, Vector3.up).normalized;
Vector3 targetWorldDirXZ = Vector3.ProjectOnPlane(target.position, Vector3.up).normalized; 

cameraWorldDirXZtargetWorldDirXZ之间的角度是指南针的角度。

但我不认为这会像你想的那样。这给了你一个角度,你需要旋转camera.forward矢量围绕y轴面对目标。如果你围绕camera.forward旋转,你不会改变camera.forward矢量或y轴,所以指南针不会改变。

你可能想在本地空间试试指南针。为此,您将投影到照相机XZ平面上:

代码语言:javascript
复制
Vector3 cameraLocalDirXZ = camera.forward;
Vector3 targetLocalDirXZ = Vector3.ProjectOnPlane(target.position, camera.up).normalized; 

同样,cameraLocalDirXZtargetLocalDirXZ之间的角度就是指南针的角度。这就给出了你需要围绕camera.forward旋转camera.up来面对目标的角度。注意,当你围绕camera.forward旋转时,它会改变camera.up,所以它会改变指南针的方向。

票数 3
EN

Stack Overflow用户

发布于 2017-07-29 00:05:05

如果有人偶然发现这个问题,解决方案(感谢@Pluto)非常简单,将你的相机四元数乘以三个轴矢量(0,1,1),(0,1,0),(1,0,0),你会得到三个矢量定义你的相机的坐标系,将这三个矢量投影到你的平面上,找到你三个投影点的质心,看看你有指南针的方向。

下面是这方面的代码:

代码语言:javascript
复制
var rotation = /* Your quaternion */;

var cameraOrtX = rotation * new Vector3 (1, 0, 0);
var cameraOrtY = rotation * new Vector3 (0, 1, 0);
var cameraOrtZ = rotation * new Vector3 (0, 0, 1);

var cameraOrtPX = Vector3.ProjectOnPlane(cameraOrtX, new Vector3(0, 1, 0));
var cameraOrtPY = Vector3.ProjectOnPlane(cameraOrtY, new Vector3(0, 1, 0));
var cameraOrtPZ = Vector3.ProjectOnPlane(cameraOrtZ, new Vector3(0, 1, 0));

var centroid = (cameraOrtPX + cameraOrtPY + cameraOrtPZ) / 3.0f;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45292175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档