STDIO
Tìm kiếm gần đây
    Nội dung
    0
    0
    Chia sẻ
    Nội dung
    0
    0
    Chia sẻ

    Collision Detection – Xét Va Chạm Giữa Hình Tròn và Hình Chữ Nhật

    Để mô phỏng được các tình huống như ở thế giới thực thì cần phải kết hợp vật lý trong thế giới thực, các tính năng như phát hiện va chạm, lực đàn hồi, độ đàn hồi, ma sát, ... cần được đưa vào phần mềm. Bài viết này  giới thiệu 1 trong các tình huống đó là phát hiện va chạm giữa hình tròn và hình chữ nhật.
    02/04/2017 27/08/2020 2 phút đọc
    Collision Detection – Xét Va Chạm Giữa Hình Tròn và Hình Chữ Nhật

    Va chạm giữa hình tròn và hình chữ nhật

    Thuật toán

    Gọi C(Xc, Yc) là tâm hình tròn có bán kính là R. Tìm điểm A là điểm gần nhất thuộc hình chữ nhật đến tâm C. So sánh độ dài CA và R. Nếu CA<=R thì va chạm. CA>R thì không va chạm. (Khi C nằm trong hình chữ nhật thì C trùng A).

    Khoảng cách CA được biểu diễn như hình vẽ:

    Kiểm tra va chạm giữa hình chữ nhật và hình tròn

    Để tính được CA, cần xác định điểm A theo thuật toán sau:

    • B1: Gán A = C (Xa = Xc, Ya = Yc)
    • B2: Nếu Xc < rect.left thì Xa=rect.left
      • Xc > rect.right thì Xa = rect.right
      • Xc >= rect.left && Xc <= rect.right thì Xa = Xc
    • B3: Nếu Yc < rect.top thì Ya = rect.top
      • Nếu Yc > rect.bottom thì Ya = rect.bottom
      • Nếu Yc >= rect.top && Yc<= rect.right thì Ya = Yc 

    * Trường hợp điểm 0(0, 0) nằm ở góc trên bên trái màn hình, trục tọa độ hướng xuống.

    Có điểm A, tính CA rồi so sánh với R.

    Code mẫu C++ xét sự tương quan giữa hình tròn và hình chữ nhật

    Khai báo các thành phần của hình tròn và hình chữ nhật

    struct Point
    {
        double x;
        double y;
    
        Point(Point p)
        {
            x = p.x;
            y = p.y;
        }
    };
    
    struct Circle
    {
        Point O;
        double r;
    
        Circle(Point _o, double _r) : Point(_o)
        {
            r = _r;
        }
    };
    
    struct Rectangle
    {
        double top;
        double bottom;
        double left;
        double right;
    
        Rectangle(double _top, double _bottom, double _left, double _right)
        {
            top = _top;
            bottom = _bottom;
            left = _left;
            right = _right;
        }
    };
    
    bool checkCollision(Circle cir, Rectangle rect)
    {
        double Ax = cir.O.x;
        double Ay = cir.O.y;
    
        if(cir.O.x < rect.left)
            Ax = rect.left;
        else if(cir.O.x > rect.right)
            Ax = rect.right;
    
        if(cir.O.y < rect.top)
            Ay = rect.top;
        else if(cir.O.y > rect.bottom)
            Ay = rect.bottom;
    
        double dx = cir.O.x - Ax;
        double dy = cir.O.y - Ay;
    
        return (dx * dx + dy * dy) <= cir.r * cir.r;
    }
    
    int main()
    {
        Point p(2.5, 6.6);
        
        Circle cir(p, 2.5);
        Rectangle rect(1.56, 7.95, 3.28, 13.4);
        
        if(checkCollision(cir, rect))
            cout << "cir(rect)";
        else cout << "cir   rect";
        
        return 0;
    }

    Bài chung series

    0 Bình luận
    Giải Thuật Lập Trình

    Giải Thuật Lập Trình

    STDIO Training - Chia sẻ các giải thuật lập trình từ cổ điển đến hiện đại.

    Khi bạn nhấn vào sản phẩm do chúng tôi đề xuất và mua hàng, chúng tôi sẽ nhận được hoa hồng. Điều này hỗ trợ chúng tôi có thêm kinh phí tạo nhiều nội dung hữu ích. Tìm hiểu thêm.
    STDIO

    Trang chính

    Công ty TNHH STDIO

    • 30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
      +84 28.36205514 - +84 942.111912
      developer@stdio.vn
    • 383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
      Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012
    ©STDIO, 2013 - 2021