旋转后的翻译缓冲区
translating buffer after rotating
我希望能够从中心旋转四边形。为此,我遵循以下步骤:
- 转换为 (0, 0)
- 旋转
- 返回目的地
我卡在第三点了。当我旋转矩阵时,我想将它相对于屏幕向右移动一点,但它相对于旋转向右移动了一点。
这是我的代码:
var moveBackX = ((-usedSprite.originX)/usedViewWidth);
var moveBackY = (((usedSprite.originY)))/usedViewHeight;
//The translation is already at (0, 0, 0)
mat4.rotateZ(mvMatrix, mvMatrix, rotation);
mat4.translate(mvMatrix, mvMatrix, [(moveBackX)/scaleX, moveBackY/scaleY, 0.0]);
mat4.translate(mvMatrix, mvMatrix, [((xPos)/scaleX), (-(yPos)/scaleY), 0.0]);
我该如何解决这个问题?
您只需将转换顺序更改为:
mat4.rotateZ(mvMatrix, mvMatrix, rotation);
mat4.translate(mvMatrix, mvMatrix, [(moveBackX)/scaleX, moveBackY/scaleY, 0.0]);
mat4.translate(mvMatrix, mvMatrix, [((xPos)/scaleX), (-(yPos)/scaleY), 0.0]);
下面是一个使用 Context2D 的小演示:
const ctx = maincanvas.getContext('2d');
maincanvas.width = 320;
maincanvas.height = 240;
function drawRect(color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.rect(0, 0, 50, 50);
ctx.stroke();
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(100, 0);
drawRect('#ff8888');
ctx.rotate(Math.PI/12);
drawRect('#ff0000');
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.rotate(Math.PI/12);
drawRect('#88ff88');
ctx.translate(100, 0);
drawRect('#00ff00');
canvas {
width: 320px;
height: 240px;
border: 1px solid black;
}
<canvas id='maincanvas'></canvas>
您必须在我们称之为 "world space" 而不是 "local space" 中应用翻译。您的 mat4.translate() 函数似乎在本地 space 中执行翻译。
更清楚地说,你的平移函数是怎么回事,平移向量乘以变换矩阵的 rotation/scale 部分,这会沿着你的对象的局部轴产生这个平移(即本地 space)。为防止这种情况,您应该简单地将平移向量添加到变换矩阵的平移部分。
让我们假设以下转换 4x4 矩阵:
Xx Xy Xz 0 // <- X axis
Yx Yy Yz 0 // <- Y axis
Zx Zy Zz 0 // <- Z axis
Tx Ty Tz 1 // <- Translation
其中:
mat4[ 0] = Xx; mat4[ 1] = Xy; mat4[ 2] = Xz; mat4[ 3] = 0;
mat4[ 4] = Yx; mat4[ 5] = Yy; mat4[ 6] = Yz; mat4[ 7] = 0;
mat4[ 8] = Zx; mat4[ 9] = Zy; mat4[10] = Zz; mat4[11] = 0;
mat4[12] = Tx; mat4[13] = Ty; mat4[14] = Tz; mat4[15] = 1;
rotation/scale部分(轴)是在[0]到[10](不包括[3]、[7]和[11])范围内定义的3x3矩阵。翻译部分是[12]、[13]和[14]。
要在世界 space 中向此转换矩阵添加翻译,您只需执行以下操作:
mat4[12] += TranslationX;
mat4[13] += TranslationY;
mat4[14] += TranslationZ;
我希望能够从中心旋转四边形。为此,我遵循以下步骤:
- 转换为 (0, 0)
- 旋转
- 返回目的地
我卡在第三点了。当我旋转矩阵时,我想将它相对于屏幕向右移动一点,但它相对于旋转向右移动了一点。
这是我的代码:
var moveBackX = ((-usedSprite.originX)/usedViewWidth);
var moveBackY = (((usedSprite.originY)))/usedViewHeight;
//The translation is already at (0, 0, 0)
mat4.rotateZ(mvMatrix, mvMatrix, rotation);
mat4.translate(mvMatrix, mvMatrix, [(moveBackX)/scaleX, moveBackY/scaleY, 0.0]);
mat4.translate(mvMatrix, mvMatrix, [((xPos)/scaleX), (-(yPos)/scaleY), 0.0]);
我该如何解决这个问题?
您只需将转换顺序更改为:
mat4.rotateZ(mvMatrix, mvMatrix, rotation);
mat4.translate(mvMatrix, mvMatrix, [(moveBackX)/scaleX, moveBackY/scaleY, 0.0]);
mat4.translate(mvMatrix, mvMatrix, [((xPos)/scaleX), (-(yPos)/scaleY), 0.0]);
下面是一个使用 Context2D 的小演示:
const ctx = maincanvas.getContext('2d');
maincanvas.width = 320;
maincanvas.height = 240;
function drawRect(color) {
ctx.strokeStyle = color;
ctx.beginPath();
ctx.rect(0, 0, 50, 50);
ctx.stroke();
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.translate(100, 0);
drawRect('#ff8888');
ctx.rotate(Math.PI/12);
drawRect('#ff0000');
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.rotate(Math.PI/12);
drawRect('#88ff88');
ctx.translate(100, 0);
drawRect('#00ff00');
canvas {
width: 320px;
height: 240px;
border: 1px solid black;
}
<canvas id='maincanvas'></canvas>
您必须在我们称之为 "world space" 而不是 "local space" 中应用翻译。您的 mat4.translate() 函数似乎在本地 space 中执行翻译。
更清楚地说,你的平移函数是怎么回事,平移向量乘以变换矩阵的 rotation/scale 部分,这会沿着你的对象的局部轴产生这个平移(即本地 space)。为防止这种情况,您应该简单地将平移向量添加到变换矩阵的平移部分。
让我们假设以下转换 4x4 矩阵:
Xx Xy Xz 0 // <- X axis
Yx Yy Yz 0 // <- Y axis
Zx Zy Zz 0 // <- Z axis
Tx Ty Tz 1 // <- Translation
其中:
mat4[ 0] = Xx; mat4[ 1] = Xy; mat4[ 2] = Xz; mat4[ 3] = 0;
mat4[ 4] = Yx; mat4[ 5] = Yy; mat4[ 6] = Yz; mat4[ 7] = 0;
mat4[ 8] = Zx; mat4[ 9] = Zy; mat4[10] = Zz; mat4[11] = 0;
mat4[12] = Tx; mat4[13] = Ty; mat4[14] = Tz; mat4[15] = 1;
rotation/scale部分(轴)是在[0]到[10](不包括[3]、[7]和[11])范围内定义的3x3矩阵。翻译部分是[12]、[13]和[14]。
要在世界 space 中向此转换矩阵添加翻译,您只需执行以下操作:
mat4[12] += TranslationX;
mat4[13] += TranslationY;
mat4[14] += TranslationZ;