我有 3 个向量,xyz,我只想更改 1 个向量,然后根据它们之前的方向(最接近它们的方向)计算其他 2 个向量。我想在内存使用/游戏设计方面以最有效的方式做到这一点。
编辑(在 Stef 提出一些建设性意见后):
我们拥有:
我们需要什么(我相信):
我尝试过的:
我的愿望:
Quaternion Quaternion ( Vector3 arc_from, Vector3 arc_to ) Constructs a quaternion representing the shortest arc between two points on the surface of a sphere with a radius of 1.0.
如果我理解正确,您需要一个四元数来表示将一个向量转换为另一个向量所需的最短旋转,因此您可以将其应用为您的自定义基础。
我们可以从计算此旋转变换的旋转轴开始......
我将编写 GDScript。我假设向量非零且有限。
var axis := arc_from.cross(arc_to)
除非当矢量方向相同或相反时,这不起作用。所以,让我们考虑一下......
var axis := arc_from.cross(arc_to)
if axis.is_zero_approx():
var longest_axis := arc_to.max_axis_index()
var with := Vector3.ONE
with[longest_axis] = 0.0
axis = arc_to.cross(with)
在这里,我创建了一个新的
Vector3
,它将是 0.0
位于轴上,arc_to
具有最长的幅度,1.0
位于其他轴上。所以保证它不在同一方向,然后我用它与 arc_to
进行叉积,这应该给出一个垂直于 arc_to
的向量。
当然,我们应该标准化轴以确保它的长度
1.0
:
var axis := arc_from.cross(arc_to)
if axis.is_zero_approx():
var longest_axis := arc_to.max_axis_index()
var with := Vector3.ONE
with[longest_axis] = 0.0
axis = arc_to.cross(with)
axis = axis.normalized()
现在我们可以算出旋转的角度了:
var axis := arc_from.cross(arc_to)
if axis.is_zero_approx():
var longest_axis := arc_to.max_axis_index()
var with := Vector3.ONE
with[longest_axis] = 0.0
axis = arc_to.cross(with)
axis = axis.normalized()
var angle := arc_from.signed_angle_to(arc_to, axis)
并为其创建一个四元数:
var axis := arc_from.cross(arc_to)
if axis.is_zero_approx():
var longest_axis := arc_to.max_axis_index()
var with := Vector3.ONE
with[longest_axis] = 0.0
axis = arc_to.cross(with)
axis = axis.normalized()
var angle := arc_from.signed_angle_to(arc_to, axis)
return Quaternion(axis, angle)
我相信这足以满足您的需求。