Wiki Thuật toán Hình học tính toán

Hình học tính toán

huunguyen huunguyen Updated Tháng tư 8, 2026

Hình học tính toán (Computational Geometry) là nhánh thuật toán xử lý các bài toán về điểm, đường thẳng, đa giác và các đối tượng hình học khác.

Cơ sở: Vector và tích có hướng

struct Point {
    long long x, y;
    Point(long long x=0, long long y=0): x(x), y(y) {}
    Point operator-(const Point& p) const { return {x-p.x, y-p.y}; }
    Point operator+(const Point& p) const { return {x+p.x, y+p.y}; }
};

// Tích có hướng (cross product) của vector OA và OB
// > 0: B nằm bên trái OA (ngược chiều kim đồng hồ)
// < 0: B nằm bên phải OA (cùng chiều kim đồng hồ)
// = 0: A, O, B thẳng hàng
long long cross(Point O, Point A, Point B) {
    return (long long)(A.x-O.x)*(B.y-O.y) - (long long)(A.y-O.y)*(B.x-O.x);
}

// Tích vô hướng (dot product)
long long dot(Point A, Point B) { return A.x*B.x + A.y*B.y; }

// Khoảng cách bình phương (tránh sqrt)
long long dist2(Point A, Point B) {
    return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y);
}

Kiểm tra điểm nằm trong tam giác

bool point_in_triangle(Point P, Point A, Point B, Point C) {
    long long d1 = cross(A, B, P);
    long long d2 = cross(B, C, P);
    long long d3 = cross(C, A, P);
    bool has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
    bool has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
    return !(has_neg && has_pos);
}

Giao điểm hai đoạn thẳng

// Kiểm tra hai đoạn AB và CD có giao nhau không
bool segments_intersect(Point A, Point B, Point C, Point D) {
    long long d1 = cross(C, D, A);
    long long d2 = cross(C, D, B);
    long long d3 = cross(A, B, C);
    long long d4 = cross(A, B, D);

    if (((d1>0&&d2<0)||(d1<0&&d2>0)) && ((d3>0&&d4<0)||(d3<0&&d4>0)))
        return true;

    // Kiểm tra trường hợp thẳng hàng
    auto on_segment = [](Point P, Point A, Point B) {
        return min(A.x,B.x)<=P.x && P.x<=max(A.x,B.x)
            && min(A.y,B.y)<=P.y && P.y<=max(A.y,B.y);
    };
    if (d1==0 && on_segment(A,C,D)) return true;
    if (d2==0 && on_segment(B,C,D)) return true;
    if (d3==0 && on_segment(C,A,B)) return true;
    if (d4==0 && on_segment(D,A,B)) return true;
    return false;
}

Diện tích đa giác (Shoelace Formula)

long long polygon_area2(vector<Point>& pts) {
    long long area = 0;
    int n = pts.size();
    for (int i = 0; i < n; i++) {
        int j = (i+1) % n;
        area += pts[i].x * pts[j].y;
        area -= pts[j].x * pts[i].y;
    }
    return abs(area);   // diện tích thực = area/2
}

Các trang con

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0