Godot/Gdscript 旋转 + 从本地翻译到世界 space
Godot/Gdscript rotate + translate from local to world space
我有一个 RigidBody 节点 (3D),我想得到,在全局坐标 中,“目标”的位置,给定:
- 角度“旋转”(向上是 Y)
- 一个向量 = 5 * Vector.FORWARD
看起来很简单....先平移,再旋转,或者如果不行,先旋转,再旋转。
A 到 B -> 如果我只应用翻译,它可以工作,没问题:
target = global_transform.translated(5 * Vector3.FORWARD).origin
但是如果我想从 B 到 C,它会失败:它看起来像围绕世界原点旋转
在过去的几个小时里我尝试了很多东西并阅读了很多关于 Transform 的文章,现在我放弃了。那么...你会怎么做?
又过了1个小时,我终于找到了东西,但是有点难看:
target = to_global(to_local(transform.translated(3 * Vector3.FORWARD).origin).rotated(Vector3.UP, rot))
如果你有更好的,请添加你的答案!
我们将在 XZ 平面上通过极坐标(即“旋转”角度和距离,我称之为“d”)定义相对于您的 RigidBody(3D) 的位置。
为了清楚起见,我们将在RigidBody(3D)的局部space定义它,然后将它移动到全局坐标。
我们可以使用转换。如果您需要保持旋转,您会这样做。虽然它需要更多的工作。或者,您可以 仅使用向量 。哪个更容易。
以下是执行此操作的不同方法。
使用变换
局部变换
我们这样定义旋转和平移变换:
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
我有一个 RigidBody 节点 (3D),我想得到,在全局坐标 中,“目标”的位置,给定:
- 角度“旋转”(向上是 Y)
- 一个向量 = 5 * Vector.FORWARD
看起来很简单....先平移,再旋转,或者如果不行,先旋转,再旋转。
A 到 B -> 如果我只应用翻译,它可以工作,没问题:
target = global_transform.translated(5 * Vector3.FORWARD).origin
但是如果我想从 B 到 C,它会失败:它看起来像围绕世界原点旋转
在过去的几个小时里我尝试了很多东西并阅读了很多关于 Transform 的文章,现在我放弃了。那么...你会怎么做?
又过了1个小时,我终于找到了东西,但是有点难看:
target = to_global(to_local(transform.translated(3 * Vector3.FORWARD).origin).rotated(Vector3.UP, rot))
如果你有更好的,请添加你的答案!
我们将在 XZ 平面上通过极坐标(即“旋转”角度和距离,我称之为“d”)定义相对于您的 RigidBody(3D) 的位置。
为了清楚起见,我们将在RigidBody(3D)的局部space定义它,然后将它移动到全局坐标。
我们可以使用转换。如果您需要保持旋转,您会这样做。虽然它需要更多的工作。或者,您可以 仅使用向量 。哪个更容易。
以下是执行此操作的不同方法。
使用变换
局部变换
我们这样定义旋转和平移变换:
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