Câu trả lời:
Đây là cố gắng của tôi. Các thuật toán sau không hoàn hảo , nhưng chúng đơn giản và tôi tin rằng bạn nên bắt đầu với điều này, kiểm tra xem chúng có hoạt động trong tình huống của bạn không, và chuyển sang thứ gì đó nhanh hơn và / hoặc chính xác hơn sau này.
Ý tưởng như sau:
Đường cong Bézier được tham số hóa bởi một hàm F(t)
sử dụng một tập hợp các điểm kiểm soát và một tham số khác nhau t
. Số lượng điểm tạo ra là không quan trọng.
Dòng này được tham số hóa bởi hai điểm A
và B
.
Hãy SAMPLES = 10
ví dụ
Bắt đầu với t0 = 0
vàt1 = 1
Để cho dt = (t1 - t0) / SAMPLES
Nếu dt < 1e-10
(hoặc bất kỳ điều kiện chính xác nào khác mà bạn thấy phù hợp), thuật toán đã kết thúc và câu trả lời làF(t0)
.
Tính toán danh sách các SAMPLES + 1
điểm trên đường cong Bézier:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
Tìm điểm nào trong L
chỉ mục i
gần với đường thẳng nhất. Sử dụng bất kỳ phương pháp khoảng cách điểm / đường nào bạn biết, ví dụ khoảng cách vuông ||AB^L[i]A||² / ||AB||²
trong đó ^
biểu thị sản phẩm chéo và ||…||
là khoảng cách.
Nếu i == 0
, đặt i = 1
; nếu i == SAMPLES
, đặti = SAMPLES - 1
Hãy để t1 = t0 + (i + 1) * dt
vàt0 = t0 + (i - 1) * dt
Quay trở lại bước 3.
Lần này chúng ta có hai đường cong Bézier, được tham số hóa bởi F(t)
và G(t)
.
Hãy SAMPLES = 10
ví dụ
Bắt đầu với t0 = 0
, t1 = 1
, s0 = 0
vàs1 = 1
Để cho dt = (t1 - t0) / SAMPLES
Để cho ds = (s1 - s0) / SAMPLES
Nếu dt < 1e-10
(hoặc bất kỳ điều kiện chính xác nào khác mà bạn thấy phù hợp), thuật toán đã kết thúc và câu trả lời làF(t0)
.
NẾU đây là lần chạy đầu tiên của vòng lặp:
6.1. Tính toán danh sách các SAMPLES + 1
điểm trên F
( xem bên trên ).
6.2. Tính toán một danh sách các SAMPLES + 1
điểm trên G
.
6.3. Tìm cặp điểm nào gần nhau nhất.
6.4. Cập nhật t0
, t1
, s0
, s1
như đã thấy ở trên.
ELSE : cách khác là tính toán danh sách các điểm trên F
HOẶC danh sách các điểm trên G
, sau đó tìm điểm nào F
gần nhất G(s0)
và cập nhật t0
và t1
, HOẶC mà điểm G
là gần F(t0)
và cập nhật s0
và s1
.
Quay trở lại bước 3.
Theo thiết kế, các thuật toán này sẽ luôn hội tụ đến mức tối thiểu cục bộ. Tuy nhiên, không có gì đảm bảo rằng họ sẽ hội tụ đến giải pháp tốt nhất. Cụ thể, thuật toán đường cong Bézier hoàn toàn không tốt, và trong trường hợp hai đường cong gần nhau ở nhiều nơi, bạn có thể không may bỏ lỡ giải pháp bằng một cú sút xa.
Nhưng như tôi đã nói, trước khi bạn bắt đầu nghĩ về những giải pháp mạnh mẽ hơn, trước tiên bạn nên thử nghiệm với những giải pháp đơn giản đó.
1) Dịch mọi thứ sang một trục, vì vậy thay vì cần tính độ dài của một điểm đến, 'đường', 'đường', giả sử là Trục Y.
Sau đó, uh, đưa ra một đường cong bezier tôi sẽ nói nó lên đến số điểm kiểm soát.
Nếu có ba, (bắt đầu, 'kiểm soát' và kết thúc) tôi sẽ thực hiện một số loại quét (giả sử mỗi một vài phần trăm và sau đó tinh chỉnh giữa các phương pháp gần nhất (với cách tiếp cận 'nhị phân').
Nhiều điểm hơn tôi sẽ thử cặp đôi gần nhất với (trục Y dịch).
Tôi chắc chắn một anh chàng toán học có thể cung cấp cho bạn giải pháp chính xác (trong toán học) nhưng nếu bạn muốn tìm / một giải pháp trong trò chơi video, bạn có thể tốt hơn với một giải pháp hơi ok vì giải pháp thực sự có thể chứa nhiều câu trả lời ( Tôi thậm chí không nói về sức mạnh xử lý).
Một số câu trả lời từ trang blog Thuật toán , tìm đúng điểm gần nhất trên đường cong bậc hai đã cho.
Bản demo .
Đối với đường cong Bezier - trường hợp đường thẳng, cách chính xác nhất để tìm câu trả lời là làm như sau: