Esiste una funzione seno più veloce?


25

Sto lavorando alla generazione del rumore perlin 3d. La libreria matematica C # sembra eccessiva per ciò di cui ho bisogno poiché la maggior parte delle sue funzioni usa la doppia percisione. Uso Math.Sin () in diversi punti per generare il rumore. Qualcuno sa di una funzione seno più veloce?

Risposte:


32

È possibile utilizzare una parabola per approssimare il valore della funzione seno. Questo ha il vantaggio di avere le radici esattamente a -pi / 2 e pi / 2, che di solito non è il caso di altre approssimazioni veloci basate su TaylorSeries o MaclaurinSeries .

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));
} 

Ecco un confronto con la vera funzione seno:

alt text


3
Questa è davvero un'ottima soluzione. Ecco un eccellente articolo di devmaster.net che descrive perché funziona e fornisce alcuni dettagli di implementazione: devmaster.net/forums/showthread.php?t=5784
riverbero

Non so di C #, ma la funzione abs () nella maggior parte degli ambienti C sarà probabilmente più veloce di un ramo (l'operatore?:), Se ottimizzata.

3
Ho rimosso la chiamata Math.Abs ​​() perché ho presupposto che questo codice potesse essere eseguito su Xbox 360 o Windows Phone 7. Il compilatore JIT su Xbox 360 non incorpora nulla. Una chiamata a Math.Abs ​​() è in realtà più costosa.
zfedoran,

Il link @reverbb è 404. Ecco una copia cache.
Daniel Pendergast,

1
@zfedoran Perché annulli il valore di ritorno? Sembra essere un'onda sinusoidale negativa.
Daniel Pendergast,

12

Qual è la gamma di valori di input per il tuo sin () ? Per quello per cui lo stai usando, sembra che potrebbero essere limitati, il che significa che potresti pre-calcolare i valori . Ad esempio, se si arrotondano i valori di input al grado più vicino, si hanno solo 360 possibili valori: basta pre-calcolarli e archiviarli in una tabella.

Se hai bisogno di un po 'più di valori, diciamo con una cifra decimale, potresti interpolare dalla tabella - non ho familiarità con il rumore perlin , ma la parola "rumore" sembra indicare che non richiede alta precisione. :) (Potresti anche solo creare una tabella più grande, 3600 voci non sono molto spazio).


3
Se la velocità è la tua preoccupazione numero uno e non ti dispiace sacrificare un po 'di precisione, questa è la risposta migliore.
AttackingHobo,

1
Non so di "migliore" - Come mostrato in un'altra risposta, puoi ottenere un'altra approssimazione molto buona in cinque operazioni + abs (la cui velocità dipende dal tuo arco / compilatore, ma è spesso senza rami). Se la tabella di ricerca non è nella cache, sarà molto più lenta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.