29/09/2012 - 23:20
Tôi đã tạo một git Repo tại đây:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Bạn có thể tải về các tệp nguồn dưới dạng zip từ đó. Nó cũng bao gồm một bản demo mà bạn có thể biên dịch bằng FlashDevelop. Để sử dụng bản demo, hãy mở dự án trong Flash Develop và nhấp vào 'Test Project'. Trong khi chạy bản demo, nhấp vào LMB để chọn ngẫu nhiên một đường cong Bezier mới và Vòng tròn mới.
Chúc may mắn!
Liên kết zip rất khó nhìn - chỉ cần sử dụng Ctrl + F và nhập zip. Nguồn này đại diện cho một vài tuần nghiên cứu và lập trình, tôi hy vọng bạn thích nó.
Nếu bạn có kế hoạch chia bezier theo cách đệ quy thành các phân đoạn và kiểm tra va chạm với chúng, tôi khuyên bạn nên tạo một mảng 100.100 (lưới) và đặt từng phân đoạn vào bốn ô vuông gần nhất, vì vậy bạn chỉ phải kiểm tra va chạm với 4 / 10.000 phân đoạn từng khung.
Tôi nghĩ bạn sẽ được hưởng lợi từ box2d với tư cách là một lập trình viên và là một người sáng tạo trò chơi, vì có rất nhiều trở ngại nhỏ trong việc tạo ra một công cụ vật lý 'đơn giản' làm cho chuyển động có vẻ hơi gập ghềnh và ít trôi chảy hơn.
Câu trả lời cũ: Cách thuần khiết.
Bạn thực sự có thể thấy nếu một vòng tròn đang va chạm với một đường cong Bezier, bằng cách kiểm tra khoảng cách giữa khoảng cách giữa tâm của vòng tròn và điểm gần nhất trên đường cong.
Phương trình khoảng cách (nói chung)
giải thích:
Phương trình Bezier:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Điều này có thể được tóm tắt đến (với một số đại số) - Tôi sẽ bỏ qua. (X, y) để dễ đọc (chúng vẫn là các điểm, không phải là một số)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
Khoảng cách từ điểm (x, y) là:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Để tìm điểm gần nhất trên bezier với quả bóng, bạn cần lấy đạo hàm và tìm tất cả các điểm mà đạo hàm bằng 0 (gốc). Nó là một đa thức bậc ba, do đó bạn có thể sử dụng một công thức đóng nhưng nó có thể không đáng tin cậy vì độ chính xác của dấu phẩy động của máy tính đại diện cho các phân số có thể không đủ. Nó là tốt hơn nhiều để sử dụng Newton hoặc một cái gì đó có tính chất đó.
Đạo hàm bạn cần tìm gốc là:
Giả sử: a = start b = control c = end d = điểm trung tâm cirlce
Phần khó khăn là nhân lên điểm này, bạn phải sử dụng sản phẩm chấm.
Nếu bạn thích, tôi có mã cho điều này và tôi có thể chia sẻ nó ở đây dưới dạng một hàm chỉ đơn giản trả về boolean nếu có va chạm hay không và góc va chạm. Một số vấn đề có thể xuất hiện khi triển khai một động cơ va chạm như thế này chẳng hạn, một quả bóng chuyển động nhanh có thể bị kẹt giữa hai đường cong.
Tôi khuyên bạn nên tránh nó ngay bây giờ, chỉ cần tổng hợp các hệ số cho trục x và cho trục y và thêm chúng lên.
Việc sử dụng bất kỳ phương pháp đáng tin cậy nào bạn có thể chọn như Newton để tìm gốc, kiểm tra khoảng cách từ các điểm gốc trên bezier, 0 <= t <= 1 đến tâm vòng tròn và kiểm tra khoảng cách cho hai đầu của bezier (bắt đầu và kết thúc) đến trung tâm vòng tròn, bất cứ nơi nào gần nhất, sẽ cho bạn biết nếu có va chạm.
Nếu bán kính nhỏ hơn khoảng cách tối thiểu, có va chạm.
Góc này xấp xỉ một góc giữa tâm của vòng tròn và điểm gần nhất trên bezier.
Điều đó đang được nói, nếu bạn thực sự muốn làm một trò chơi với vật lý va chạm, tôi khuyên bạn chỉ nên lặp đi lặp lại trên bezier
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Chia từng mảnh ở giữa một cách đệ quy cho đến khi nó đủ nhỏ, giả sử 10 pixel trở xuống, sau đó xây dựng bezier khoảng từ các hộp và sử dụng Box2d cho vật lý vì có thể việc viết tất cả mã phát hiện va chạm này sẽ chứng tỏ là tuyệt vời thời gian chìm mà không tăng cường chơi trò chơi nhiều. Sử dụng Box2d đã chứng tỏ bản thân trong vô số dự án trong quá khứ.