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 10. 4, 2026 Đọc 4 phút 6 lượt xem

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

Bài tập luyện

Luyện kỹ thuật
  • Hàng rào kim đồng hồ (clockfnc) (Học việc) Dấu của diện tích có hướng (Shoelace) cho biết đa giác đi theo chiều kim đồng hồ hay ngược lại.
  • Hình bình hành trở lại (paraback) (Trung cấp) Cộng trừ vector: điểm thứ tư là B+C−A (và hai hoán vị), luyện tư duy điểm như vector.
  • Anton và các đường thẳng (antlines) (Nâng cao) Hai đường thẳng cắt nhau trong dải (x1,x2) khi thứ tự y của chúng đảo ngặt giữa hai biên; luyện kiểm tra giao bằng so sánh dấu thay vì tính giao điểm số thực.
  • Tam giác của Vasya (vastri) (Nâng cao) Hai lần diện tích tam giác đỉnh nguyên (tích có hướng) luôn là số nguyên, từ đó suy điều kiện có nghiệm và dựng tam giác vuông bằng gcd.
Đề VOI
  • Trò chơi với những viên bi (voi14_ballgm) (Nâng cao) VOI 2014: subtask dùng tích có hướng để kiểm tra thẳng hàng; bản đầy đủ gom theo vector hướng tối giản bằng số nguyên thay cho góc số thực.
Trang này có hữu ích không? Đăng nhập để trả lời

Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.47 awk 1.3.4 gcc 16.2.0 dotnet 10.0.402 g++ 16.2.0 g++-themis 16.2.0 g++17 16.2.0 g++20 16.2.0 g++23 16.2.0 clang++ 22.1.8 dmd 2.113.0 dart 3.13.6 gforth 0.7.3 gfortran 15.3.0 go 1.27.3 groovyc 5.1.3 javac 26.0.2.1 node 26.12.1 julia 1.13.2 kotlinc 2.4.21 lean 4.35.0 sbcl 2.2.9 lua 5.5.1 nim 2.2.12 fpc 3.2.2 fpc-themis 3.2.2 perl 5.42.3 php 8.5.12 pike 8.0 swipl 9.0.4 pypy3 7.3.23 python3 3.15.1 racket 8.7 ruby 4.0.8 rustc 1.99.1 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 swiftc 6.4.1 tclsh 8.6 bun 1.4.4 deno 2.9.8 v 0.5.2 zig 0.17.0