Daha hızlı bir sinüs fonksiyonu var mı?


25

Nesil 3d perlin gürültüsü üzerinde çalışıyorum. C # Math kütüphanesi, ihtiyaç duyduğum şeyin gereğinden fazla olduğu gibi görünüyor, çünkü işlevlerinin çoğu çifte sapma kullanmaktadır. Gürültüyü oluşturmak için Math.Sin () 'i birkaç yerde kullanıyorum. Daha hızlı sinüs fonksiyonunu bilen var mı?

Yanıtlar:


32

Sinüs fonksiyonunun değerini onaylamak için bir parabol kullanabilirsiniz. Bu, kökleri tam olarak -pi / 2 ve pi / 2'de tutma avantajına sahiptir; bu, genellikle TaylorSeries veya MaclaurinSeries'e dayanan diğer hızlı yaklaşımlarla durum böyle değildir .

public float Sin(float x)
{
    const float B = 4 / PI;
    const float C = -4 / (PI*PI);

    return -(B * x + C * x * ((x < 0) ? -x : x));
} 

İşte gerçek sinüs fonksiyonunun bir karşılaştırması:

alt metin


3
Bu gerçekten harika bir çözüm. Devmaster.net'ten, bunun neden işe yaradığını ve bazı uygulama detaylarını verdiğini anlatan mükemmel bir makale: devmaster.net/forums/showthread.php?t=5784
reverbb 23:10

C # hakkında bilgim yok, ancak çoğu C ortamındaki abs () işlevi, optimize edildiğinde bir daldan (?: Operatörü) daha hızlı olacaktır.

3
Math.Abs ​​() çağrısını kaldırdım çünkü bu kodun Xbox 360 veya Windows Phone 7'de çalışabileceğini varsaydım. Xbox 360'taki JIT derleyicisi hiçbir şeyi satır içi yapmıyor. Math.Abs ​​() 'a yapılan çağrı aslında daha pahalıdır.
zfedoran


1
@zfedoran Neden dönüş değerini reddedersiniz? Negatif bir sinüs dalgası gibi görünüyor.
Daniel Pendergast

12

Sin () fonksiyonunuz için giriş değerleri aralığı nedir ? Ne için kullandığınıza göre, onlar sınırlı olabilir gibi geliyor, bu da değerleri önceden hesaplayabileceğiniz anlamına geliyor . Örneğin, giriş değerlerini en yakın dereceye yuvarlıyorsanız, o zaman sadece 360 ​​olası değere sahipsiniz - sadece önceden hesaplayın ve bir tabloda saklayın.

Biraz daha fazla değere ihtiyacınız varsa, bir ondalık basamağa söyleyin, tablodan enterpolasyon yapabilirsiniz - aşina değilim perlin gürültüsüne , ancak "noise" kelimesi yüksek hassasiyet gerektirmediğini gösteriyor gibi görünüyor. :) (Ayrıca, daha büyük bir tablo da yapabilirsiniz, 3600 girişler fazla alan değildir).


3
Eğer hız sizin bir numaralı endişenizse ve biraz doğruluktan ödün vermeyi düşünmüyorsanız, bu en iyi cevaptır.
AttackHobo

1
"En iyi" hakkında bir şey bilmiyorum - Başka bir cevapta gösterildiği gibi, beş ops + abs'de (hızı kemer / derleyicinize bağlı, ancak genellikle dalsızdır) çok iyi bir yaklaşım daha elde edebilirsiniz. Arama tablosu önbellekte değilse, çok daha yavaş olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.