B2031 计算三角形面积 题解

· · 题解

考虑不使用海伦公式,这题还可以用计算几何的简单方法做。

众所周知两个向量的叉积即这两个向量三个顶点组成三角形的有向面积的两倍。

叉积定义为两个向量长度乘积乘上夹角的 \sin 值。

所以只需计算三个点之间任意两个向量的叉积即可。

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

const double eps = 1e-8;
int sgn(double x) {
    if (fabs(x) < eps) {
        return 0;
    }
    return (x < 0) ? -1 : 1;
}

struct Point {
    double x, y;
    Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}
};
typedef Point Vector;
const double pi = acos(-1.0);

Vector operator + (Vector A, Vector B) {
    return Vector(A.x + B.x, A.y + B.y);
}
Vector operator - (Point A, Point B) {
    return Vector(A.x - B.x, A.y - B.y);
}
Vector operator * (Vector A, double p) {
    return Vector(A.x * p, A.y * p);
}
Vector operator / (Vector A, double p) {
    return Vector(A.x / p, A.y / p);
}
bool operator < (const Point A, const Point B) {
    return A.x < B.x || (sgn(A.x - B.x) == 0 && A.y < B.y);
}
bool operator == (const Point A, const Point B) {
    return sgn(A.x - B.x) == 0 && sgn(A.y - B.y) == 0;
}
double dot(Vector A, Vector B) {
    return A.x * B.x + A.y * B.y;
}
double cross(Vector A, Vector B) {
    return A.x * B.y - A.y * B.x;
}
double length(Vector A) {
    return sqrt(dot(A, A));
}
double areatri(Point A, Point B, Point C) {
    return fabs(cross(B - A, C - A)) / 2;
}
int main() {
    Point a, b, c;
    scanf("%lf%lf%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y, &c.x, &c.y);
    printf("%lf", areatri(a, b, c));
    return 0;
}

顺便赠送计算几何模板