关于任意点的旋转矩阵

7

默认情况下,旋转矩阵以原点作为旋转中心。如果要围绕任意点进行旋转,则必须使用平移矩阵减去到原点的距离进行旋转,然后再进行平移。但是这对我来说似乎并不奏效。假设我的对象大小为100x100,中心点位于50,50,以下是我的代码:

t = IDENTITY;
t = translate(t, -50, -50);
t = rotate(t, theta);
t = translate(t, 50, 50);

很不幸,如果我将这个变换矩阵t应用到我的对象上,对象的位置就会出现错误。

我已经实现了一个快速的jsfiddle来演示我的问题:http://jsfiddle.net/9M3uy/67/

在JSFiddle中,红色旋转正方形是旋转应该结束的位置(由CSS3内置的transform-origin提供),而蓝色旋转正方形是我的计算结果(绿色是原始的非旋转正方形)。

有什么想法吗?我是不是没有理解如何使用平移、旋转、再平移回来的机制,还是我做错了什么?


你必须使用Chrome或Safari浏览器。我更新了JSFiddle,包括所有浏览器所需的CSS。 - syazdani
是的!但看起来你已经找到了答案!我来晚了。 - Ander Biguri
2个回答

2
你的代码存在两个问题:
  1. 矩阵乘法的顺序与你意图相反。看起来你希望 rotate(t, theta) 返回一个应用旋转后接着应用 t 的矩阵,但实际上是相反的——旋转将先应用于 t。你需要在 rotatetranslate 中调用 matrixMultiply 时颠倒参数顺序。
  2. CSS matrix 函数的参数顺序不正确。正确的顺序应为 a11, a21, a12, a22, a13, a23。而你传入的是 a11, a12, a21, a22, a13, a23
这里是已经修复好的版本链接:fixed version

这是interjay修复版本的优化版。http://jsfiddle.net/orwellophile/hvvo9oh8/ - Orwellophile

0

先尝试实现2D情况下的“标准”3x3矩阵乘法,然后再尝试优化掉由于乘以零而产生的元素。当索引方案过于不规范时,很难看出公式是否正确。

旋转矩阵= [c -s 0; s c 0; 0 0 1]; 平移矩阵= [1 0 x; 0 1 y; 0 0 1];

我必须假设CSS-翻译函数也假定3x3结果。

乘法和旋转都是通过将向量(x,y,1)与相应的矩阵相乘来执行的。

编辑:稍微调整一下后,似乎矩阵m应该被翻译,或者运算符可以定义为 return MatMul([rot matrix],m) and return MatMul([trans matrix],m)

编辑2:现在我可以看到一些奇怪的东西:仅通过+-50,+-50进行平移并旋转约10度,角落不会停留在红色正方形的中心。但无论如何都不理解CSS矩阵的格式。抱歉...


我更新了示例,使其成为完整的3x3乘法:http://jsfiddle.net/9M3uy/5/。CSS变换(我认为这就是你的意思)以矩阵形式输入:`matrix(a, b, c, d, tx, ty)`(它会丢掉第三行)。 - syazdani
1
你必须使用Chrome或Safari(或其他基于Webkit的浏览器)。在CSS中,变换的原点默认为中心,如果您没有在CSS中更改任何内容,则我的代码计算出的矩阵似乎可以工作,但这仅因为浏览器正在为您居中旋转。如果您查看更新的fiddle,在其中我将所有浏览器的原点设置为0,0,您将看到您建议的更改不起作用。 - syazdani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接