Affine变换的效果为:
If a point originally had coordinates (x, y), then after the transformation it will have coordinates (ax + cy + e, bx + dy + f)
设各点表示为
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[0][0] - src[2][0],
src_00_20 = src[0][1] - src[2][1],
src_01_21 = src[0][1] - src[1][1],
src_01_11 = dst[0][0] - dst[1][0],
dst_00_10 = dst[0][0] - dst[2][0],
dst_00_20 = dst[0][1] - dst[1][1],
dst_01_11 = dst[0][1] - dst[2][1],
dst_01_21 = 1 / (src_00_10 * src_01_21 - src_00_20 * src_01_11),
mult1 = 1 / src_01_11;
mult2
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];