从3点生成AffineTransform

时间:2014-01-21 23:03:08

标签: java awt affinetransform

给定坐标系A中的3个点(x和y坐标)以及坐标系B中的3个对应点,我如何得出将从A转换为B的AffineTransform。

我的问题类似于Create transform to map from one rectangle to another?,但该问题只涉及2个点 - 即它假设没有轮换。

2 个答案:

答案 0 :(得分:3)

假设您的转换形式为

x' = px + qy + r
y' = sx + ty + u

并将您的六点写为(A1x, A1y), (A2x, A2y), (A3x, A3y), (B1x, B1y), (B2x, B2y), (B3x, B3y)。用矩阵形式表示

/               \       /           \   /               \
| B1x  B2x  B3x |       | p   q   r |   | A1x  A2x  A3x |
|               |   =   |           |   |               |
| B1y  B2y  B3y |       | s   t   u |   | A1y  A2y  A3y |
\               /       \           /   |               |
                                        |  1    1    1  |
                                        \               /

现在找到右边3x3矩阵的倒数。你会在网上找到很多算法告诉你如何做到这一点。例如,http://www.econ.umn.edu/undergrad/math/An%20Algorithm%20for%20Finding%20the%20Inverse.pdf有一个。

将上面等式的两边乘以3x3矩阵的倒数,得到p, q, r, s, t, u, v的值。

答案 1 :(得分:1)

如果这对其他人有用,这里是我用来执行此操作的Java代码。

    public static AffineTransform deriveAffineTransform(
        double oldX1, double oldY1,
        double oldX2, double oldY2,
        double oldX3, double oldY3,
        double newX1, double newY1,
        double newX2, double newY2,
        double newX3, double newY3) {

    double[][] oldData = { {oldX1, oldX2, oldX3}, {oldY1, oldY2, oldY3}, {1, 1, 1} };
    RealMatrix oldMatrix = MatrixUtils.createRealMatrix(oldData);

    double[][] newData = { {newX1, newX2, newX3}, {newY1, newY2, newY3} };
    RealMatrix newMatrix = MatrixUtils.createRealMatrix(newData);

    RealMatrix inverseOld = new LUDecomposition(oldMatrix).getSolver().getInverse();
    RealMatrix transformationMatrix = newMatrix.multiply(inverseOld);

    double m00 = transformationMatrix.getEntry(0, 0);
    double m01 = transformationMatrix.getEntry(0, 1);
    double m02 = transformationMatrix.getEntry(0, 2);
    double m10 = transformationMatrix.getEntry(1, 0);
    double m11 = transformationMatrix.getEntry(1, 1);
    double m12 = transformationMatrix.getEntry(1, 2);

    return new AffineTransform(m00, m10, m01, m11, m02, m12);       
}