几何

二维平面上

#include <bits/stdc++.h>
namespace math2d {
template <typename T>  // 二维平面 点
using point_t = std::pair<T, T>;
namespace points {
template <typename T>  // 二维平面 创建二维点
point_t<T> create(T x, T y) {
    return {x, y};
};
template <typename T>  // 二维平面 两点间的距离
double distance(const point_t<T> &p1, const point_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    // hypot(x, y) => sqrt(x^2 - y^2);
    return std::hypot(x1 - x2, y1 - y2);
}
template <typename T>  // 二维平面 求两点的中点
point_t<T> midpoint(const point_t<T> &p1, const point_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    return {(x1 + x2) / 2, (y1 + y2) / 2};
}
}  // namespace points

template <typename T>  // 二维平面 直线一般式
using line_t = std::tuple<T, T, T>;

namespace lines {
template <typename T>  // 直接给出 a b c 构建一般方程
line_t<T> create(T a, T b, T c) {
    return {a, b, c};
}
template <typename T>  // 给出两个二维点 构建一般方程
line_t<T> create(const point_t<T> &p1, const point_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    auto a = y2 - y1;
    auto b = x1 - x2;
    auto c = x2 * y1 - x1 * y2;
    return {a, b, c};
}
template <typename T>  // 给出两个二维点 求线段垂直平分线的一般方程
line_t<T> verticle_bisector(const point_t<T> &p1, const point_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    auto a = (x1 - x2) * 2;
    auto b = (y1 - y2) * 2;
    auto c = -(x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2);
    return {a, b, c};
}
template <typename T>  // 二维点到直线的距离
double distance(const point_t<T> &p, const line_t<T> &l) {
    const auto &[x, y] = p;
    const auto &[a, b, c] = l;
    return std::abs(a * x + b * y + c) / std::hypot(a, b);
}
template <typename T>  // 给出一条二维线,求他的垂线一般方程
line_t<T> verticle_line(const line_t<T> &l) {
    const auto &[a, b, c] = l;
    return {b, -a, c};
}
template <typename T>  // 将一般方程化到最简
line_t<T> reduce(const line_t<T> &l) {
    auto [a, b, c] = l;
    auto gcd = std::gcd(std::gcd(a, b), c);
    a /= gcd, b /= gcd, c /= gcd;
    if (a < 0) a = -a, b = -b, c = -c;
    if (a == 0 and b < 0) b = -b, c = -c;
    return {a, b, c};
}
template <typename T>  // 判断两条线是不是平行
bool is_parallel(const line_t<T> &l1, const line_t<T> &l2) {
    const auto &[a1, b1, c1] = reduce(l1);
    const auto &[a2, b2, c2] = reduce(l2);
    return a1 == a2 and b1 == b2;
}
template <typename T>  // 判断两条线是不是同一条
bool is_same_line(const line_t<T> &l1, const line_t<T> &l2) {
    return reduce(l1) == reduce(l2);
}
template <typename T>  // 求两直线的交点,记得先判断是否平行(交点不存在)[浮点数的点才能用]
point_t<T> intersection(const line_t<T> &l1, const line_t<T> &l2) {
    const auto &[a1, b1, c1] = l1;
    const auto &[a2, b2, c2] = l2;
    return {(c2 * b1 - c1 * b2) / (a1 * b2 - a2 * b1),
            (a1 * c2 - a2 * c1) / (a2 * b1 - a1 * b2)};
}
};  // namespace lines
};  // namespace math2d

template <typename T>  // 二维平面 点
using point2d_t = std::pair<T, T>;
template <typename T>  // 三维空间 点
using point3d_t = std::tuple<T, T, T>;
namespace points {
template <typename T>  // 二维平面 两点间的距离
double distance(const point2d_t<T> &p1, const point2d_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    return std::hypot(x1 - x2, y1 - y2);
}
template <typename T>  // 二维平面 求两点的中点
point2d_t<T> midpoint(const point2d_t<T> &p1, const point2d_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    return {(x1 + x2) / 2, (y1 + y2) / 2};
}
template <typename T>  // 三维平面 两点间的距离
double distance(const point3d_t<T> &p1, const point3d_t<T> &p2) {
    const auto &[x1, y1, z1] = p1;
    const auto &[x2, y2, z2] = p2;
    return std::hypot(x1 - x2, y1 - y2, z1 - z2);
}
template <typename T>  // 三维平面 求两点的中点
point3d_t<T> midpoint(const point3d_t<T> &p1, const point3d_t<T> &p2) {
    const auto &[x1, y1, z1] = p1;
    const auto &[x2, y2, z2] = p2;
    return {(x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2};
}
}  // namespace points

线

一般式

template<typename T> // 二维平面 直线一般式
using general_line2d_t = std::tuple<T, T, T>;
template<typename T> // 三维空间 直线一般式
using general_line3d_t = std::tuple<T, T, T, T>;

namespace lines {
    template<typename T> // 直接给出 a b c 构建一般方程
    general_line2d_t<T> create(T a, T b, T c){ return {a, b, c}; }
    template<typename T> // 给出两个二维点 构建一般方程
    general_line2d_t<T> create(const point2d_t<T> &p1, const point2d_t<T> &p2) {
        const auto &[x1, y1] = p1;
        const auto &[x2, y2] = p2;
        auto a = y2 - y1;
        auto b = x1 - x2;
        auto c = x2 * y1 - x1 * y2;
        return {a, b, c};
    }
    template<typename T> // 出两个二维点 求线段垂直平分线的一般方程
    general_line2d_t<T> verticle_bisector(const point2d_t<T> &p1, const point2d_t<T> &p2) {
        const auto &[x1, y1] = p1;
        const auto &[x2, y2] = p2;
        auto a = (x1 - x2) * 2;
        auto b = (y1 - y2) * 2;
        auto c = -(x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2);
        return {a, b, c};
    }
    template<typename T> // 将一般方程化到最简
    general_line2d_t<T> reduce(const general_line2d_t<T> &l) {
        auto [a, b, c] = l;
        auto gcd = std::gcd(std::gcd(a, b), c);
        a /= gcd, b /= gcd, c /= gcd;
        if (a < 0)
            a = -a, b = -b, c = -c;
        if (a == 0 and b < 0)
            b = -b, c = -c;
        return {a, b, c};
    }
};

几何
https://winterl-blog.netlify.app/2024/10/26/几何/
作者
winterl
发布于
2024年10月26日
许可协议