1009
复数
题意
给出一个
n
×
m
n\times m
n×m 地图,并将其按比例缩小后随意放置在原地图内部(包括边界),如图矩形ABCD即为原地图,abcd为缩小后地图。
现给出ABCD和abcd八个顶点坐标,一定有一个地点在原地图和新地图的坐标相同(即图中P),求这个点坐标。
思路
新地图由原地图缩小/旋转/平移得到。
考虑复数,复数乘法可以实现向量缩小/旋转,而复数加法可以实现向量平移。
所以一个点的变换
x
→
x
′
x\to x'
x→x′ 可以写为
x
×
r
+
t
=
x
′
x\times r + t = x'
x×r+t=x′,也就是乘上一个系数以及加上一个系数。显然这两个系数对于整个图中任意一个点都是相同的。
于是我们可以任意挑两组点(比如
A
→
a
,
B
→
b
A\to a,B\to b
A→a,B→b),解出
r
,
t
r,t
r,t ,然后算不动点。解
x
×
r
+
t
=
x
x\times r + t = x
x×r+t=x 即可。
代码
complex<double> b[10];
//rx1 + t = y1 && rx2 + t = y2 得到 r,t 代入下式解得x
//rx + t = x;
void solve() {
for(int i = 1; i <= 8; i++) {
int x, y;
cin >> x >> y;
b[i] = {double(x), double(y)};
}
complex<double> x1 = b[1];
complex<double> x2 = b[2];
complex<double> y1 = b[5];
complex<double> y2 = b[6];
complex<double> t = (y1 * x2 - y2 * x1) / (x2 - x1);
complex<double> r = (y2 - t) / x2;
complex<double> x = t / (complex<double>(1, 0) - r);
cout << x.real() << ' ' << x.imag() << endl;
}