Generate AffineTransform from 3 points

半城伤御伤魂 提交于 2019-12-11 05:08:34

问题


Given 3 points (x and y coordinates) in coordinate system A, and 3 corresponding points in coordinate system B, how can I derive an AffineTransform that will convert from A to B.

My question is similar to Create transform to map from one rectangle to another?, except that question only deals with 2 points - i.e., it assumes there is no rotation.


回答1:


Suppose your transform is of the form

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

and write your six points as (A1x, A1y), (A2x, A2y), (A3x, A3y), (B1x, B1y), (B2x, B2y), (B3x, B3y). Expressing this in matrix form gives

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

Now find the inverse of the 3x3 matrix on the right. You'll find plenty of algorithms online telling you how to do this. There's one at http://www.econ.umn.edu/undergrad/math/An%20Algorithm%20for%20Finding%20the%20Inverse.pdf, for example.

Post-multiply both sides of the equation above by the inverse of the 3x3 matrix, to get the values of p, q, r, s, t, u, v.




回答2:


In case this is useful to anyone else, here is the Java code I used to do this.

    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);       
}


来源:https://stackoverflow.com/questions/21270892/generate-affinetransform-from-3-points

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!