有更快的正弦功能吗?


25

我正在研究3D Perlin噪声。C#数学库似乎对我需要的东西来说是过高的,因为它的大多数功能都使用双精度。我在多个地方使用Math.Sin()来产生噪声。有谁知道更快的正弦函数?

Answers:


32

您可以使用抛物线来接近正弦函数的值。这样做的优点是,根的精确位置为-pi / 2和pi / 2,而对于其他基于TaylorSeriesMaclaurinSeries的快速近似方法,通常不是如此。

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

这是与实际正弦函数的比较:

替代文字


3
这确实是一个很好的解决方案。这是来自devmaster.net的出色文章,描述了它为何起作用并提供了一些实现细节:devmaster.net/forums/showthread.php?t=5784
reverbb 2010年

我不了解C#,但是在优化后,大多数C环境中的abs()函数可能比分支(?:运算符)要快。

3
我删除了Math.Abs​​()调用,因为我假设此代码可能在Xbox 360或Windows Phone 7上运行。Xbox 360上的JIT编译器不内联任何内容。调用Math.Abs​​()实际上更昂贵。
zfedoran 2010年


1
@zfedoran为什么要否定返回值?它似乎是负正弦波。
Daniel Pendergast 2015年

12

sin()函数的输入值范围是多少?对于您用于它的用途,听起来好像它们受到限制,这意味着您可以预先计算这些值。例如,如果您将输入值四舍五入到最接近的程度,那么您只有360个可能的值-只需预先计算它们并存储在表中即可。

如果您需要更多的值(例如,保留一位小数),则可以从表格中进行插值-我对perlin噪声不熟悉,但是“ noise”一词似乎表明它不需要很高的精度。:)(您也可以只做一个更大的表,3600个条目空间不大)。


3
如果速度是您的第一要务,并且您不介意牺牲一点准确性,那么这就是最佳答案。
AttackingHobo 2010年

1
我不知道“最佳”-如另一个答案所示,您可以在五个ops + abs中获得另一个非常好的近似值(速度取决于您的arch /编译器,但通常是无分支的)。如果查找表不在高速缓存中,它将变慢得多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.