C 任意相移的两个正弦波的atan2?

C 任意相移的两个正弦波的atan2?,c,algorithm,math,atan2,C,Algorithm,Math,Atan2,我正在尝试实现一个类似atan2的函数,将任意相对相移的两个输入正弦信号映射为一个从0到2π的线性输出信号atan2通常假定两个信号具有90度相移 给定y0(x)=sin(x)和y1=sin(x+相位),其中phase是一个固定的非零值,我如何实现一种方法来返回x模2π?atan2返回2d向量的角度。您的代码不能正确处理这种缩放。但不用担心,实际上很容易将您的问题简化为atan2,这样可以很好地处理所有问题 请注意,计算sin(x)和sin(x+相位)与将点(cos(x),sin(x))投影到轴

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


给定
y0(x)=sin(x)
y1=sin(x+相位)
,其中
phase
是一个固定的非零值,我如何实现一种方法来返回
x
atan2
返回2d向量的角度。您的代码不能正确处理这种缩放。但不用担心,实际上很容易将您的问题简化为
atan2
,这样可以很好地处理所有问题

请注意,计算
sin(x)
sin(x+相位)
与将点
(cos(x),sin(x))
投影到轴
(0,1)
(sin(相位),cos(相位))
。这与使用这些轴获取点积,或将坐标系从标准正交基转换为倾斜基相同。这建议了一个简单的解决方案:逆变换以获得正交基中的坐标,然后使用
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
的计算并非绝对必要。可以用
fmod
copysign
替换它(我们仍然需要
u
v
的正确符号)。

派生:

// assume phase != k * pi, for any integer k
double f (double y0, double y1, double phase)
{
    double u = (- y0 * cos(phase) + y1) / sin(phase);
    double v = y0;

    double x = atan2 (v, u);
    return (x < 0) ? (x + 2 * M_PI) : x;
}

在代码中:

// assume phase != k * pi, for any integer k
double f (double y0, double y1, double phase)
{
    double u = (- y0 * cos(phase) + y1) / sin(phase);
    double v = y0;

    double x = atan2 (v, u);
    return (x < 0) ? (x + 2 * M_PI) : x;
}
//假设阶段!=k*pi,对于任意整数k
双f(双y0,双y1,双相)
{
双u=(-y0*cos(相位)+y1)/sin(相位);
双v=y0;
双x=atan2(v,u);
返回(x<0)-(x+2*M_-PI):x;
}

这是对问题的正确重述吗:给定y0和y1为sin(x)和sin(x+相位),其中相位为常数,返回x模2π?请准确重述问题,因为不清楚。atan2(y,x)作用于y和x,并计算从(0,0)和(x,y)穿过x的直线相对于x的正轴的角度,给出从-π排除到+π包含的结果。注意:
-π这似乎是一个数学问题,而不是一个编程问题。