【问题标题】:How to find the transformation matrix for given scale, skew, and translation values?如何找到给定比例、偏斜和平移值的变换矩阵?
【发布时间】:2015-01-21 02:06:12
【问题描述】:

变换矩阵是如何定义的?

我有定义比例、倾斜和平移的值。我想找到它们所代表的变换矩阵。

  • x/y 比例可以是任意数字。
  • 翻译 x/y 可以是任何数字。
  • 倾斜 x/y 的度数在 -180 到 180 之间。

如何找到这些值的转换矩阵?

我正在处理来自 Flash 的值,并且希望矩阵的格式是这样的,以便我可以导出这个矩阵并在另一种语言中应用相同的转换:

| a c u |
| b d v |
| 0 0 1 |

我需要能够从参数转到 AS3/JSFL/Flash 之外的矩阵。

(具体来说,我想使用 C#,但我想要一个不依赖于给定语言的答案。)

此链接讨论了矩阵在 Flash 中的工作原理,我了解其中的大部分内容。但是据我所知,它没有描述如何从位置/比例/倾斜值到矩阵。 http://www.senocular.com/flash/tutorials/transformmatrix/

我知道 Flash 显示对象有一个 .matrix 属性,但我正在使用 Flash 之外的给定值,需要找到不使用它的解决方案。

Actionscript 的偏差行为不端

鉴于 Cimbali 的答案中通常的转换定义,我仍然无法从它的 skew 参数构建矩阵。

这是一组数据示例:

A) 对象属性(直接从Flash using JSFLelement.xelement.skewX 等记录...)

x: 0
y: 0
scaleX: 1
scaleY: 1.0000152587890625
skewX: 19.9998779296875
skewY: 0

B) 变换矩阵(使用 JSFL 直接从 Flash 记录,element.matrix

1      | 0      | 0     
-0.342 | 0.94   | 0     
0      | 0      | 1     

这是我尝试过的:

sx = tan(19.9998779296875 * PI / 180) = tan(0.34906372) = 0.36396782164

Scale Matrix        Skew X Matrix       Result Matrix
1 | 0 | 0           1    | 0 | 0        1    | 0 | 0
0 | 1 | 0      x    0.36 | 1 | 0    =   0.36 | 1 | 0
0 | 0 | 1           0    | 0 | 0        0    | 0 | 1

SkewY 为 0,因此没有理由使用 Skew Y 矩阵再次相乘。

那么为什么我的结果矩阵与 Flash 发布的矩阵有很大不同?

在此示例中,我的图形最初为 200 x 100 像素。它不会从任何父级继承转换(父级肯定不会以任何方式进行转换)。但是,当我将图形放在舞台上并且仅将倾斜 X 值更改为 20° 时,属性面板中的高度从 100 变为 94px,但缩放 Y 保持在 100%。

如果您不熟悉 Flash IDE,当您仅调整倾斜 X 值时,它不会简单地向左/向右推动图形的角。它实际上使角沿弧线移动,随着倾斜 X 的增加,平行四边形在垂直方向上变短。

(我意识到我已经四舍五入了一些数字,但这只是为了便于在此处显示它们。)

【问题讨论】:

  • 考虑到输入偏斜,您计算的矩阵是正确的,尽管它们似乎采用相反的角度 (tan(-19.99...))。 JSFL 吐出的矩阵似乎不正确,或者至少似乎是您的矩阵与将 Y 轴缩放 0.94 的矩阵的“连接”(0.36396782164 * 0.94 = 0.3421*0.94 = 0.94)。是否有容器、父元素或任何可以解释这种补充缩放的东西?其他例子也一样吗?
  • 有趣。是的,我的图形最初是 200 x 100 像素。它确实有一个父母,但父母绝对没有以任何方式转变。但是,当我将图形放在舞台上并且仅将倾斜 X 值更改为 20° 时,属性面板中的高度从 100 更改为 94 像素,但 Y 比例保持在 100%。呃。
  • 如果您不熟悉 Flash IDE,当您仅调整倾斜 X 值时,它不会简单地向左/向右推动图形的角。它实际上使角沿弧线移动,随着倾斜 X 的增加,平行四边形在垂直方向上变短。
  • 我应该澄清一下,这些 cmets 中讨论的值来自 IDE 面板,而我的帖子中的值来自图形的 JSFL 代码日志记录属性。
  • Dustin :好的,这很有趣,而且不完全是歪曲。我们确实有cos(0.34906372) = 0.9396,所以它似乎很合适。我会更新我的答案。

标签: actionscript-3 flash math matrix


【解决方案1】:

由于某种奇怪的原因,应用连续变换在 actionscript 3 中被称为“连接矩阵”,正如您的链接所解释的那样,它是通过将矩阵相乘来完成的:完全阅读“矩阵乘法”部分:它首先定义矩阵乘法和以A*B -> B.concat(A); 结尾。

请注意,应用转换的顺序很重要:B*A 不是 A*B。在A*BB.concat(A); 中,BA 之前应用。由于矩阵乘积的关联性,您可以将其视为A*(B*(x,y,1))。这也在链接的“连接矩阵”部分中进行了解释,其中子元素先由其矩阵转换,然后再由其父矩阵转换,这与child_matrix.concat(parent_matrix);的单个转换相同。

然而,难题的缺失部分在于,对于您描述的每个操作,都有一个相应的转换矩阵。他们都是illustrated and explained in adobe's reference on Matrices。不过偏斜矩阵的图示有一个小错误,请参考to this stackoverflow question instead

这是来自the wikipedia page on the topic的插图,同样清晰:

请注意,所有反射都可以通过使用具有 -1 值的 W 和/或 H 进行缩放来表示。对于以角度表示的剪切,只需在上图中使用A = tan(a)


然而,flash 似乎不同意“倾斜”的含义,而不是在倾斜另一个坐标时保留一个坐标,而是保留 最初沿该坐标的长度。或者,正如您所描述的,如果您沿 X 倾斜一个矩形,它的(某些)顶点不会向左或向右推,而是在弧上移动。

看起来,他们歪斜了一个坐标,然后通过缩放另一个坐标来纠正图形的伸长率。幸运的是,发生这种情况的因素很容易预测,因为我们知道三角学:它是角度的余弦。

因此,每当您在 flash 中以 a 的角度倾斜 X 时,您必须使用以下矩阵乘积(使用上图中的定义表示):matrix(scale with W=1 and H=cos(a)) * matrix(skew along x with A=-tan(a))

在闪存中定义一个 skewY 会产生合理的编程语言 matrix(scale with W=cos(a) and H=1) * matrix(skew along y with B=-tan(a))

是合乎逻辑的

【讨论】:

  • 首先,感谢您的帮助!我知道 A * B 不等于 B * A,但是我怎么知道我应该执行 scaleMatrix * skewXMatrix * skewYMatrix 还是其他顺序?
  • 所以“正确”的方式应该是产生与 Flash 吐出的相同矩阵的任何方式,对吧?我猜我还没有完全掌握计算。我用一些示例值更新了原始帖子,并尝试遵循您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
相关资源
最近更新 更多