PIXI.js - Canvas 坐标到容器坐标
PIXI.js - Canvas Coordinate to Container Coordinate
我已经启动了一个PIXI js canvas:
g_App = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
设置容器:
container = new PIXI.Container();
g_App.stage.addChild(container);
将背景纹理 (2000x2000) 放入容器中:
var texture = PIXI.Texture.fromImage('picBottom.png');
var back = new PIXI.Sprite(texture);
container.addChild(back);
设置全局:
var g_Container = container;
我在容器和 canvas 舞台元素上做各种枢轴点和旋转:
// Set the focus point of the container
g_App.stage.x = Math.floor(400);
g_App.stage.y = Math.floor(500); // Note this one is not central
g_Container.pivot.set(1000, 1000);
g_Container.rotation = 1.5; // radians
现在我需要能够将 canvas 像素转换为背景纹理上的像素。
g_Container
有一个元素 transform
,它又有几个元素 localTransform
、pivot
、position
、scale
和 skew
。同样 g_App.stage
具有相同的 transform
元素。
在数学中这很简单,你只需要矢量点并对它们进行矩阵运算。然后以另一种方式返回,你只需找到这些矩阵的逆并向后相乘。
那么我在pixi.js这里做什么?
如何转换 canvas 上的像素并查看背景容器上的像素?
注意:以下是根据美国使用矩阵的惯例编写的。它们在左侧有行向量,并将它们乘以右侧的矩阵。 (我们英国讨厌的英国人做的恰恰相反。我们在右边有列向量,然后用它乘以左边的矩阵。这意味着英国和美国的矩阵做同样的工作看起来会略有不同。)
现在已经把大家弄糊涂了,继续解答。
g_Container.transform.localTransform
- 该矩阵将世界坐标转换为 scaled/transposed/rotated 坐标
g_App.stage.transform.localTransform
- 该矩阵采用旋转的世界坐标并输出屏幕(或更准确地说)html canvas 坐标
例如容器矩阵是:
MatContainer = [g_Container.transform.localTransform.a, g_Container.transform.localTransform.b, 0]
[g_Container.transform.localTransform.c, g_Container.transform.localTransform.d, 0]
[g_Container.transform.localTransform.tx, g_Container.transform.localTransform.ty, 1]
旋转到屏幕的容器矩阵是:
MatToScreen = [g_App.stage.transform.localTransform.a, g_App.stage.transform.localTransform.b, 0]
[g_App.stage.transform.localTransform.c, g_App.stage.transform.localTransform.d, 0]
[g_App.stage.transform.localTransform.tx, g_App.stage.transform.localTransform.ty, 1]
所以要从世界坐标到屏幕坐标(注意我们的向量将在左边一行,所以首先作用于世界坐标的第一个操作矩阵也必须在左边),我们需要将向量乘以:
MatAll = MatContainer * MatToScreen
因此,如果您有一个世界坐标向量 vectWorld = [worldX, worldY, 1.0]
(我将在最后解释 1.0),那么要获得屏幕坐标,您可以执行以下操作:
vectScreen = vectWorld * MatAll
因此,要获得屏幕坐标和世界坐标,我们首先需要计算 MatAll
的逆矩阵,称之为 invMatAll
。 (有很多地方告诉你如何做到这一点,所以我不会在这里做。)
所以如果我们有屏幕 (canvas) 坐标 screenX 和 screenY,我们需要创建一个向量 vectScreen = [screenX, screenY, 1.0]
(稍后我将再次解释 1.0),然后得到世界坐标 worldX
和 worldY
我们做:
vectWorld = vectScreen * invMatAll
就是这样。
那么 1.0 呢?
在 2D 系统中,您可以进行旋转,使用 2x2 矩阵进行缩放。不幸的是,您不能使用 2x2 矩阵进行二维平移。因此,您需要 3x3 矩阵来完整描述所有 2D 缩放、旋转和平移。这意味着您还需要制作矢量 3D,并且需要将 1.0 放在第三个位置才能正确进行平移。这个 1.0 在任何矩阵运算之后也将是 1.0。
注意:如果我们在 3D 系统中工作,我们将需要 4x4 矩阵并出于完全相同的原因在我们的 4D 向量中放置一个虚拟 1.0。
我已经启动了一个PIXI js canvas:
g_App = new PIXI.Application(800, 600, { backgroundColor: 0x1099bb });
设置容器:
container = new PIXI.Container();
g_App.stage.addChild(container);
将背景纹理 (2000x2000) 放入容器中:
var texture = PIXI.Texture.fromImage('picBottom.png');
var back = new PIXI.Sprite(texture);
container.addChild(back);
设置全局:
var g_Container = container;
我在容器和 canvas 舞台元素上做各种枢轴点和旋转:
// Set the focus point of the container
g_App.stage.x = Math.floor(400);
g_App.stage.y = Math.floor(500); // Note this one is not central
g_Container.pivot.set(1000, 1000);
g_Container.rotation = 1.5; // radians
现在我需要能够将 canvas 像素转换为背景纹理上的像素。
g_Container
有一个元素 transform
,它又有几个元素 localTransform
、pivot
、position
、scale
和 skew
。同样 g_App.stage
具有相同的 transform
元素。
在数学中这很简单,你只需要矢量点并对它们进行矩阵运算。然后以另一种方式返回,你只需找到这些矩阵的逆并向后相乘。
那么我在pixi.js这里做什么?
如何转换 canvas 上的像素并查看背景容器上的像素?
注意:以下是根据美国使用矩阵的惯例编写的。它们在左侧有行向量,并将它们乘以右侧的矩阵。 (我们英国讨厌的英国人做的恰恰相反。我们在右边有列向量,然后用它乘以左边的矩阵。这意味着英国和美国的矩阵做同样的工作看起来会略有不同。)
现在已经把大家弄糊涂了,继续解答。
g_Container.transform.localTransform
- 该矩阵将世界坐标转换为 scaled/transposed/rotated 坐标
g_App.stage.transform.localTransform
- 该矩阵采用旋转的世界坐标并输出屏幕(或更准确地说)html canvas 坐标
例如容器矩阵是:
MatContainer = [g_Container.transform.localTransform.a, g_Container.transform.localTransform.b, 0]
[g_Container.transform.localTransform.c, g_Container.transform.localTransform.d, 0]
[g_Container.transform.localTransform.tx, g_Container.transform.localTransform.ty, 1]
旋转到屏幕的容器矩阵是:
MatToScreen = [g_App.stage.transform.localTransform.a, g_App.stage.transform.localTransform.b, 0]
[g_App.stage.transform.localTransform.c, g_App.stage.transform.localTransform.d, 0]
[g_App.stage.transform.localTransform.tx, g_App.stage.transform.localTransform.ty, 1]
所以要从世界坐标到屏幕坐标(注意我们的向量将在左边一行,所以首先作用于世界坐标的第一个操作矩阵也必须在左边),我们需要将向量乘以:
MatAll = MatContainer * MatToScreen
因此,如果您有一个世界坐标向量 vectWorld = [worldX, worldY, 1.0]
(我将在最后解释 1.0),那么要获得屏幕坐标,您可以执行以下操作:
vectScreen = vectWorld * MatAll
因此,要获得屏幕坐标和世界坐标,我们首先需要计算 MatAll
的逆矩阵,称之为 invMatAll
。 (有很多地方告诉你如何做到这一点,所以我不会在这里做。)
所以如果我们有屏幕 (canvas) 坐标 screenX 和 screenY,我们需要创建一个向量 vectScreen = [screenX, screenY, 1.0]
(稍后我将再次解释 1.0),然后得到世界坐标 worldX
和 worldY
我们做:
vectWorld = vectScreen * invMatAll
就是这样。
那么 1.0 呢?
在 2D 系统中,您可以进行旋转,使用 2x2 矩阵进行缩放。不幸的是,您不能使用 2x2 矩阵进行二维平移。因此,您需要 3x3 矩阵来完整描述所有 2D 缩放、旋转和平移。这意味着您还需要制作矢量 3D,并且需要将 1.0 放在第三个位置才能正确进行平移。这个 1.0 在任何矩阵运算之后也将是 1.0。
注意:如果我们在 3D 系统中工作,我们将需要 4x4 矩阵并出于完全相同的原因在我们的 4D 向量中放置一个虚拟 1.0。