当前位置: 首页 > 知识库问答 >
问题:

如何计算随时间变化的正弦波

尚俊楠
2023-03-14

用例是为数字合成产生正弦波,因此,我们需要计算sin(d t)的所有值,其中:

幼稚的实现方式是:

double next()
{
    t++;
    return sin( ((double) t) * (d) );
}

但是,问题是当t增加时,精度会降低,因为给“sin”函数提供了大量的数字。

改进的版本如下:

double next()
{
    d_sum += d;
    if (d_sum >= (M_PI*2)) d_sum -= (M_PI*2);

    return sin(d_sum);
}
#include <stdio.h>
#include <math.h>

#define TEST      (300000006.7846112)
#define TEST_MOD  (0.0463259891528704262050786960234519968548937998410258872449766)
#define SIN_TEST  (0.0463094209176730795999323058165987662490610492247070175523420)

int main()
{
    double a = sin(TEST);
    double b = sin(TEST_MOD);

    printf("a=%0.20f \n" , a);
    printf("diff=%0.20f \n" , a - SIN_TEST);
    printf("b=%0.20f \n" , b);
    printf("diff=%0.20f \n" , b - SIN_TEST);
    return 0;
}

输出:

a=0.04630944601888796475
diff=0.00000002510121488442
b=0.04630942091767308033
diff=0.00000000000000000000

共有1个答案

方宜
2023-03-14

您可以尝试使用的一种方法是快速傅立叶变换的一些实现。三角函数的值是根据前值和delta计算的。

Sin(A + d) = Sin(A) * Cos(d) + Cos(A) * Sin(d)

在这里,我们还必须存储和更新余弦值,并存储常数(对于给定的delta)因子Cos(d)和Sin(d)。

现在关于精度:小d的余弦(d)非常接近1,因此存在精度损失的风险(像0.99999987这样的数字中只有很少的有效数字)。为了克服这个问题,我们可以将常数因子存储为

dc = Cos(d) - 1 =  - 2 * Sin(d/2)^2
ds = Sin(d) 
ts = sa //remember last values
tc = ca
sa = sa * dc + ca * ds
ca = ca * dc - ts * ds
sa = sa + ts
ca = ca + tc

附注。一些FFT实现周期性地(每K步)通过触发器更新SACA值。函数,以避免错误累积。

示例结果。双倍计算。

d=0.000125
800000000 iterations
finish angle 100000 radians

                             cos               sin
described method       -0.99936080743598  0.03574879796994 
Cos,Sin(100000)         -0.99936080743821  0.03574879797202
windows Calc           -0.9993608074382124518911354141448 
                            0.03574879797201650931647050069581           
 类似资料:
  • 我正在做一个自上而下的视图游戏,在游戏中敌人向特定的位置移动。被移动的目的地经常会发生剧烈的变化--有时敌人还在向前一个目的地移动的时候…… 我想要实现比直线移动更真实的移动,所以当敌人在目的地之间切换时,应该有一些加速和减速。 转向(方向)不是一个因素。你可能会认为sprites会像气垫船一样移动,在目的地之间以最快的速度进行加速和减速。 最后一个考虑是,敌人不仅有一个“最大速度”值,而且还有一

  • 问题内容: 我有两个标准化张量,我需要计算这些张量之间的余弦相似度。如何使用TensorFlow做到这一点? 问题答案: 这将完成工作: 此打印

  • 我写了一个小函数,它给出了一个基于正弦波的值,当我在0到1之间放一个浮点数时。我用它在游戏中把东西弄得乱七八糟。 它很好用..但我想知道有没有一种数学方法来改变正弦波,这样我就可以让它在中间变得“陡峭”或“浅”?在下面的图中,蓝色曲线是正弦波,我想知道我是否可以让它更像绿线。

  • 我已经通过谷歌和堆栈溢出搜索,但我没有找到一个关于如何计算时间复杂度的清晰而直接的解释。 说代码像下面这样简单: 说一个像下面这样的循环: 这将只执行一次。 时间实际上被计算为而不是声明。

  • 我在考虑换硬币时想到了以下问题,但我不知道一个有效的(伪多项式时间)算法来解决它。我想知道是否有任何伪多项式时间的解决方案,或者一些经典的文献,我遗漏了。 硬币变化问题有一个著名的伪多项式时间动态规划解决方案,它问以下问题: 取硬币仅此,将此硬币指定为具有值 取硬币仅此,将此硬币指定为具有值 取硬币和,将其赋值为具有值和,或和,它们分别被认为是相同的方式 取硬币,和,并将其赋值为具有值,和 我遇到