Bagaimana cara menentukan panjang jalan?

11

Saya memiliki permainan yang mengharuskan setiap pemain untuk bergerak di satu jalur yang ditentukan. Saya menggambar jalur menggunakan kurva Bézier. Bagaimana saya bisa menentukan total nyata (tidak linear) panjang jalan dan jarak yang masing-masing pemain telah membuat? (Jarak antara titik awal dan titik tertentu di jalan.)

MEMPERBARUI:

Lintasan direpresentasikan dalam bidang Cartesian (2D).

Valentin Radu
sumber
Pertanyaan Anda dijawab di dekat bagian bawah jawaban ini
BlueRaja - Danny Pflughoeft

Jawaban:

7

Seperti jawaban sebelumnya mengatakan, menghitung panjang kurva Bezier itu sulit ( tidak mungkin ?). Saya akan mengatakan bahwa 100% dari gim menggunakan perkiraan panjang, yang hampir selalu cukup akurat.

Beberapa bulan yang lalu saya menerapkannya menggunakan pendekatan yang diusulkan untuk memecah kurva menjadi segmen "kecil" dan menambahkan panjangnya. Ada contoh implementasi C ++ di sini .

Dan
sumber
11

Mengukur panjang kurva Bezier itu sulit. Jika Anda tidak keberatan sedikit ketidakakuratan, solusi sederhana adalah dengan memperkirakan kurva Bezier dengan garis lurus dan menghitung jumlah panjang garis. Semakin banyak segmen yang Anda buat, semakin baik aproksimasi.

bummzack
sumber
Saya mungkin mempertimbangkan itu, tetapi bagaimana saya bisa menentukan berapa banyak segmen yang harus saya miliki dan bagaimana saya bisa memetakan segmen untuk memiliki titik awal dan titik akhir di jalur saya? Apakah teknik ini memiliki nama? (jadi saya mencarinya di Google)
Valentin Radu
Pendekatan sederhana adalah dengan hanya menggunakan distribusi linier poin dari B (0) ke B (1) ... seperti sesuatu yang Anda gunakan untuk benar-benar memplot kurva. Lihatlah kode sumber dalam jawaban Dan.
bummzack
Saya akan menghargai penjelasan tentang pemungutan suara, hanya untuk mengetahui apa yang bisa saya tingkatkan dalam jawaban saya ...
bummzack
7

Urutan lebih tinggi (yaitu lebih besar dari urutan pertama) parameterisasi panjang spline harus didekati; itu tidak dapat diwakili secara langsung, maka kenyataan bahwa tidak mudah untuk menemukan solusi langsung untuk ini.

Beberapa implementasi yang masih ada (kode salin-tempel):

Menggunakan perkiraan Chebyshev , menurut penulis, akurasi tumbuh seiring meningkatnya ukuran kurva. Lihatlah pp. 7-8 pseudocode, sisanya adalah deskripsi dari algoritma lain di mana mereka mendasarkan pendekatan mereka yang dapat Anda abaikan. Sejumlah referensi online menyebut metode ini sebagai metode yang bagus.

Lihat juga pendekatan singkat ini .

Insinyur
sumber
5

Ini dimulai sebagai komentar pada komentar pada jawaban @ bummzack, tetapi tumbuh terlalu lama.

bagaimana saya bisa menentukan berapa banyak segmen yang harus saya miliki

Ada dua pendekatan. Yang pertama hanyalah algoritma standar untuk merender kurva Bézier: titik kontrol membentuk kotak pembatas kurva, jadi jika semua titik kontrol berada dalam epsilon segmen garis dari titik awal ke titik akhir Anda kira-kira sebagai garis; jika tidak, Anda membagi menggunakan algoritma de Casteljau. Epsilon dipilih sesuai dengan kesalahan yang Anda inginkan pada hasil akhir. (Untuk rendering biasanya 0,5 piksel).

Pendekatan lain adalah penyempurnaan yang menggunakan aritmatika interval. Ambil panjang garis dari awal hingga akhir sebagai batas bawah, dan jumlah panjang garis melalui titik kontrol sebagai batas atas. Sekali lagi, bagi lagi seperti yang dipersyaratkan oleh persyaratan kesalahan akhir Anda.

Satu biasanya dibagi lagi pada t = 0,5, tetapi algoritma de Casteljau memungkinkan pemisahan pada titik mana pun, jadi jika Anda memiliki Bézier kubik dengan titik kontrol C_0 hingga C_3 dan C_2 jauh lebih dekat dengan segmen garis antara titik akhir daripada C_1 Anda mungkin menemukan pemisahan itu pada satu dari 1/3 atau 2/3 memberikan batasan yang lebih ketat. Saya belum bekerja melalui aljabar untuk membenarkan mana yang lebih baik, tetapi Anda dapat melakukan percobaan dan melaporkan kembali jika Anda mau. Jika tidak ada yang lain, saya ingin menunjukkan bahwa opsi ada di sana.

Peter Taylor
sumber
3

Menghitung panjang kurva parametrized dapat dilakukan dengan mengambil integral dari sqrt ((dx / dt) ² + (dy / dt) ²), di mana dx / dt adalah turunan dari komponen-x dari kurva, dan / dt adalah turunan dari komponen-y dari kurva. Dalam kasus Bézier-spline, keduanya sama, karena persamaan dapat diperluas ke dimensi apa pun.

Rumus untuk Bézier-spline kubik adalah sebagai berikut: B (t) = (1 - t³) * P0 + 3 (1 - t) ²t * P1 + 3 (1 - t) t² * P2 + t³ P3 di mana P0 melalui P3 adalah titik kontrol.

Menurut Wolfram | Alpha, turunan dari rumus ini adalah: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))

Sekarang Anda dapat memasukkan ini kembali ke persamaan untuk panjang kurva, dan menghitung integral dari t = 0 ke t = 1. Sayangnya, Wolfram | Alpha time out ketika saya mencoba melakukan ini. Anda dapat melakukan integrasi numerik.

Ruud
sumber