bzoj3621: 我想那还真是令人高兴啊

题意

给出两个相似的三角形,要求一个点,使一个三角形关于该点缩放、旋转后与另一个三角形重合。

题解

首先三角形的顶点之间有6种对应关于。不放只考虑其中一种。
\(A \leftrightarrow A'\)\(B \leftrightarrow B'\)\(C \leftrightarrow C'\)
考虑到点可以映射复平面上,不妨都用复数表示,因为注意到一个复数就能完成缩放和旋转的操作。
假设所求的点为\(P\),缩放旋转向量为\(T\),则有

\[T(A - P) = A' - P \\ T(B - P) = B' - P \\ T(C - P) = C' - P \\ \]

用其中两个式子解一个方程,带入到另一个式子检验即可。

#include <bits/stdc++.h>
using namespace std;
typedef double db;
const db eps = 1e-4;
struct Complex {
    db a, b;
    Complex () {}
    Complex (db _a, db _b = 0) :
        a(_a), b(_b) {}
    friend Complex operator + (const Complex &c1, const Complex &c2) {
        return Complex(c1.a + c2.a, c1.b + c2.b);
    }
    friend Complex operator - (const Complex &c1, const Complex &c2) {
        return Complex(c1.a - c2.a, c1.b - c2.b);
    }
    friend Complex operator * (const Complex &c1, const Complex &c2) {
        return Complex(c1.a * c2.a - c1.b * c2.b, c1.a * c2.b + c1.b * c2.a);
    }
    friend Complex operator / (const Complex &c1, const Complex &c2) {
        double modulus = c2.a * c2.a + c2.b * c2.b;
        return Complex((c1.a * c2.a + c1.b * c2.b) / modulus, (c1.b * c2.a - c1.a * c2.b) / modulus);
    }
    friend bool operator == (const Complex &c1, const Complex &c2) {
        return fabs(c1.a - c2.a) < eps && fabs(c1.b - c2.b) < eps;
    }
} A, B, C, p[3];
 
bool calc (const Complex _A, const Complex _B, const Complex _C) {
    Complex T = (_A - _B) / (A - B), P = (A * T - _A) / (T - 1);
    if ((C - P) * T == (_C - P)) {
        printf("%lf %lf\n", P.a, P.b);
        return 1;
    }
    return 0;
}
int T;
int main () {
    for (scanf("%d", &T); T; --T) {
        scanf("%lf%lf%lf%lf%lf%lf", &A.a, &A.b, &B.a, &B.b, &C.a, &C.b);
        scanf("%lf%lf%lf%lf%lf%lf", &p[0].a, &p[0].b, &p[1].a, &p[1].b, &p[2].a, &p[2].b);
        if (calc(p[0], p[1], p[2])) {
            continue;
        }
        if (calc(p[0], p[2], p[1])) {
            continue;
        }
        if (calc(p[1], p[0], p[2])) {
            continue;
        }
        if (calc(p[1], p[2], p[0])) {
            continue;
        }
        if (calc(p[2], p[0], p[1])) {
            continue;
        }
        if (calc(p[2], p[1], p[0])) {
            continue;
        }
    }
    return 0;
}
posted @ 2019-07-20 15:19  psimonw  阅读(180)  评论(0编辑  收藏  举报