Plazma sayı 2, sayfa 156

Bu sayfadaki yazılar

Sayfanın metni

Sayfa 156

Sin(54.7f) = 0.80902f * 0.3f + 0.81915f * 0.7f

Sin(54.7f) = 0.81611f sonucunu elde ederiz. Sin(54.7f)'in gerçekteki değeri olan 0.81614f'e önceki ikisinden çok daha fazla yaklaştık.

Buradaki püf noktası, sinüs fonksiyonunun aslında kübik bir şekli olmasına rağmen, küçük aralıklarda baktığımızda fonksiyonda düze yakın çizgiler elde etmemiz. Evet şekil biraz bozulacak ama yumuşaklık kaybolmayacak ve hareket olarak sinüs uyguladığımızda akıcı görüntüler elde edeceğiz.

Şimdi de bu tekniği koda nasıl dökeceğimizi anlatalım. Önceki basit tablo yönteminde ufak bir makro yeterliyken, artık yeni bir fonksiyon tanımlıyorum:

float sine (float fAngle) { unsigned int iCeiling = (unsigned int)fAngle ; float fFraction = fAngle - iCeiling ;

return Sin(iCeiling % 360) * (1.0f - fFraction) + Sin(iCeiling + 1) % 360) * fFraction ; } iCeiling değeri, verilen açının hemen altındaki tamsayı. fFraction ise bu sayıyla arasındaki uzaklık, yani bir sonraki tamsayının katsayısı. Burada üstüne basmamız gereken şey negatif açılarda işlerin sarpa sardığı. Negatif % 360 işleminin sonucu negatif olacağı için tablo dışına taşacağız. Burada unsigned int kullanarak taşmayı engelledim ama negatif açılar için yanlış sonuçlar geliyor. (Aslında fonksiyonun negatifi geliyor.) Negatif açıları da kullanmak için gereken değişiklikleri size bırakıyorum.

Şimdi bir başka soru bu doğrusal tekniğinin daha da geliştirilip geliştirilemeyeceği olabilir. Aslında birinci dereceden (doğrusal) yerine ikinci dereceden (kuadratik) bir teknik mevcut. Sinüse çok daha yakın sonuçlar veriyor ama tabii ki daha yavaş. Bunu üçüncü, dördüncü diye götürmek mümkün. Hatta fonksiyon periyodik olduğu için (yani aslında 360 değil de sonsuz tane açının sinüsünü bildiğimiz için) tüm sinüsü verecek olan sonsuz dereceli bir polinom yazabiliriz. Ama o kadar yaklaşık değeri FPU bile vermiyor, o yüzden kasmanın anlamı yok. :)

Bu yöntem üzerinde birkaç iyileştirme de yapılabilir. Örneğin 360 derece yerine, 180 ya da 90 derecenin içindeki açıları tutabiliriz. Ya da hem kosinüs hem sinüs tablosu yerine, sadece birini tutup diğerini kaydırmayla elde edebiliriz. 360 tane açı yerine 256 ya da 1024 gibi yuvarlak bir sayı kullanıp modülasyon işlemini hızlandırabiliriz (kendimiz AND kullanarak tabii).

Aslında tablo tutmadan da sinüse yakın sonuçları hızlıca elde edebilirsiniz. Ama bu doğrusal birleştirme yönteminin güzelliği sadece trigonometrik ya da sadece periyodik fonksiyonlar değil de her şeye uygulanabilmesi. Örneğin bir tabloya attığınız splinelarla elde edilmiş kamera ve obje konumlarını, hatta kısa animasyonların framelerini bile yumuşak geçişlerle gösterebilirsiniz. Ya da bir objeyi diğerine dönüştürmek için kullanabilirsiniz. Aklınıza gelebilecek her türlü geçiş efekti ya da statik data kullanımı için işe yarayabilir.

Bu yazı burada bitiyor. Bir başka yazıya kadar bol prodlu günler dilerim.

Anesthetic/Resident

Klavyeyle gezinmek için ← ve → tuşları.