Bir yolun uzunluğu nasıl belirlenir?


11

Her oyuncunun belirli bir yol boyunca hareket etmesini gerektiren bir oyunum var. Bézier eğrilerini kullanarak yolu çiziyorum. Yolun toplam gerçek (doğrusal olmayan) uzunluğunu ve her bir oyuncunun kat ettiği mesafeyi nasıl belirleyebilirim ? (Başlangıç ​​noktası ile yolda belirtilen bir nokta arasındaki mesafe.)

GÜNCELLEME:

Yol, Kartezyen bir düzlemde (2D) temsil edilir.


Yanıtlar:


7

Önceki cevapların söylediği gibi, bir Bezier eğrisinin uzunluğunu hesaplamak zordur ( imkansız ?). Oyunların% 100'ünün uzunluğun yaklaşık bir oranını kullandığını söyleyebilirim, ki bu hemen hemen her zaman yeterince doğrudur.

Birkaç ay önce eğriyi "küçük" segmentlere ayırma ve uzunluklarını ekleme önerisini kullanarak uyguladım. Burada bir C ++ uygulaması örneği var .


11

Bir Bezier eğrisinin uzunluğunu ölçmek zordur. Hafif bir yanlışlık sakıncası yoksa, basit bir çözüm, Bezier eğrilerini düz çizgilerle yaklaşıklaştırmak ve çizgi uzunluklarının toplamını hesaplamak olacaktır. Ne kadar çok segment oluşturursanız, yaklaşım o kadar iyi olur.


Bunu düşünebilirim, ancak kaç segmente sahip olmam gerektiğini nasıl belirleyebilirim ve segmentleri yolumda başlangıç ​​ve bitiş noktaları olacak şekilde nasıl eşleyebilirim? Bu tekniğin bir adı var mı? (Google'da
ararım

Basit bir yaklaşım, B (0) ' dan B (1)' e noktaların doğrusal bir dağılımını kullanmak olacaktır ... eğriyi çizmek için kullanacağınız bir şey gibi. Dan'ın cevabındaki kaynak koduna bakın.
bummzack

Aşağı cevabın bir açıklamasını takdir ediyorum, sadece
cevabımda

7

Daha yüksek mertebeden (yani 1. mertebeden daha büyük) kama uzunluğu parametrelendirmesi yaklaşık olarak yapılmalıdır; doğrudan temsil edilemez, bu nedenle buna doğrudan çözümler bulmak kolay değildir.

Bazı mevcut uygulamalar (kopyala-yapıştır kodu):

Yazarlara göre Chebyshev yaklaşımlarını kullanarak , eğri boyutu arttıkça doğruluk artar. S. 7-8 sözde koduna bakın, geri kalanı görmezden gelebileceğiniz yaklaşımlarını temel aldıkları diğer algoritmaların bir açıklamasıdır. Bazı çevrimiçi referanslar bu yönteme iyi bir yöntem olarak atıfta bulunur.

Ayrıca bu kısa yaklaşımlara bakınız.


5

Bu, @ bummzack'in cevabına yapılan yorum hakkında yorum olarak başladı, ancak çok uzun büyüdü.

kaç segmente sahip olmam gerektiğini nasıl belirleyebilirim

İki yaklaşım vardır. Birincisi sadece bir Bézier eğrisi oluşturmak için standart algoritmadır: kontrol noktaları eğrinin sınırlayıcı bir kutusunu oluşturur, bu nedenle kontrol noktalarının tümü başlangıç ​​noktasından bitiş noktasına kadar çizgi segmentinin epsilonundaysa, bir çizgi olarak yaklaşık olarak; aksi takdirde de Casteljau algoritmasını kullanarak alt bölümlere ayırırsınız. Epsilon, nihai sonuçta istediğiniz hataya göre seçilir. (Oluşturmak için genellikle 0,5 pikseldir).

Diğer yaklaşım aralık aritmetiği kullanılarak yapılanı geliştirmektir. Çizginin uzunluğunu alt sınır olarak baştan sona ve kontrol noktalarından üst sınır olarak çizgilerin uzunluklarının toplamını alın. Yine, son hata gereksinimlerinizin gerektirdiği şekilde alt bölümlere ayırın.

Bir tanesi normalde t = 0.5'e bölünür, ancak de Casteljau'nun algoritması herhangi bir noktada bölünmeye izin verir, bu nedenle kontrol noktaları C_0 ila C_3 ve C_2 olan bir kübik Bézier'iniz varsa, bitiş noktaları arasındaki çizgi segmentinin C_1'den çok daha yakın olduğunu görebilirsiniz. 1/3 veya 2/3'ten biri daha sıkı sınırlar verir. Hangisinin daha iyi olacağını gerekçelendirmek için cebirde çalışmadım, ancak isterseniz deneyebilir ve geri bildirebilirsiniz. Başka bir şey yoksa, seçeneğin orada olduğunu belirtmek istedim.


3

Parametreli bir eğrinin uzunluğunun hesaplanması, drt / dt eğrinin x bileşeninin türevi olan sqrt ((dx / dt) ² + (dy / dt) ²) integrali alınarak yapılabilir. / dt eğrinin y bileşeninin türevidir. Bir Bézier-spline durumunda, bu ikisi aynıdır, çünkü denklem herhangi bir boyuta genişletilebilir.

Kübik bir Bézier-spline formülü aşağıdaki gibidir: B (t) = (1 - t³) * P0 + 3 (1 - t) ²t * P1 + 3 (1 - t) t² * P2 + t³ P3 burada P0 P3 ila kontrol noktalarıdır.

Wolfram | Alpha'ya göre, bu formülün türevi: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))

Şimdi bunu bir eğrinin uzunluğu için denkleme geri koyabilir ve integrali t = 0'dan t = 1'e hesaplayabilirsiniz. Ne yazık ki, Wolfram | Alpha bunu yapmaya çalıştığımda zaman aşımına uğruyor. Bununla birlikte, sayısal entegrasyon yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.