Godot/Gdscript 旋转 + 从本地空间到世界空间的转换

问题描述

enter image description here

我有一个刚体节点(3D),我想在全局坐标中获得“目标”的位置,给定:

  • 角度“旋转”(向上是 Y)
  • 一个向量 = 5 * Vector.FORWARD

看起来很简单....先平移,然后旋转,或者如果它不起作用,先旋转,然后旋转。

A 到 B -> 如果我只应用翻译,它可以工作,没问题:

target = global_transform.translated(5 * Vector3.FORWARD).origin

但是如果我想要 B 到 C,它会失败:它看起来像围绕世界原点旋转

在过去的几个小时里,我尝试了很多东西,并阅读了很多关于 Transform 的文章,现在,我要放弃了。那么...你会怎么做?

enter image description here

解决方法

又过了 1 小时,我终于找到了一些东西,但是有点难看:

target = to_global(to_local(transform.translated(3 * Vector3.FORWARD).origin).rotated(Vector3.UP,rot))

如果您有更好的答案,请添加您的答案!

,

我们将在 XZ 平面上通过极坐标(即“旋转”角度和距离,我称之为“d”)定义相对于您的刚体(3D)的位置。

明确地说,我们将在 RigidBody(3D) 的局部空间中定义它,然后将其移动到全局坐标。

我们可以使用转换。如果您需要保留旋转,您会怎么做。虽然它需要更多的工作。或者,您可以仅使用向量。哪个更容易。

以下是执行此操作的不同方法。


使用变换

局部变换

我们像这样定义组合旋转和平移变换:

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)

顺便说一下,使用这些方法时顺序无关紧要。结果是这样的:

var t = Transform.IDENTITY.rotated(Vector3.UP,rot) * Transform.IDENTITY.translated(d * Vector3.FORWARD)

它以给定的距离围绕原点旋转。但是,如果您这样做:

var t = Transform.IDENTITY.translated(d * Vector3.FORWARD) * Transform.IDENTITY.rotated(Vector3.UP,rot)

你得到一个向前位移的变换,然后在位置上旋转。


全局变换

对于全局变换,我们可以利用它应该相对于 RidigBody(3D) 的事实,并且我们有它的全局变换:

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t

请注意,这将应用旋转、缩放等。如果你只想要全局翻译,你可以这样做:

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var global_t = Transform.IDENTITY.translated(global_transform.origin) * t

不,t.translated(global_transform.origin) 不是一回事。当您使用 translated 时,它位于您调用它的变换的本地坐标中。


本地位置

如您所知,我们可以使用转换的 origin

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var v = t.origin

全球定位

您可以使用to_global

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = to_global(v)

或者我们可以从全局变换中取出 origin

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var global_t = global_transform * t
var global_v = global_t.origin

如果你只想要全局翻译,你可以添加global_transform.origin

var t = Transform.IDENTITY.rotated(Vector3.UP,rot).translated(d * Vector3.FORWARD)
var v = t.origin
var global_v = global_transform.origin + v

仅使用矢量

本地位置

如果你只关心位置,我们可以完全不用转换:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP,rot)

全球定位

当然,您可以使用 to_global

var v = (d * Vector3.FORWARD).rotated(Vector3.UP,rot)
var global_v = to_global(v)

再说一次,如果你只想要全局翻译,你可以添加 global_transform.origin:

var v = (d * Vector3.FORWARD).rotated(Vector3.UP,rot)
var global_v = global_transform.origing + v