29/09/2012 - 23:20
Burada bir git Repo oluşturdum:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Kaynak dosyaları buradan zip olarak indirebilirsiniz. Ayrıca FlashDevelop kullanarak derleyebileceğiniz bir demo içerir. Demoyu kullanmak için, Flash Geliştirme'de projeyi açın ve 'Projeyi Test Et'i tıklayın. Demoyu çalıştırırken, yeni bir Bezier eğrisini ve yeni bir Circle'ı rastgele seçmek için LMB'yi tıklayın.
İyi şanslar!
Zip bağlantısını görmek zor - sadece Ctrl + F kullanın ve zip yazın. Bu kaynak birkaç haftalık yeniden arama ve programlama temsil eder, umarım beğenirsiniz.
Çerçeveyi özyinelemeli olarak bölümlere ayırmayı ve onlarla çarpışmaları kontrol etmeyi planlıyorsanız, 100.100 dizi (ızgara) oluşturmanızı ve her bir segmenti en yakın dört kareye yerleştirmenizi öneririm, böylece yalnızca 4 / 10.000 ile çarpışmaları kontrol etmeniz gerekir her kareyi keser.
Box2d'den hem bir programcı hem de bir oyun yaratıcısı olarak faydalanacağınızı düşünüyorum, çünkü hareketi biraz engebeli ve daha az sıvı gibi gösteren 'basit' bir fizik motoru yapmak için birçok gizli küçük engel var.
Eski cevap: Saf yol.
Dairenin merkezi ile eğri üzerindeki en yakın nokta arasındaki mesafeyi kontrol ederek bir dairenin Bezier eğrisi ile çarpışıp çarpışmadığını görebilirsiniz.
Mesafe denklemi (genel olarak)
açıkladı:
Bezier denklemi:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Bu, (bazı cebirlerle) toplanabilir - Okunabilirlik için atlayacağım. (X, y) (hala bir sayı değil, puanlardır)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
Noktadan (x, y) uzaklık:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Bezier üzerinde topa en yakın noktayı bulmak için, türevin sıfıra eşit olduğu tüm noktaları (kökler) bulmanız ve bulmanız gerekir. Üçüncü dereceden bir polinomdur, bu yüzden kapalı bir formül kullanabilirsiniz, ancak güvenilir olmayan olabilir, çünkü bilgisayar kayan nokta temsil kesimlerinin hassasiyeti yeterli olmayabilir. Newton'u veya bu türden bir şeyi kullanmak çok daha iyidir.
Kökleri bulmanız için gereken türev:
Varsayım: a = başlangıç b = kontrol c = son d = merkez merkez noktası
Zor kısmı bu noktaları çoğaltır, nokta ürünü kullanmanız gerekir.
İsterseniz, bunun için kod var ve burada bir çarpışma olup olmadığını ve bir çarpışma açısı varsa sadece bir boolean döndüren bir işlev şeklinde paylaşabilirsiniz. Böyle bir çarpışma motorunun naif uygulanmasında bazı problemler ortaya çıkabilir, örneğin hızlı hareket eden bir top iki eğri arasında sıkışabilir.
Şimdilik bundan kaçınmanızı öneririm, sadece x ekseni ve y ekseni için katsayıları toplayın ve ekleyin.
Kökleri bulmak için Newton gibi seçebileceğiniz güvenilir bir yöntem kullanın, çerçevedeki kök noktalardan mesafeyi kontrol edin, 0 <= t <= 1 daire merkezine ve çerçevenin iki ucu için mesafeyi kontrol edin (başlangıç ve bitiş) daire merkezine, hangisi en yakınsa, size bir çarpışma olup olmadığını söyleyecektir.
Yarıçap minimum mesafeden daha küçükse, bir çarpışma olur.
Açı, dairenin merkezi ile bezier üzerindeki en yakın nokta arasındaki açıdır.
Bununla birlikte, çarpışma fiziği ile gerçekten bir oyun yapmak istiyorsanız, sadece bezier üzerinde tekrar etmenizi öneririm
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Ortadaki her parçayı, yeterince küçük olana kadar tekrar tekrar bölün , 10 piksel veya daha az diyelim, sonra çerçeveyi kabaca kutulardan inşa edin ve fizik için Box2d'yi kullanın , çünkü tüm bu çarpışma algılama kodunun yazılmasının harika olduğunu kanıtlaması mümkündür oyun fazla geliştirmez zaman lavabo. Box2d kullanımı geçmişte sayısız projede kendini kanıtlamıştır.