我正在尝试实现一个类似 atan2 的函数,将任意相对相移的两个输入正弦信号映射到从 0 线性变化的单个输出信号。 atan2 通常假设两个具有 90 度相移的信号。

给定 y0(x) = sin(x)y1 = sin(x + phase) ,其中 phase 是一个固定的非零值,我该如何实现返回 x modulo 的方法?

最佳答案

atan2 返回二维 vector 的角度。您的代码无法正确处理此类缩放。但是不用担心,实际上很容易将您的问题简化为可以很好地处理所有问题的 atan2

请注意,计算 sin(x)sin(x + phase) 与将点 (cos(x), sin(x)) 投影到轴 (0, 1)(sin(phase), cos(phase)) 上相同。这与对这些轴进行点积或将坐标系从标准正交基转换为偏斜坐标系相同。这提出了一个简单的解决方案:反转变换以获得正交基中的坐标,然后使用 atan2

这是执行此操作的代码:

double super_atan2(double x0, double x1, double a0, double a1) {
    double det = sin(a0 - a1);
    double u = (x1*sin(a0) - x0*sin(a1))/det;
    double v = (x0*cos(a1) - x1*cos(a0))/det;
    return atan2(v, u);
}

double duper_atan2(double y0, double y1, double phase) {
    const double tau = 6.28318530717958647692; // https://tauday.com/
    return super_atan2(y0, y1, tau/4, tau/4 - phase);
}
super_atan2 获取两个投影轴的角度,duper_atan2 完全按照您的说明解决问题。

还要注意,det 的计算并不是绝对必要的。可以用 fmodcopysign 替换它(我们仍然需要 uv 的正确符号)。

关于c - atan2 用于两个任意相移的正弦曲线?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56048754/

10-10 02:29