Làm thế nào để tìm các ô lưới 2D quét bởi một vòng tròn chuyển động?


9

Tôi đang tạo một trò chơi dựa trên lưới 2D, với một số ô có thể vượt qua và một số thì không. Các đối tượng động có thể di chuyển liên tục, độc lập với lưới, nhưng cần phải va chạm với các tế bào không thể vượt qua.

Tôi đã viết một thuật toán để theo dõi một tia so với lưới, nó cung cấp cho tôi tất cả các ô mà tia đó giao nhau. Tuy nhiên, đối tượng thực tế không có kích thước điểm; Tôi hiện đang đại diện cho họ như là vòng tròn. Nhưng tôi không thể tìm ra một thuật toán hiệu quả để theo dõi một vòng tròn chuyển động. Đây là hình ảnh của những gì tôi cần: nhập mô tả hình ảnh ở đây

Các số hiển thị theo thứ tự vòng tròn va chạm với các ô lưới. Có ai biết thuật toán để tìm những va chạm này không? Tốt nhất là trong C #.

Cập nhật Vòng tròn thể lớn hơn một ô lưới đơn.


mmh tại sao 3 va chạm TRƯỚC 4?
FxIII

@FxIII Tôi thực sự đã di chuyển vòng tròn trong ảnh và nó chạm 3 trước 4. Chỉ hầu như không có, nhưng vẫn còn trước đó.
Nevermind

Câu trả lời:


6

Tôi nghĩ rằng bản vẽ của bạn hơi sai lệch bởi vì bạn chọn vẽ các nét từ điểm trên đường tròn tiếp tuyến với hướng di chuyển của bạn. Tôi có thể thấy rằng các va chạm vào các cạnh lưới của bạn sẽ xảy ra khi các điểm TOP và TRÁI của vòng tròn của bạn chạm vào một cạnh.

Đặt C là tâm của bạn và r bán kính sao cho P ' = C + ( r , 0) và P " = C + (0, r).

Nếu D là vectơ chỉ đường của bạn (câu thơ), bạn có hai dòng:

R '= D · t + P' ,

R "= D · t + P"

Bạn đơn giản phải tìm giao điểm của các đường đó với các đường phương trình:

y = i và y = i đó là các cạnh của lưới của bạn!

Giải pháp rất dễ vì bạn chỉ cần xem xét thành phần x hoặc y của R 'và R ". Bạn sẽ tìm thấy giá trị t s cho mỗi phần chèn và các điểm cho thoose t s, chỉ cần sắp xếp các điểm đó theo t và bạn xong rồi

Tôi tin rằng bạn có thể dễ dàng nói ô nào bị tấn công nếu bạn biết điểm giao nhau.

Điều này hoạt động nếu r <1 (chiều rộng và chiều cao của ô).

Nó cũng hoạt động đối với các trường hợp khác chỉ đơn giản là thực hiện một số xem xét về P 'P " . Chúng tôi chọn TOP và LEFT vì hướng, BOTTOM và RIGHT nên được xem xét cho hướng ngược lại, bạn hiểu tại sao.

Bây giờ hãy nhìn vào hình ảnh này: vòng tròn lớn

Vòng tròn lớn hơn một ô duy nhất và chúng tôi cho rằng nó sẽ đi cùng hướng với bản vẽ của bạn. P1 là điểm đầu tiên sẽ chạm vào, P2 là điểm thứ hai, P3 là vô dụng vì nằm ở nửa dưới. Những gì bạn cần làm là truyền các tia từ P1 và P2 như chúng ta đã thấy trước đó và làm tương tự cho các đường thẳng đứng.

Nói chung, bạn sẽ có các điểm bắt đầu khác cùng với các điểm TOP và TRÁI từ nơi bắn tia của bạn, vòng tròn của bạn càng lớn, càng nhiều tia để đúc.

Thành thật mà nói, một số bạn có thể tránh bắn tất cả các tia đó bằng cách xem xét hình học, nhưng điều đó có thể làm cho những điều khó hiểu hơn.


Vâng, tôi đã tự nghĩ ra điểm P 'và P ", nhưng không thể biết phải làm gì khi vòng tròn lớn hơn một ô. Các điểm bổ sung thực sự có ý nghĩa (và rõ ràng tôi chỉ cần thêm các tia giữa P' và P ")
Nevermind

Cân nhắc hình học có thể được thực hiện để đơn giản hóa các tính toán nhưng sử dụng thực hiện có thể dẫn bạn đến kết quả tương tự bằng kinh nghiệm.
FxIII

Có rõ ràng rằng bạn phải kiểm tra riêng cho các đường lưới ngang và dọc?
FxIII

Tôi nghĩ bạn cũng phải kiểm tra khi vòng tròn bao phủ một đỉnh lưới, bởi vì vòng tròn sẽ va chạm với ô liền kề chéo ở góc của nó nhưng nó không nhất thiết phải là điểm trên cùng / trái / dưới / phải trên vòng tròn chạm vào nó trước (và bạn sẽ phát hiện ra sự va chạm quá sớm.) Ví dụ: hình vuông 3,4,5 trong sơ đồ ví dụ trong câu hỏi. Chúng được đánh theo thứ tự (3 rồi 4 rồi 5) nhưng thuật toán của bạn sẽ phát hiện đồng thời 4 & 5.
vây

@finnw chúng chỉ chạm đồng thời nếu cicle di chuyển chính xác theo hướng của bisector.
FxIII

1

Nếu bạn muốn sử dụng thuật toán va chạm tia của mình, bạn có thể chọn tám điểm trên mỗi vòng tròn (với mức tăng 45 độ, căn chỉnh với lưới vuông của bạn) và sử dụng xung đột tia giữa các điểm tương ứng (nghĩa là từ đỉnh của một điểm vòng tròn lên đỉnh của cái khác). Sự kết hợp của tất cả các va chạm tia này là toàn bộ các ô được giao nhau.

Bạn có thể có thể cải thiện điều này một chút - ví dụ: bằng cách sử dụng đoạn đường thẳng từ tâm của vòng tròn này đến tâm vòng tròn khác, nhưng được mở rộng ở hai bên bởi bán kính của vòng tròn, cũng như các đoạn đường song song trên hoặc ở hai bên của các vòng tròn.


8 tia có thể sẽ đảm bảo tất cả các giao lộ, nhưng chúng sẽ không cung cấp cho chúng theo đúng thứ tự. Và để va chạm tôi cần trật tự, không chỉ là một danh sách các ô.
Nevermind

Tăng cường thuật toán va chạm tia của bạn để giữ giá trị t cho mỗi va chạm. Khi bạn có được sự kết hợp của các ô, bạn có thể sắp xếp theo giá trị t để có thứ tự đúng.
TreDubZedd

Nhưng làm thế nào tôi có thể so sánh giá trị t của các tia khác nhau ?
Không bao giờ bắt đầu

Nếu bạn luôn xuất phát từ cùng một vòng tròn, các điểm giao nhau của bạn sẽ cách các vòng tròn đó. Khi bạn đến một ô mà bạn đã thấy, nếu giá trị t của va chạm hiện tại nhỏ hơn ô trước đó, hãy sử dụng nó ... nếu không, hãy loại bỏ giao lộ (giữ nguyên bản gốc).
TreDubZedd

1
Bạn có thể thoát ra chỉ bằng hai tia sáng ở hai bên của vòng tròn vuông góc với chuyển động, sau đó bạn có thể thấy gạch nào bị tia sáng tấn công và bạn có thể kiểm tra phần còn lại để xem tâm của chúng có rơi vào giữa hai tia không. Thứ duy nhất nên bỏ lỡ sẽ là những thứ va chạm ở vòng tròn đầu hoặc cuối nhưng đó chỉ là hai vòng tròn và có thể được xử lý dễ dàng. Nó có thể chậm hơn một chút so với tám tia, tôi không chắc chắn; nhưng bạn sẽ không cần phải chia tỷ lệ dựa trên kích thước của vòng tròn.
Lunin

1

Tôi không nói rằng đây là một sự tương tự hoàn hảo, nhưng bạn có thể nghĩ về thuật toán dòng của Bresenham . Một sửa đổi của thuật toán này hoặc một trong các phần mở rộng của nó có thể hữu ích, đặc biệt nếu bạn kết hợp nó với một số bài đăng và nhận xét khác. Thông thường, thuật toán này không liên quan đến việc đặt hàng, nhưng tôi nghĩ rằng bạn có thể thêm nó một cách khá tầm thường.


Tôi cũng đã suy nghĩ về điều này, nhưng theo ý kiến ​​của tôi, đây không phải là thuật toán phù hợp. Bresenham chỉ chọn một pixel, anh ta cần tất cả. Và sẽ rất khó để điều chỉnh bresenham thành vòng tròn chỉ với một pixel.
zacharmarz

Công cụ đánh dấu tia tôi sử dụng thực sự là loại sắp xếp dựa trên thuật toán Bresenham. Tôi gặp khó khăn khi khái quát nó từ một đường mỏng thành "béo", đặc biệt là quét vòng tròn.
Nevermind
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.