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).
Jawaban:
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 .
sumber
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.
sumber
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 .
sumber
Ini dimulai sebagai komentar pada komentar pada jawaban @ bummzack, tetapi tumbuh terlalu lama.
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.
sumber
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.
sumber