[title = SNS KOSNS][b]-Siins Kosins Tablolarnda Dorusal Gei-[/b]

Demolarda en ok kullanlan fonksiyonlar sins ve kosins olmal. Scroll textlerde, obje oluturmada, kamera yollarnda hatta sktrmada bile sk sk kullanlyorlar. Ama bir deerin sinsn almak, bellekte bir yerden deer okumaktan ok daha uzun sryor. zellikle her framede yaplacak milyonlarca sins ilemi varsa, rnein bir kb eip bkecekseniz sins ve kosinsler kodu olduka yavalatyorlar. 
[img = CTR data/articles/sincos/normal.png]Ama sklkla sins hesaplamaktan kanmak iin baz yntemler var. rnein bir eyi sadece 10 derecelik alarla dndrecekseniz sadece sin(10) ve cos(10) deerlerini kullanmanz yeterli. Bu deeri de fpuya her seferinde batan hesaplatmamak iin bir yere not edip srekli oradan kullanabiliriz. imizi biraz daha kolaylatrmak iin de 10, 20, 30,... 360 olmak zere 36 ann sins ve kosinslerini bir tabloda tutabiliriz. Sadece bu alar kullandmz srece hi bir sorunumuz yok. stediimiz ann sinsn tablodaki deere bakarak annda elde edebiliriz.
[img = CTR data/articles/sincos/ayrik.png]Fakat her zaman iimiz bu kadar kolay olmayabilir. rnein yukardaki ekildeki gibi belli alarn deil de, tm alarn sinsne ihtiyacmz olduu zaman ne yapacaz? Sanrm bunun en kolay cevab aradaki alar iin tabloda tuttuumuz deerleri kullanmak. Deerini bilmediimiz her a iin, ondan kk ve deerini bildiimiz ilk ay kullanmak ilk bakta mantkl gzkyor. rnein her 1 derece iin birer adet (yani toplamda 360 tane) sins ve kosins deerini Sin ve Cos adl arraylerde tuttuumuz zaman, Cos(14.5f) dediimizde derleyici bunu float-long evirimi ile 14 yapp Cos(14) deerini kullanacak. Dahas [code]"#define Cos(a) Cos@(unsigned int)(a)%360"[/code] makrosu ile sadece 0 ve 360 aras deil, bunlarn ilerisindeki alarn sins ve kosinsn tablomuzdan karabiliriz.
[img = CTR data/articles/sincos/dikdortgen.png]Fakat yukardaki ekilde grld gibi bu bize kesikli bir fonksiyon salayacak. zellikle yava hareketlerde bu tabloyu kullanmak, gze bir taklma hissi verecek. rnein cisim yumuak bir ekilde dnmek yerine ani atlamalarla ilerleyecek. Eer amacmz sadece hz kazanmaksa ve yumuakl kaybetmek umrumuzda deilse kullanabileceimiz en iyi yntem bu. Ama hem hz hem de yumuaklk istiyorsak tablonun kullanmna ufak bir optimizasyon yapabiliriz.
[img = CTR data/articles/sincos/yamuk.png]
stediimiz ann bir yanndaki tablo elemann kullanmak yerine, her iki yanndaki bilgiyi de kullanabiliriz. rnein Cos(14.5) iin Cos(14)+Cos(15)/2.0f demek, gereine ok daha yakn sonular verecekti. Yapmamz gereken tabloda iki deerin arasnda sins ve kosins fonksiyonlarnn dorusal deitiini varsaymak. Bir ann sins istendiinde, bu ann tabloda bulunduu aralklardaki snra ne kadar yakn olduuna bakp ona gre bir deer hesaplamak.

rnein tablomuzda Sin(54) = 0.80902f ve Sin(55) = 0.81915f ve bulmak istediimiz deer de Sin(54.7f) olsun. lk yntemimize gre yle bir sonu alacaktk:

Sin(54.7f) = Sin(54) = 0.80902f

Eer daha akll bir sistem gelitirip bir nceki deil de en yakndaki tablo deerine bakarsak:

Sin(54.7f) = Sin(55) = 0.81915f

Yeni ynteme gre ise bu iki deerden herhangi birini deil, bunlarn belli oranlarnn toplamn kullanmamz gerekiyor. 54.7f derece, 54 dereceye 0.7f yakn, 55 dereceye ise 0.3f. Snrlarn deerlerini uzaklklarla ters orantl olarak kullanrsak:

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

sonucunu elde ederiz. Sin(54.7f)'in gerekteki deeri olan 0.81614f'e nceki ikisinden ok daha fazla yaklatk.

Buradaki pf noktas, sins fonksiyonunun aslnda ucubik bir ekli olmasna ramen, kk aralklarda baktmzda fonksiyonda dze yakn izgiler elde etmemiz. Evet ekil biraz bozulacak ama yumuaklk kaybolmayacak ve hareket olarak sins uyguladmzda akc grntler elde edeceiz.

imdi de bu teknii koda nasl dkeceimizi anlatalm. nceki basit tablo ynteminde ufak bir makro yeterliyken, artk yeni bir fonksiyon tanmlyorum:

[code]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 ;
}[/code]

iCeiling deeri, verilen ann hemen altndaki tamsay. fFraction ise bu sayyla arasndaki uzaklk, yani bir sonraki tamsaynn katsays. Burada stne basmamz gereken ey negatif alarda ilerin sarpa sard. Negatif % 360 ileminin sonucu negatif olaca iin tablo dna taacaz. Burada unsigned int kullanarak tamay engelledim ama negatif alar iin yanl sonular geliyor. (Aslnda fonksiyonun negatifi geliyor.) Negatif alar da kullanmak iin gereken deiiklikleri size brakyorum.

imdi bir baka soru bu dorusal tekniinin daha da gelitirilip gelitirilemeyecei olabilir. Aslnda birinci dereceden (dorusal) yerine ikinci dereceden (kuadratik) bir teknik mevcut. Sinse ok daha yakn sonular veriyor ama tabi ki daha yava. Bunu nc, drdnc diye gtrmek mmkn. Hatta fonksiyon periyodik olduu iin (yani aslnda 360 deil de sonsuz tane ann sinsn bildiimiz iin) tm sins verecek olan sonsuz dereceli bir polinom yazabiliriz. Ama o kadar yaklak deeri fpu bile vermiyor, o yzden kasmann anlam yok. :)

Bu yntem zerinde bir ka iyiletirme de yaplabilir. rnein 360 derece yerine, 180 ya da 90 derecenin iindeki alar tutabiliriz. Ya da hem kosins hem sins tablosu yerine, sadece birini tutup dierini kaydrmayla elde edebiliriz. 360 tane a yerine 256 ya da 1024 gibi yuvarlak bir say kullanp modlasyon ilemini hzlandrabiliriz (kendimiz and kullanarak tabi).

Aslnda tablo tutmadan da sinse yakn sonular hzlca elde edebilirsiniz. Ama bu dorusal birletirme ynteminin gzellii sadece trigonometrik ya da sadece periyodik fonksiyonlar deil de her eye uygulanabilmesi. rnein bir tabloya attnz splinelarla elde edilmi kamera ve obje konumlarn, hatta ksa animasyonlarn framelerini bile yumuak geilerle gsterebilirsiniz. Ya da bir objeyi dierine dntrmek iin kullanabilirsiniz. Aklnza gelebilecek her trl gei efekti ya da statik data kullanm iin ie yarayabilir.

Bu yaz burada bitiyor. Bir baka yazya kadar bol prodlu gnler dilerim.

[b]Anesthetic/Resident[/b]