2010-01-26 14 views
5

'da döndürülmesi işlevi Birisi bu sorunu çözmek zorunda kaldı. Bu sorunu ve nasıl çözüleceğini açıklayan harika bir web sitesi bulabilirim. Eminim ki iyi yazılmışlar ve matematiksel zekaya mantıklılar, bu ben değilim. Ve belirsiz bir şekilde anlayabildiğim halde, bu matematiği kullanabileceğim bir işleve nasıl çevireceğimi anlamıyorum.Bir Bezier eğrisindeki noktaların bir listesinin eşit arclength

Bu yüzden, bunu yapabileceğiniz bir fonksiyonunuz varsa, herhangi bir dilde (hatta fortran veya heck 6502 assembler) - lütfen bana yardım edin.

  • iteratif çözüme

DÜZENLEMEYİ analitik tercih: belirtmek demek bu onun Birlikte çalışmaya çalışıyorum kübik bezier.

cevap

3

Ne istediğinizi, ark uzunluğu işlevinin tersidir. Bu nedenle, bir eğri B verildiğinde, 0 ile 1 arasında bir t döndüren bir Linv (len) işlevi istiyorsunuz, böylece 0 ile t arasındaki eğrinin yay uzunluğu len.

Bu işleve sahip olsaydınız, sorununun çözülmesi gerçekten çok kolay. İlk nokta B (0) olsun. Bir sonraki noktayı bulmak için, basitçe B'yi (Linv (w)) hesaplamanız gerekir; burada w, sizin için kullandığınız "eşit yayılım" dır. Bir sonraki noktayı elde etmek için, Linv (n * w) 1'den büyük hale gelene kadar B (Linv (2 * w)) ve benzerlerini değerlendirin.

Son zamanlarda bu problemle başa çıkmak zorunda kaldım. Buraya gelmedim ya da birkaç çözümle karşılaştım, bunların hiçbiri benim için tatmin edici değil (ama belki senin için olacaklar).

Şimdi, bu biraz karmaşık, bu yüzden ilk önce kaynak kodunun bağlantısını vereyim: http://icedtea.classpath.org/~dlila/webrevs/perfWebrev/webrev/raw_files/new/src/share/classes/sun/java2d/pisces/Dasher.java. İstediğiniz şey, LengthIterator sınıfında. Dosyanın başka bölümlerine bakmanıza gerek yok. Başka bir dosyada tanımlanan bir dizi yöntem vardır. Onlara ulaşmak için sadece/raw_files/URL’nin sonuna kadar her şeyi kesin. Bunu böyle kullanıyorsun. Nesneyi bir eğri üzerinde başlat. Ardından eğri başlangıcından itibaren yay uzunluğu L olan bir noktanın parametresini almak için sadece bir sonraki çağrı (L) (gerçek noktayı elde etmek için deCasteljau'nun algoritmasını veya zneak'in önerisini kullanarak bu parametrede eğrinizi değerlendirin). Her sonraki sonraki (x) çağrısı, son konumunuza göre size eğri boyunca x'lik bir mesafe taşır. sonraki eğri bittiğinde negatif bir sayı verir.

Kod açıklaması: bu nedenle, B (0) ila B (t) uzunluğunun LEN (LEN'nin bilindiği) olacak şekilde bir t değerine ihtiyacım vardı. Sadece eğriyi düzleştirdim. Bu yüzden, her eğri bir çizgiye yeterince yakın olana kadar, eğriyi tekrar tekrar sıraya bölün. (Kontrol poligonunun uzunluğunu bitiş noktalarını birleştiren hattın uzunluğunu karşılaştırarak bunu test edebilirsiniz). Bu alt eğrinin uzunluğunu (controlPolyLength + endPointsSegmentLen)/2 olarak hesaplayabilirsiniz. Tüm bu uzunlukları bir akümülatöre ekleyin ve akümülatör değeri> = LEN olduğunda tekrarlamayı durdurun. Şimdi, en son alt madde C'yi arayın ve [t0, t1] alan adı olsun. Bunu istediğinizin t0 < = t < t1 olduğunu biliyorsunuz ve B (0) - B (t0) arasındaki uzunluğu biliyorsunuz - bu değeri L0t0 olarak adlandırın. Yani, şimdi C (0) ila C (t) uzunluğunun LEN-L0t0 olduğu bir t onu bulmanız gerekiyor. Bu tam olarak başladığımız sorun, ama daha küçük bir ölçekte. Yinelemeyi kullanabilirdik, ama bu korkunç bir şekilde yavaş olurdu, bunun yerine sadece C'nin çok düz bir eğri olduğu gerçeğini kullanırız. C'nin bir çizgi olduğunu ve P = C (0) + ((LEN-L0t0)/uzunluk (C)) * (C (1) -C (0)) kullanarak noktayı hesaplıyoruz. Bu nokta aslında eğri üzerinde değildir çünkü C (0) -> C (1) satırındadır, fakat istediğimiz noktaya çok yakındır. Yani, sadece Bx (t) = Px ve By (t) = Py'yu çözüyoruz. Bu sadece kapalı kaynak çözümü olan kübik kökleri bulmakta, ama ben sadece Newton yöntemini kullandım. Şimdi istediğimiz var ve gerçek nokta olan C (t) 'yi hesaplayabiliriz.

Birkaç ay önce, bunun eğrinin doğal parametreleştirilmesine bir yaklaşım getiren başka bir çözümü olan bir kağıttan geçirdiğimi belirtmeliyim. Yazar, buraya bir bağlantı gönderdi: Equidistant points across Bezier curves

+0

Bu TWO yıl önce yorum göndermediğiniz için çok üzgünüm, bu yüzden çok fazla bir şey yapmadım çünkü ünüm yok. . evet, evet) .. ama mükemmel cevap ve harika kod örneği, şimdi tamamen yanıtı gübrelemek için .... – Prozacgod

İlgili konular