Affine变换的效果为:

If a point originally had coordinates (x, y), then after the transformation it will have coordinates (ax + cy + e, bx + dy + f)

参考setTransform文档

设各点表示为 src: (s00, s01), (s10, s11), (s20, s21); dst: (d00, d01), ...

整理可得两组三元一次等式:

a, c, e: \[\begin{array}{c} d00 = a * s00 + c * s01 + e \\ d10 = a * s10 + c * s11 + e \\ d20 = a * s20 + c * s21 + e \\ \end{array}\]

b, d, f: \[\begin{array}{c} d01 = b * s00 + d * s01 + f \\ d11 = b * s10 + d * s11 + f \\ d21 = b * s20 + d * s21 + f \\ \end{array}\]

先考虑 a, c, e

分别使用 d00 - d10, d00 - d20 消去 e: \[\begin{array}{c} d00 - d10 &= a * (s00 - s10) + c * (s01 - s11) \\ d00 - d20 &= a * (s00 - s20) + c * (s01 - s21) \\ \end{array}\]

简化记录, 记 \(d_{00,10} = d00-d10\)

再消去c: \[\begin{array}{c} d_{00,10} \cdot s_{01,21} &= a \cdot s_{00,10} \cdot s_{01,21} + c \cdot s_{01,11} \cdot s_{01,21} \\ d_{00,20} \cdot s_{01,11} &= a \cdot s_{00,20} \cdot s_{01,11} + c \cdot s_{01,21} \cdot s_{01,11} \\ d_{00,10} \cdot s_{01,21} - d_{00,20} \cdot s_{01,11} &= a \cdot (s_{00,10} \cdot s_{01,21} - s_{00,20} \cdot s_{01,11}) \\ \end{array}\]

最终得到:

\[ a = (d_{00,10} \cdot s_{01,21} - d_{00,20} \cdot s_{01,11}) / (s_{00,10} \cdot s_{01,21} - s_{00,20} \cdot s_{01,11}) \]

代入 \(d00 - d10 = a * (s00 - s10) + c * (s01 - s11)\), 得到:

\[\begin{array}{c} c * (s01 - s11) = (d00 - d10) - a * (s00 - s10) \\ c = (d_{00,10} - a \cdot s_{00,10}) / s_{01,11} \\ \end{array}\]

再代入\(d00 = a * s00 + c * s01 + e\), 最终得到: \[\begin{array}{c} a =& (d_{00,10} \cdot s_{01,21} - d_{00,20} \cdot s_{01,11}) / (s_{00,10} \cdot s_{01,21} - s_{00,20} \cdot s_{01,11}) \\ c =& (d_{00,10} - a \cdot s_{00,10}) / s_{01,11} \\ e =& d00 - a * s00 - c * s01 \\ \end{array}\]

b, d, f的结果, 可以直接使用a, c, e的结果, 替换得到. \[\begin{array}{c} d_{00,10} & \rightarrow & d{01,11} \\ d_{00,20} & \rightarrow & d{01,21} \\ d00 & \rightarrow & d01 \\ a & \rightarrow & b \\ c & \rightarrow & d \\ \end{array}\]

得到: \[\begin{array}{c} b =& (d_{01,11} \cdot s_{01,21} - d_{01,21} \cdot s_{01,11}) / (s_{00,10} \cdot s_{01,21} - s_{00,20} \cdot s_{01,11}) \\ d =& (d_{01,11} - b \cdot s_{00,10}) / s_{01,11} \\ f =& d01 - b * s00 - d * s01 \\ \end{array}\]

const src_00_10 = src[0][0] - src[1][0],
  src_00_20 = src[0][0] - src[2][0],
  src_01_21 = src[0][1] - src[2][1],
  src_01_11 = src[0][1] - src[1][1],
  dst_00_10 = dst[0][0] - dst[1][0],
  dst_00_20 = dst[0][0] - dst[2][0],
  dst_01_11 = dst[0][1] - dst[1][1],
  dst_01_21 = dst[0][1] - dst[2][1],
  mult1 = 1 / (src_00_10 * src_01_21 - src_00_20 * src_01_11),
  mult2 = 1 / src_01_11;

const a = (dst_00_10 * src_01_21 - dst_00_20 * src_01_11) * mult1;
const c = (dst_00_10 - a * src_00_10) * mult2;
const e = dst[0][0] - a * src[0][0] - c * src[0][1];

const b = (dst_01_11 * src_01_21 - dst_01_21 * src_01_11) * mult1;
const d = (dst_01_11 - b * src_00_10) * mult2;
const f = dst[0][1] - b * src[0][0] - d * src[0][1];