Làm thế nào để bạn tính điểm gần nhất trên 2 đường cong?


15

Cho các điểm của một đường thẳng và một đường cong bậc hai, làm thế nào để bạn tính điểm gần nhất của chúng? .... Tương tự, cho các điểm của 2 đường cong, làm thế nào để bạn có được điểm gần nhất?

nhập mô tả hình ảnh ở đây


2
Tôi tin rằng câu hỏi này là một khởi đầu tốt.
sam hocevar

Câu trả lời:


3

Đâ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:

  • Lấy mẫu đường cong Bézier, tìm điểm gần nhất trên mẫu đó
  • Lấy mẫu một khu phố xung quanh điểm tìm thấy, tìm một điểm gần nhất mới
  • Tiếp tục cho đến khi điểm không còn thay đổi nhiều

Thuật toán cho khoảng cách từ đường cong Bézier đến đường thẳng

Đườ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 AB.

  1. Hãy SAMPLES = 10ví dụ

  2. Bắt đầu với t0 = 0t1 = 1

  3. Để cho dt = (t1 - t0) / SAMPLES

  4. 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) .

  5. 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)
    • Giáo dục
    • L[SAMPLES] = F(t0 + SAMPLES * dt)
  6. Tìm điểm nào trong Lchỉ mục igầ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.

  7. Nếu i == 0, đặt i = 1; nếu i == SAMPLES, đặti = SAMPLES - 1

  8. Hãy để t1 = t0 + (i + 1) * dtt0 = t0 + (i - 1) * dt

  9. Quay trở lại bước 3.

Thuật toán cho khoảng cách từ đường cong Bézier đến đường cong Bézier

Lần này chúng ta có hai đường cong Bézier, được tham số hóa bởi F(t)G(t).

  1. Hãy SAMPLES = 10ví dụ

  2. Bắt đầu với t0 = 0, t1 = 1, s0 = 0s1 = 1

  3. Để cho dt = (t1 - t0) / SAMPLES

  4. Để cho ds = (s1 - s0) / SAMPLES

  5. 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) .

  6. 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, s1như đã thấy ở trên.

  7. 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 Fgần nhất G(s0)và cập nhật t0t1, HOẶC mà điểm Glà gần F(t0)và cập nhật s0s1.

  8. Quay trở lại bước 3.

Các vấn đề

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 đó.


0

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ý).


ps. 2 đường cong, thậm chí không nghĩ về nó (bạn có thể nhận được bất cứ điều gì (ít nhất là có thể ..) theo số điểm kiểm soát)
Valmond 12/12/11


0

Đố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:

  1. Biến đổi bài toán sao cho đường thẳng luôn nằm ngang tại Y = 0. Điều này được thực hiện bằng cách nhân tất cả các điểm kiểm soát với một ma trận affine thích hợp. (Tôi giả sử bạn đã quen với việc biểu diễn các phép biến đổi affine của mặt phẳng với ma trận 3x3 với 3 mục cố định.)
  2. Kiểm tra tọa độ Y của các điểm kiểm soát. Nếu tất cả chúng không có cùng một dấu hiệu, có thể có một giao điểm với đường kẻ. Tính toán gốc của phần Y của đường cong Bezier. Bạn có thể sử dụng bất kỳ phương pháp tìm kiếm gốc cho đa thức, có rất nhiều trong số chúng trong tài liệu. Ví dụ: google "lồi thân tàu" - đây là một phương pháp khá hợp lý cho các đa thức được sử dụng trong các đường cong Bezier. Mỗi gốc bạn tìm thấy là một giá trị thời gian của một giao điểm với đường thẳng, trong đó khoảng cách bằng 0 - công việc của bạn đã hoàn thành.
  3. Nếu tất cả các hợp đồng Y có cùng dấu, hãy tính đạo hàm của phần Y của đường cong Bezier. Bạn có thể bỏ qua tọa độ X của các điểm, vì chúng không tạo ra sự khác biệt - đường đích nằm ngang. Tìm nguồn gốc của đạo hàm đó. Đây là các giá trị thời gian tại đó đường cong gần nhất cục bộ với đường.
  4. Đánh giá rõ ràng đường cong Bezier cho tất cả các gốc bạn đã tìm thấy trong bước trước và báo cáo gốc cung cấp khoảng cách nhỏ nhất từ ​​đường. Bạn cũng cần kiểm tra các điểm cuối - chúng có thể cho khoảng cách nhỏ hơn bất kỳ gốc nào.
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.