【问题标题】:How to map java's AffineTransform to android's Matrix?如何将java仿射变换映射到android的矩阵?
【发布时间】:2013-10-02 18:06:07
【问题描述】:

假设我初始化一个 AffineTransform 如下:

AffineTransform af = new AffineTransform(2, 3, 4, 5, 6, 7);

如何使用 android 的 sdk 创建等效矩阵?

【问题讨论】:

  • 需要应用setPivotX(0); setPivotY(0);旋转后得到准确的位置,这是为什么呢?

标签: java android


【解决方案1】:

来自AffineTransform's javadoc

[ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
[ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ]

不确定,但也许

Matrix m = new Matrix();
m.setValues(new float[]{2,3,4,5,6,7,0,0,1});

编辑: 评论者指出顺序应该是

m.setValues(new float[]{2,4,6,3,5,7,0,0,1});

【讨论】:

  • 谢谢,我在文档中没有看到。它实际上是: Matrix m = new Matrix(); m.setValues(new float[]{2,4,6,3,5,7,0,0,1});
  • 真的吗?这很奇怪。我认为这将是列顺序或行顺序.. 您发布的内容似乎是混合的
  • 因为 AffineTransform 的构造函数的顺序很奇怪:AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12)
  • 矩阵被转置了,这就是原因。
  • 需要应用setPivotX(0); setPivotY(0);旋转后得到准确的位置,这是为什么呢?
【解决方案2】:

AffineTransform 中提供的顺序为:

java.awt.geom.AffineTransform.AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12)

从代表 3x3 变换矩阵的 6 个可指定条目的 6 个浮点值构造一个新的 AffineTransform。

参数:
m00 3x3矩阵的X坐标缩放元素
m10 3x3矩阵的Y坐标剪切元素
m01 3x3 矩阵的 X 坐标剪切元素
m11 3x3 矩阵的 Y 坐标缩放元素
m02 X 坐标平移3x3矩阵的元素
m12 3x3矩阵的Y坐标平移元素

一个示例实现:

new AffineTransform(
    q0, q1, q2,
    q3, q4, q5);

反直觉地产生:

[  m00  m01  m02  ]   [ q0  q2  q4 ]
[  m10  m11  m12  ] = [ q1  q3  q5 ]
[   0    0    1   ]   [  0   0   1 ]

使用android.graphics.Matrix 完成相同的结果:

Matrix m = new Matrix();
m.setValues(new float[] {
    q0, q2, q4,
    q1, q3, q5,
     0,  0,  1
}

我认为 Matrix 的 setValues() 方法文档可以改进;它应该反映其参数的顺序是:

void android.graphics.Matrix.setValues(float[] values)

将数组中的 9 个值复制到矩阵中。根据 Matrix 的实现,这些可能会被转换为 Matrix 中的 16.16 个整数,这样后续对 getValues() 的调用将不会产生完全相同的值。

这些值按以下顺序提供到 3x3 矩阵中:

float[] {  
    m00, m01, m02,
    m10, m11, m12,
    m20, m21, m22
}

地点:

m00 3x3 矩阵的 X 坐标缩放元素 (Matrix.MSCALE_X)
m01 3x3 矩阵的 X 坐标剪切元素 (Matrix.MSKEW_X)
m02 3x3 矩阵的 X 坐标平移元素 (Matrix.MTRANS_X)
m10 3x3 矩阵的 Y 坐标剪切元素 (Matrix.MSKEW_Y)
m11 3x3 矩阵的 Y 坐标缩放元素 (Matrix.MSCALE_Y)
m12 3x3 矩阵的 Y 坐标平移元素 (Matrix.MTRANS_Y)
m20 3x3 矩阵的第一个透视元素 (Matrix.MPERSP_0)
m21 3x3 矩阵的第二个透视元素 (Matrix.MPERSP_1)
m22 3x3 矩阵的第三个透视元素 (Matrix.MPERSP_2)

【讨论】:

  • 我正在使用 getmatrix 从图像中获取矩阵。我应该遵循哪个顺序?
  • Android 始终使用相同的矩阵顺序,因此您永远不会在 SDK 中看到 AWT 顺序。
  • -ve 是我的错误,矩阵的顺序不同。但我仍然需要应用 setPivotX(0); setPivotY(0);旋转后得到准确的位置为什么会这样
【解决方案3】:

这是一个演示 Java 代码:

 public static float[] createMatrixValues(AffineTransform Tx) {
    double[] at = new double[9];
    Tx.getMatrix(at);
    float[] f = new float[at.length];
    f[0] = (float) at[0];
    f[1] = (float) at[2];
    f[2] = (float) at[4];
    f[3] = (float) at[1];
    f[4] = (float) at[3];
    f[5] = (float) at[5];
    f[6] = 0;
    f[7] = 0;
    f[8] = 1;
    return f;
}

并创建 Matrix 对象:

public static Matrix createMatrixObj(AffineTransform Tx) {
    Matrix m = new Matrix();
    m.reset();
    m.setValues(createMatrix(Tx));
    return m;
}

我希望这个辅助方法能解决你的问题。

【讨论】:

  • 需要应用setPivotX(0); setPivotY(0);旋转后得到准确的位置,这是为什么呢?
猜你喜欢
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 2020-07-06
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多