我需要一个函数来随着时间的推移无限地为正弦波设置动画。正弦波向左移动。
我的正弦波是使用以下等式构建的:
A * sin(B * x + C) + D
现在要为正弦波设置动画,好像它向左移动一样,每次刷新屏幕时,我只需将C增加1。现在这一切都很好,花花公子几分钟,但我需要让这个动画运行几个小时。我不能永远只有60次整数构建。有人怎么处理这个?我是否只是尝试找到正弦波超过0的点,然后从0重新开始动画?
我只需要解释这样的逻辑。
编辑#1 我忘了提到我的正弦中有一个随机组件。正弦不是连续不变的。 A和D是此刻与该整数相关的正弦函数。正弦需要以不同的周期和幅度随机看。
编辑#2
已编辑,请参阅编辑3
编辑#3
@Potatoswatter我尝试实施你的技术,但我不认为我得到它。这就是我得到的:
static double i = 0;
i = i + (MPI / 2);
if ( i >= 800 * (MPI / 2) ) i -= 800 * (MPI / 2);
for (k = 0; k < 800; ++k)
{
double A1 = 145 * sin((rand1 * (k - 400) + i) / 300) + rand3; // Amplitude
double A2 = 100 * sin((rand2 * (k - 400) + i) / 300) + rand2; // Amplitude
double A3 = 168 * sin((rand3 * (k - 400) + i) / 300) + rand1; // Amplitude
double B1 = 3 + rand1 + (sin((rand3 * k) * i) / (500 * rand1)); // Period
double B2 = 3 + rand2 + (sin((rand2 * k) * i) / 500); // Period
double B3 = 3 + rand3 + (sin((rand1 * k) * i) / (500 * rand3)); // Period
double x = k; // Current x
double C1 = 10 * i; // X axis move
double C2 = 11 * i; // X axis move
double C3 = 12 * i; // X axis move
double D1 = rand1 + sin(rand1 * x / 600) * 4; // Y axis move
double D2 = rand2 + sin(rand2 * x / 500) * 4; // Y axis move
double D3 = rand3 + cos(rand3 * x / 400) * 4; // Y axis move
sine1[k] = (double)A1 * sin((B1 * x + C1) / 400) + D1;
sine2[k] = (double)A2 * sin((B2 * x + C2) / 300) + D2 + 100;
sine3[k] = (double)A3 * cos((B3 * x + C3) / 500) + D3 + 50;
}
如何修改它以使其有效?
HALP!
答案 0 :(得分:2)
对于任何sin(x) = sin(x + 2 * M_PI)
,正弦的周期为2 pi,意味着x
。
因此,您可以通过C
增加pi/n
,其中n
是任何整数,当您刷新屏幕时,在2n
刷新后,重置{ {1}}(至C
,或其他)。
为了清晰起见进行编辑:整数0
并不意味着随时间变化。
相反,选择一些n
,例如,让我们说n
。现在,每一帧,n = 10
增加x
。在pi / 10
帧后,您将20
增加了x
。自20 * pi / 10 = 2 * pi
起,您也可以将sin(x + 2 * pi) = sin(x)
输入重置为sin(...)
,然后重新开始此过程。
答案 1 :(得分:0)
sin
是周期性的,周期为2π。因此,如果参数大于2π,您可以从中减去2 * M_PI
并获得相同的答案。
使用三个变量k
而不是使用单个变量double k1, k2, k3
计算所有不同速度的波,而是将它们绑定在0到2π的范围内。
if ( k2 >= 2 * M_PI ) k2 -= 2 * M_PI;
可以通过在每个帧中添加一些值来单独更新它们。如果增量可能超过2π,则减去单个2π不会将它们带回范围,但您可以使用fmod()
代替。
答案 2 :(得分:0)
我决定改变我的行动方针。我只是用系统的单调时钟驱动i
,如下所示:
struct timespec spec;
int ms;
time_t s;
static unsigned long long etime = 0;
clock_gettime(CLOCK_MONOTONIC, &spec);
s = spec.tv_sec;
ms = spec.tv_nsec / 10000000;
etime = concatenate((long)s, ms);
然后我只是在我的正弦方程中将i
更改为etime
。这是我用于此目的的连接函数:
unsigned concatenate(unsigned x, unsigned y) {
x = x * 100;
return x + y;
}