简易二维计算几何

发布时间 2023-09-07 17:30:59作者: Kidding_Ma

\(\text{C++}\) 中的 \(\text{complex}\)

先判断该题是浮点数据还是整型数据

浮点用 long double 或者 double

整型用 long long 或者 int

计算过程出现小数务必使用浮点

using Point = std::complex<double>;

读入 \(n\) 个点

int n;
std::cin >> n;
std::vector<Point> a(n);
for (int i = 0; i < n; i++) {
    int x, y;
    std::cin >> x >> y;
    a[i] = Point(x, y);
}

\(\text{complex}\) 有一点点类似 \(\text{pair}\)\(\text{pair}\)\(\text{first}\)\(\text{second}\)\(\text{complex}\)\(\text{real}\)\(\text{imag}\)

Point p(1, 0);
double x = std::real(p);
double y = std::imag(p);

Point p(1, 0);
double x = p.real();
double y = p.imag();

叉乘

auto cross(const Point &a, const Point &b) {
    return std::imag(std::conj(a) * b);
}

点乘

auto dot(const Point &a, const Point &b) {
    return std::real(std::conj(a) * b);
}

向量变为 \(k\)

double k = 2;
Point p(1, 1);
p *= k;
// (2, 2)

\(a,b\) 两点距离

Point a(1, 0), b(0, 1);
double dis = std::abs(a - b);

\(\pi\)

const double Pi = std::acos(-1.0);

平方 \(x^{2}+y^{2}\)

Point a(1, 1);
double d = std::norm(a);

设定 \(x,y\)

Point a(1, 0);
a.real(2);
a.imag(2);

向量旋转,逆时针转 \(rad\) 弧度

Point rotate(const Point &p, const double &rad) {
    return p * Point(std::cos(rad), std::sin(rad));
}

三点构三角形面积

double area(const Point &a, const Point &b, const Point &c) {
    return std::abs(cross(b - a, c - a)) / 2.0;
}

浮点判长度 \(x,y\) 相等

一般 \(\text{EPS} = 10^{-9}\)\(\text{EPS}\) 为浮点修正

constexpr double EPS = 1E-9;
double x, y;
cin >> x >> y;
bool equ = (std::abs(x - y) <= EPS);

输出,没说保留几位就保留多一点

std::cout << std::fixed << std::setprecision(15);

\(\text{arg}\)

Point p(1, 1);
std::cout << std::arg(p); // 返回 std::atan(p.imag() / p.real())

\(\text{Line}\)
这里的线都视为有方向的,从 \(a\) 点到 \(b\)

struct Line {
    Point a, b;
    Line() = default;
    Line(const Point &a, const Point &b) : a(a), b(b) {}
};

Point a(1, 1), b(2, 2);
Line l(a, b);

\(\text{sign}\) 符号判定

int sign(const double &x) {
    return x < -EPS ? -1 : x > EPS ? 1 : 0;
}

\(\text{onLeft}\) 判定

// 1->点在左侧 -1->点在右侧 0->点在线上
int onLeft(const Point &p, const Line &l) {
    return sign(cross(l.b - l.a, p - l.a));
}