atan2返回2d向量的角度。您的代码无法正确处理此类缩放。但是不用担心,将问题简化为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);
}
Run Code Online (Sandbox Code Playgroud)
super_atan2获取两个投影轴的角度,duper_atan2完全按照您所说的解决问题。
另请注意,的计算det并非严格必要。它可以通过替换它fmod和copysign(我们仍然需要的正确的符号u和v)。