【问题标题】:How to scale Matrix4x4 around point?如何围绕点缩放 Matrix4x4?
【发布时间】:2021-06-23 23:59:09
【问题描述】:

我正在 Unity 中编写一个自定义编辑器窗口,我希望能够在其中滚动进/出并拖动视图。为此,我将GUI.matrix 设置为Matrix4x4.TRS(offset, Quaternion.identity, Vector3.one * scale),我可以控制offsetscale。这很好用,除非在滚动进/出时,它会锚定窗口的左上角。 我希望它锚定在鼠标的位置

如果这只需要在缩放时更改偏移量,那就太好了 - 我只是不确定这里的偏移量应该是多少。 Matrix4x4s 超出了我的数学舒适区。

这是我目前处理缩放的方式:

if (Event.current.type == EventType.ScrollWheel)
{
    _scale *= Math.Sign(Event.current.delta.y) == 1 ? 1.1f : 1f / 1.1f;
    _offset += Math.Sign(Event.current.delta.y) * /*What do I put here?*/;
}

【问题讨论】:

  • 我得到的最接近的方法是在更改比例之前和之后乘以光标的位置(使用Matrix.MultiplyPoint(v3)),然后从偏移量中减去after - before。这是显示结果的gif。注意内容是如何在光标上方稍微移动而不是无限接近它。
  • 当您尝试此操作时,您是否也更改了_offset,如问题所示,或者您是否离开了那部分?另外,v3 在世界空间吗?
  • @NicoSchertler 为了澄清我的尝试,我确实更改了偏移量。在更改比例之前和之后,我通过变换矩阵运行鼠标的位置。然后我从 _offset 中减去结果之间的差异。这就是给了我最接近的选项,如 gif 所示。在这种情况下,v3 是鼠标的位置(相对于窗口)。
  • 我认为我遇到的很多麻烦都源于我所拥有的值与屏幕相关、相对于矩形(窗口)、包含 _scale 和包含 _offset 的混淆.发生的事情太多了,有点不知所措。

标签: c# unity3d math unity-editor unity-ui


【解决方案1】:

让我们尝试了解 GUI 矩阵的作用。它表示一个转换,它在世界空间(您的 GUI 对象所在的位置)中获取坐标并将它们转换为 GUI 空间(或多或少与您的窗口对齐)。由于我们没有旋转,我们可以很容易地解释用TRS() 构造矩阵对世界空间点pWorld 的作用:

pGUI = scale * pWorld + offset

现在您想将scale 更改为scaleNew。这样做时,您希望在鼠标下保持相同的世界位置。

如果你的鼠标位置是在 GUI 空间中给出的(例如,来自Event.current.mousePosition),那么我们首先需要找到对应的世界空间点:

v3World = (1.0 / scaleOld) * (v3GUI - offsetOld)

我们想在鼠标下固定这个点,即:

v3GUI = scaleNew * v3World + offsetNew
v3GUI = scaleNew / scaleOld * (v3GUI - offsetOld) + offsetNew 

我们可以解决这个问题来获得新的偏移量:

v3GUI = scaleNew / scaleOld * v3GUI - scaleNew / scaleOld * offsetOld + offsetNew
(1 - scaleNew / scaleOld) * v3GUI + scaleNew / scaleOld * offsetOld = offsetNew

就是这样。

顺便说一句,您也可以单独使用矩阵运算来做到这一点。这就是GUIUtility.ScaleAroundPivot() 所做的。看起来是这样的:

newMatrix = T(v3GUI) * S(newScale / oldScale) * T(-v3GUI) * oldMatrix

T 表示平移,S 表示缩放。平移对T(v3GUI)T(-v3GUI) 将坐标系的临时原点移动到您的鼠标位置并从那里执行缩放。然后,您可以直接从此矩阵中读取偏移量和比例。

【讨论】:

  • 即使我目前无法测试,也会标记为已接受。我继续编写 ScreenToWorld 和 WorldToScreen 实用程序函数。从那里,我在另一条评论中采用了计算屏幕点的方法,即在更改缩放前后计算屏幕点。通过消除差异,屏幕点在缩放时有效地保持静止。以下是相关代码:hatebin.com/ivvyenykpq
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多