平滑循环的周期性三角函数

Smoothly Looping Periodic Trigonometric Functions

不幸的是,我是一个新手程序员,但是一个相对有经验的数学家。

我想从事游戏开发,我想我已经差不多掌握了 OpenGL 等背后的基本线性代数数学。不幸的是,我还没有做图形模拟的技术诀窍。

作为一个初级练习,我想尝试模拟一个粒子在圆形路径中的连续运动。我使用了简单的参数化

double t=0;
double x = cos(t), y = sin(t);

我知道根据 Microsoft,double 的 运行ge 为 1.7E +/- 308。那么我的问题是,"How can I ensure the smoothest continuous circular loop of the particle?" 我认为可能会发生的问题是,如果程序 运行 足够长,随着 t 变得越来越大,我们会到达 t 将重置为最低值的点,这可能会导致粒子位置出现 "jump"。

我考虑过这个,我想知道是否有必要为 t 从 [1.7E-308, 1.7E+308) 创建一个映射 → [0 ,2π).这是否有助于防止任何位置 "jumps"?还是这样做会出现我没有预料到的问题?我的计划是以预定的速度增加 t,我还没有确定。但我看到 t 增加的速度决定了 xy 坐标变化的速度。

你多虑了。或者至少是关于错误的事情。太阳将变成红巨星并吞噬地球,远在您通过添加小增量超过两倍的最大值之前。

稍微严重一点的问题是t的绝对精度随着其量级的增加而降低。这是基于这样一个事实,即 double 的精度与其大小有关。即使这需要很长时间才能成为真正的问题,但它发生在 t 超过双倍范围之前很久。

另一个相关且更实际的问题是,cos()/sin() 实现对于较大的输入值可能会变得不太精确。您通常会在标准库或硬件中找到的高质量实现有望减少争论,所以这应该不是什么大问题。

综上所述,避免这些问题中的任何一个,尽管它们在现实中可能是遥不可及的,但非常容易,您不妨解决一下。您只需在 t 的值超过 2 * pi 后立即减少它:

t += tInc;
if (t > 2.0 * M_PI)
{
    t -= 2.0 * M_PI;
}

有了这个,值将始终保持在 0 到 2 * pi 之间。

顺便说一句:非常 与图形相关的任何事情都需要双精度应该很少见。使用 float 类型的变量和常量应该就足够了,除非你有一个非常不寻常的用例。您将使用的图形库通常会以 float 精度运行,因此在您自己的代码中使用 double 只会使用额外的内存,并导致大量类型转换。