Bu sayfadaki yazılar
Sayfanın metni
Sayfa 155
Fakat yukarıdaki şekilde görüldüğü gibi bu bize kesikli bir fonksiyon sağlayacak. Özellikle yavaş hareketlerde bu tabloyu kullanmak, göze bir takılma hissi verecek. Örneğin cisim yumuşak bir şekilde dönmek yerine ani atlamalarla ilerleyecek. Eğer amacımız sadece hız kazanmaksa ve yumuşaklığı kaybetmek umurumuzda değilse kullanabileceğimiz en iyi yöntem bu. Ama hem hız hem de yumuşaklık istiyorsak tablonun kullanımına ufak bir optimizasyon yapabiliriz.
İstediğimiz açının bir yanındaki tablo elemanını kullanmak yerine, her iki yanındaki bilgiyi de kullanabiliriz. Örneğin Cos(14.5) için Cos(14)+Cos(15)/2.0f demek, gerçeğine çok daha yakın sonuçlar verecekti. Yapmamız gereken tabloda iki değerin arasında sinüs ve kosinüs fonksiyonlarının doğrusal değiştiğini varsaymak. Bir açının sinüsü istendiğinde, bu açının tabloda bulunduğu aralıklardaki sınıra ne kadar yakın olduğuna bakıp ona göre bir değer hesaplamak.
Örneğin tablomuzda Sin(54) = 0.80902f ve Sin(55) = 0.81915f ve bulmak istediğimiz değer de Sin(54.7f) olsun. İlk yöntemimize göre şöyle bir sonuç alacaktık:
Sin(54.7f) = Sin(54) = 0.80902f
Eğer daha akıllı bir sistem geliştirip bir önceki değil de en yakındaki tablo değerine bakarsak:
Sin(54.7f) = Sin(55) = 0.81915f
Yeni yönteme göre ise bu iki değerden herhangi birini değil, bunların belli oranlarının toplamını kullanmamız gerekiyor. 54.7f derece, 54 dereceye 0.7f yakın, 55 dereceye ise 0.3f. Sınırların değerlerini uzaklıklarla ters orantılı olarak kullanırsak:
Sin(54.7f) = Sin(54) * 0.3f + Sin(55) * 0.7f
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 154
-Sinüs Kosinüs Tablolarında Doğrusal Geçiş-
Demolarda en çok kullanılan fonksiyonlar sinüs ve kosinüs olmalı. Scroll textlerde, obje oluşturmada, kamera yollarında hatta sıkıştırmada bile sık sık kullanılıyorlar. Ama bir değerin sinüsünü almak, bellekte bir yerden değer okumaktan çok daha uzun sürüyor. Özellikle her framede yapılacak milyonlarca sinüs işlemi varsa, örneğin bir kübü eğip bükecekseniz sinüs ve kosinüsler kodu oldukça yavaşlatıyorlar.
Ama sıklıkla sinüs hesaplamaktan kaçınmak için bazı yöntemler var. Örneğin bir şeyi sadece 10 derecelik açılarla döndürecekseniz sadece sin(10) ve cos(10) değerlerini kullanmanız yeterli. Bu değeri de FPU'ya her seferinde baştan hesaplatmamak için bir yere not edip sürekli oradan kullanabiliriz. İşimizi biraz daha kolaylaştırmak için de 10, 20, 30,... 360 olmak üzere 36 açının sinüs ve kosinüslerini bir tabloda tutabiliriz. Sadece bu açıları kullandığımız sürece hiçbir sorunumuz yok. İstediğimiz açının sinüsünü tablodaki değere bakarak anında elde edebiliriz.
Fakat her zaman işimiz bu kadar kolay olmayabilir. Örneğin yukarıdaki şekildeki gibi belli açıların değil de, tüm açıların sinüsüne ihtiyacımız olduğu zaman ne yapacağız? Sanırım bunun en kolay cevabı aradaki açılar için tabloda tuttuğumuz değerleri kullanmak. Değerini bilmediğimiz her açı için, ondan küçük ve değerini bildiğimiz ilk açıyı kullanmak ilk bakışta mantıklı gözüküyor. Örneğin her 1 derece için birer adet (yani toplamda 360 tane) sinüs ve kosinüs değerini Sin ve Cos adlı arraylerde tuttuğumuz zaman, Cos(14.5f) dediğimizde derleyici bunu float-long çevirimi ile 14 yapıp Cos(14) değerini kullanacak. Dahası
"#define Cos(a) Cos[(unsigned int)(a)%360]"
makrosu ile sadece 0 ve 360 arası değil, bunların ilerisindeki açıların sinüs ve kosinüsünü tablomuzdan çıkarabiliriz.