Existe-t-il une fonction sinus plus rapide?


25

Je travaille sur le bruit perlin de génération 3d. La bibliothèque C # Math semble exagérée pour ce dont j'ai besoin car la plupart de ses fonctions utilisent la double percision. J'utilise Math.Sin () à plusieurs endroits pour générer du bruit. Quelqu'un connaît-il une fonction sinus plus rapide?

Réponses:


32

Vous pouvez utiliser une parabole pour approximer la valeur de la fonction sinus. Cela a l'avantage d'avoir les racines exactement à -pi / 2 et pi / 2, ce qui n'est généralement pas le cas avec d'autres approximations rapides basées sur TaylorSeries ou 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));
} 

Voici une comparaison avec la fonction sinusoïdale réelle:

texte alternatif


3
C'est en effet une excellente solution. Voici un excellent article de devmaster.net qui explique pourquoi cela fonctionne et donne quelques détails d'implémentation: devmaster.net/forums/showthread.php?t=5784
reverbb

Je ne connais pas C #, mais la fonction abs () dans la plupart des environnements C sera probablement plus rapide qu'une branche (l'opérateur?:), Lorsqu'elle est optimisée.

3
J'ai supprimé l'appel Math.Abs ​​() parce que je supposais que ce code pourrait s'exécuter sur la Xbox 360 ou Windows Phone 7. Le compilateur JIT sur Xbox 360 n'inline rien. Un appel à Math.Abs ​​() est en fait plus cher.
zfedoran


1
@zfedoran Pourquoi annulez-vous la valeur de retour? Il semble que ce soit une onde sinusoïdale négative.
Daniel Pendergast

12

Quelle est la plage de valeurs d'entrée pour votre fonction sin () ? Pour ce que vous l'utilisez, il semble qu'ils soient limités, ce qui signifie que vous pouvez pré-calculer les valeurs . Par exemple, si vous arrondissez les valeurs d'entrée au degré le plus proche, vous n'avez que 360 ​​valeurs possibles - il suffit de les pré-calculer et de les stocker dans une table.

Si vous avez besoin d'un peu plus de valeurs, disons à une décimale près, vous pouvez interpoler à partir du tableau - je ne connais pas le bruit perlin , mais le mot "bruit" semble indiquer qu'il ne nécessite pas une grande précision. :) (Vous pouvez également créer un tableau plus grand, 3600 entrées ne sont pas beaucoup d'espace).


3
Si la vitesse est votre préoccupation numéro un et que cela ne vous dérange pas de sacrifier un peu de précision, c'est la meilleure réponse.
AttackingHobo

1
Je ne sais pas "meilleur" - Comme indiqué dans une autre réponse, vous pouvez obtenir une autre très bonne approximation en cinq opérations + abs (dont la vitesse dépend de votre arch / compilateur, mais est souvent sans branche). Si la table de recherche n'est pas dans le cache, elle sera beaucoup plus lente.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.