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ẽ:

Để 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; }