我执行这个角度计算公式有什么问题?

What's wrong with my implementation of this angle calculation formula?

所以我需要计算出两点之间的角度,这应该是微不足道的。我在 SO 上发现了至少 5 个不同的问题。但是当我尝试多种算法时,我得到了错误的结果,所以我将布置我的设置:

首先,这部分不应该有问题,但我还是会把它列出来,因为它是过程的一部分,可能是错误的根源,但是基本上我生成了一个 0 到 360 之间的度数列表作为屏幕中心周围圆圈中像素坐标的键:

getRadialPixels(){
    centerX := 960
    centerY := 540
    distance := 250
    pixels := []
    loop, 360
    {
        Fi := A_Index * 3.14159265359 / 180
        x := Round(centerX + distance * Cos(Fi))
        y := Round(centerY + distance * Sin(Fi))
        realDegree := A_Index + 90
        if (realDegree > 360)
        {
            realDegree := realDegree - 360
        }
        pixels[realDegree] := {}
        pixels[realDegree]["x"] := x
        pixels[realDegree]["y"] := y
        ;FileAppend, % "Added coordinate [" . x . ", " . y . "] to radial list for degree " . realDegree . ".`n", Log.txt
    }
    return pixels
}

您会看到我为每个键添加 90 度,然后将其标准化为 360 度限制,因为基本上我希望 0 度位于顶部 [0,1],90 度位于顶部正确的 [1,0] 等等,添加 90 度似乎可以实现。我从别处得到了这个公式,但我测试了这个并且我 认为 它是正确的。我不认为代码是问题所在,但以防万一。

实际计算两点夹角的公式在这里:

getAngleBetweenPoints(x1, y1, x2, y2){
    angle := floor(atan2(y2 - y1, x2 - x1) * 180 / 3.14159265359)
    if (angle > 359) {
        angle := angle - 360
    }
    if (angle < 0) {
        angle := 360 - abs(angle)
    }
    return angle
}

我也试过:

angle := ceil((ACos((x1 * x2 + y1 * y2) / (Sqrt(x1**2 + y1**2) * Sqrt(x2**2 + y2**2))) * 57.2957795) * 180 / 3.14159265359)

作为旁注,我不得不将 atan2 添加到 AHK,因为它不受本机支持:

atan2(x,y) {    ; 4-quadrant atan
   Return dllcall("msvcrt\atan2","Double",y, "Double",x, "CDECL Double")
}

但这两个版本似乎都得到了不正确的结果。到目前为止。我做错了什么?

测试:

originX := 0
originY := 0

x1 := 0
y1 := 1

x2 := 1
y2 := 0

x3 := 0
y3 := -1

x4 := -1
y4 := 0

x5 := 1
y5 := 1

x6 := 1
y6 := -1

x7 := -1
y7 := -1

x8 := -1
y8 := 1

result1 := getAngleBetweenPoints(originX,originY,x1,y1) ; 0 deg
result2 := getAngleBetweenPoints(originX,originY,x2,y2) ; 89 deg
result3 := getAngleBetweenPoints(originX,originY,x3,y3) ; 179 deg
result4 := getAngleBetweenPoints(originX,originY,x4,y4) ; 270 deg
result5 := getAngleBetweenPoints(originX,originY,x5,y5) ; 44 deg
result6 := getAngleBetweenPoints(originX,originY,x6,y6) ; 134 deg
result7 := getAngleBetweenPoints(originX,originY,x7,y7) ; 225 deg
result8 := getAngleBetweenPoints(originX,originY,x8,y8) ; 315 deg

你在 atan2 的定义中交换了 x 和 y,应该是 y 在前,然后是 x:

atan2(y,x) {    ; 4-quadrant atan
   Return dllcall("msvcrt\atan2","Double",y, "Double",x, "CDECL Double")
}