javascript - 仿射变换矩阵偏移

标签 javascript graphics matrix html5-canvas affinetransform

这几天一直在折磨我。不是开玩笑,但我一直在努力解决这个问题。

我目前正在尝试使用仿射变换矩阵在 HTML5 中创建等距投影。 我收到一个方 block ,它是一个旋转 45 度的正方形(本质上是方形 Canvas 上的方形菱形)。然后,我根据 x 或 y 方向是否存在增量来缩放其中一个轴。 然后我将轴倾斜一个因子以适合。然后,我通过将初始旋转向后旋转 -45 度来取消初始旋转。

目前,我的仿射矩阵是:

      // note: the difference in z is about 10 in this example,
      //       so, xDiff is usually 40
      var xDiff  = 4 * (center.z   - map[x+1][y].land.z);
      var yDiff  = 4 * (center.z   - map[x][y+1].land.z);

      var matrix = multiplyAll(
        // Rotation
        [COS45,  SIN45,
         -SIN45, COS45],

        // Scale in each respective axis
        [(44+yDiff)/44, 0,
         0, (44+xDiff)/44],

        // Skew each axis
        [1,  -yDiff/(44+yDiff),
         -xDiff/(44+xDiff), 1],

        // Negate the rotation
        [NCOS45, NSIN45,
        -NSIN45, NCOS45]
      );

然后我用:

      // the map has its own x & y values which directions are determined by the red x & y arrows in the picture
      // pX & pY are the point relative to the canvas origin
      var pX = x * 22 - y * 22 + 22;
      var pY = y * 22 + x * 22 - 22 - (center.z * 4);
      context.setTransform(matrix[0], matrix[1],
                           matrix[2], matrix[3],

                           300, 100);

      //m_Context.drawImage(image, pX, pY);
      drawDiamond(pX, pY, true); // draws a 44x44 diamond

Projection test

Transformed plane

如您所见,变换后的矩阵是相对于变换后的 x 轴绘制的(我认为"new"x 轴的斜率为 yDiff/44)。我不确定如何绘制形状以使转换后的结果位于正确的位置。使用 pY = x * 22 - (yDiff/10); 似乎更接近重点,但我通过插入随机数几乎猜到了。

tl;dr:

  • 我进行了一次转型
  • 我有一个图 block 应该在的坐标(如果它没有被转换)
  • 如何计算所需的偏移量,使转换后的图 block 坐标与未转换时应在的位置相同?

PS:底部奇怪的钻石暂时可以忽略,因为它们可以correctly be created一旦我知道如何计算偏移量。

最佳答案

仿射变换矩阵 ([a b c d e f]) 表示这两个方程

x' = ax + cy + e
y' = bx + dy + f

因此,您可以使用偏移量 ef 来绕过缩放和倾斜部分(嵌入在 2x3 或 3x3 矩阵中的 4x4 线性变换)。

这在 postscript 编程中经常使用,其中用于绘制对象的坐标是相对于本地原点的。如果您要连接矩阵,请在 缩放和倾斜之前进行转换,ef 值将保持不受干扰。

关于javascript - 仿射变换矩阵偏移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14867878/

相关文章:

javascript - 制作更加模块化的 graphQL 项目

c++ - OpenGL - 对象轮廓

java - 免费随机人脸生成器

javascript - 鼠标悬停在 javascript 上停止幻灯片放映

javascript - 为不同类型的客户端创建干净且标准的 API

javascript - 根据用户在页面中的位置显示或隐藏 HTML

c - OpenGL "motion dragging"效果 - 未每帧清除屏幕

r - 将一堆函数应用于 R 中矩阵的列

c# - 系统.OutOfMemoryException。创建一个大矩阵

matrix - 在 sympy 中获取矩阵乘法的元素方程