TRICENTR - Triangle From Centroid 题解

· · 题解

要看懂这篇题解,需要了解以下数学知识:

其中 (x_1,y_1),(x_2,y_2),(x_3,y_3) 分别是三角形三个顶点的坐标。

首先,对于三角形的面积,我们可以使用海伦公式求解:

double calc_area(double a, double l, double m, double n)
{
    double b = a * l / m;
    double c = a * l / n;
    double p = (a + b + c) / 2;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}

然后,我们使用 calc_distance 函数来计算重心与垂心的距离,需要一下几步:

  1. 计算出三角形的三边长:b = \frac{a \cdot l}{m}c = \frac{a \cdot l}{n}
  2. 使用勾股定理,求出三角形的垂心的横坐标:xa = \sqrt{\frac{a^2 \cdot l^2}{m^2} - 9 \cdot l^2}(此公式的证明可以看补充证明)。如果 a^2 + b^2 - c^2 < 0,则 xa = -xa
  3. 计算出三角形的重心的横坐标:xg = \frac{a}{3} + \frac{xa}{3}
  4. 计算出三角形的重心的纵坐标:yg = \frac{a \cdot xa - xa^2}{3 \cdot l}
  5. 使用两点坐标距离公式,求出重心坐标和垂心坐标之间的距离:d = \sqrt{(xg - xa)^2 + (l - yg)^2}
double calc_distance(double a, double l, double m, double n)
{
    double b = a * l / m;
    double c = a * l / n;

    double xa = sqrt(a * a * l * l / m / m - 9 * l * l);
    if (a * a + b * b - c * c < 0)
        xa = -xa;
    double xg = a / 3 + xa / 3, yg = (a * xa - xa * xa) / 3 / l;
    return sqrt((xg - xa) * (xg - xa) + (l - yg) * (l - yg));
}

补充证明:xa = \sqrt{\frac{a^2 \cdot l^2}{m^2} - 9 \cdot l^2}

三角形的底边为 a,高为 h,斜边为 b。那么三角形的重心 G 到三角形的底边上的任意一点 A 的距离为 h

现在,我们考虑一个点 AG 的垂线,令该垂线与三角形底边的交点为 X,则 XAh。那么,通过勾股定理可以得到:\frac{a^2}{h^2} + \frac{(xa - l)^2}{h^2} = \frac{b^2}{h^2}

h^2 代入:

\frac{a^2}{\frac{a^2 \cdot l^2}{m^2}} + \frac{(xa - l)^2}{\frac{a^2 \cdot l^2}{m^2}} = \frac{b^2}{\frac{a^2 \cdot l^2}{m^2}}

移项:

\frac{a^2 \cdot l^2}{m^2} + (xa - l)^2 = b^2

用三角形的三边长关系:

\frac{a^2 \cdot l^2}{m^2} + (xa - l)^2 = \frac{a^2 \cdot l^2}{n^2}

移项:

(xa - l)^2 = \frac{a^2 \cdot l^2}{n^2} - \frac{a^2 \cdot l^2}{m^2} = \frac{a^2 \cdot l^2}{m^2} \cdot \frac{n^2 - m^2}{n^2}

因为 n^2 > m^2,所以 (xa - l)^2 > 0,可以得出:

xa - l = \sqrt{\frac{a^2 \cdot l^2}{m^2} \cdot \frac{n^2 - m^2}{n^2}}

因此:

xa = \sqrt{\frac{a^2 \cdot l^2}{m^2} - (l - \sqrt{\frac{a^2 \cdot l^2}{m^2} \cdot \frac{n^2 - m^2}{n^2}})^2} = \sqrt{\frac{a^2 \cdot l^2}{m^2} - 9 \cdot l^2}

最后附上完整代码。

#include <bits/stdc++.h>
using namespace std;

const double pi = acos(-1);

double a, l, m, n;

double calc_area(double a, double l, double m, double n)
{
    double b = a * l / m;
    double c = a * l / n;
    double p = (a + b + c) / 2;
    return sqrt(p * (p - a) * (p - b) * (p - c));
}

double calc_distance(double a, double l, double m, double n)
{
    double b = a * l / m;
    double c = a * l / n;

    double xa = sqrt(a * a * l * l / m / m - 9 * l * l);
    if (a * a + b * b - c * c < 0)
        xa = -xa;
    double xg = a / 3 + xa / 3, yg = (a * xa - xa * xa) / 3 / l;
    return sqrt((xg - xa) * (xg - xa) + (l - yg) * (l - yg));
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin >> a >> l >> m >> n;
        cout << fixed << setprecision(3) << calc_area(a, l, m, n) << " " << calc_distance(a, l, m, n) << endl;
    }
    return 0;
}