我可以得到下面这个Python代码的澄清吗?

2024-09-19 23:28:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python的初学者,我正在尝试使用Python代码计算下图的角度(-26.6和18.4),以及其他正方形的角度

Angle range

我已经找到了下面的代码,我正在努力很好地理解。这怎么行?请澄清一下

Python代码:

def computeDegree(a,b,c):
    babc = (a[0]-b[0])*(c[0]-b[0])+(a[1]-b[1])*(c[1]-b[1])

    norm_ba = math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
    norm_bc = math.sqrt((c[0]-b[0])**2 + (c[1]-b[1])**2)
    norm_babc = norm_ba * norm_bc

    radian = math.acos(babc/norm_babc)
    degree = math.degrees(radian)
    return round(degree, 1)

def funcAngle(p, s, sn):
    a = (s[0]-p[0], s[1]-p[1])
    b = (sn[0]-p[0], sn[1]-p[1])
    c = a[0] * b[1] - a[1] * b[0]

    if p != sn:
        d = computeDegree(s, p, sn)
    else:
        d = 0

    if c > 0:
        result = d
    elif c < 0:
        result = -d
    elif c == 0:
        result = 0
    return result

p = (1,4)
s = (2,2)
listSn= ((1,2),(2,3),(3,2),(2,1))

for sn in listSn:
    func(p,s,sn)

结果

我希望得到图片中的角度,如-26.6,18.4


Tags: 代码normreturndefmathsqrtresult角度
2条回答

本质上,这使用点积的定义来求解角度。你可以在this link阅读更多信息(也是我发现这些图片的地方)

Vector Graph

要求解角度,首先需要将3个输入点转换为两个向量

# Vector from b to a
# BA = (a[0] - b[0], a[1] - b[1])
BA = a - b

# Vector from b to c
# BC = (a[0] - c[0], a[1] - c[1])
BC = c - b

Dot Product Formulas

使用这两个向量,你可以通过首先用第二个公式求出点积的值来求出它们之间的角度

# babc = (a[0]-b[0])*(c[0]-b[0])+(a[1]-b[1])*(c[1]-b[1])
dot_product = BA[0] * BC[0] + BA[1] * BC[1]

然后通过返回第一个定义,您可以划分两个输入向量的长度,所得值应该是向量之间角度的余弦。使用数组表示法可能很难理解,但它只是使用毕达哥拉斯定理

# Length/magnitude of vector BA
# norm_ba = math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
length_ba = math.sqrt(BA[0]**2 + BA[1]**2)

# Length/magnitude of vector BC
# norm_bc = math.sqrt((c[0]-b[0])**2 + (c[1]-b[1])**2)
length_bc = math.sqrt(BC[0]**2 + BC[1]**2)

# Then using acos (essentially inverse of cosine), you can get the angle
# radian = math.acos(babc/norm_babc)
angle = Math.acos(dot_product / (length_ba * length_bc))

大多数其他东西只是用来捕捉程序可能意外尝试除以零的情况。希望这有助于解释为什么它看起来如此

编辑:我回答这个问题是因为我很无聊,没有看到解释代码背后的数学原理有什么害处,但是在将来尽量避免问类似“这个代码是如何工作的”这样的问题

让我们从funcAngle开始,因为它稍后调用computeDegree

它做的第一件事是将a定义为两项元组。这段代码中的很多似乎使用了两个项元组,其中两个部分由v[0]v[1]或类似引用。这些几乎可以肯定是某种二维向量

我将把这些写为𝐯 对于向量和vₓ 及vᵧ 因为它们可能是两个组成部分。 [不要太仔细地看第二个下标,它完全是y而不是gamma…]

asp之间的向量差:即

a = (s[0]-p[0], s[1]-p[1])

是一个ₓ=sₓ-Pₓ 和ᵧ=sᵧ-Pᵧ; 或者只是𝐚=𝐬-𝐩 在向量中

b = (sn[0]-p[0], sn[1]-p[1])

再次;𝐛=𝐬𝐧-𝐩

c = a[0] * b[1] - a[1] * b[0]

c=aₓBᵧ-A.ᵧBₓ; c是𝐚 和𝐛 (这只是一个数字)

if p != sn:
    d = computeDegree(s, p, sn)
else:
    d = 0

我倒过来看:如果𝐩 和𝐬𝐧 如果它们是相同的,那么我们已经知道它们之间的角度是零(而且算法可能会严重失败),所以不要计算它。否则,计算角度(我们将在后面讨论)

if c > 0:
    result = d
elif c < 0:
    result = -d
elif c == 0:
    result = 0

如果c指向法线方向(通过左手法则?右手法则?记不起来),这很好:如果不是,我们需要否定角度,显然

return result

把我们刚算出的数字传给其他代码

您可能可以通过添加以下内容来调用此代码:

print (funcangle((1,0),(0,1),(2,2))

最后,运行它。(尚未实际测试这些数字)


这个函数算出a和b,得到c;如果角度指向错误的方向,所有这些都只是为了抵消角度。这些变量实际上都没有传递给computeDegree

因此,computeDegree():

def computeDegree(a,b,c):

首先要注意的是,以前的变量已经重命名funcAngle传递了s、p和sn,但现在它们被称为a、b和c。它们被传递的顺序和它们被传递到funcAngle的顺序不一样,这是令人讨厌和困惑的

babc = (a[0]-b[0])*(c[0]-b[0])+(a[1]-b[1])*(c[1]-b[1])

babc=(a)ₓ-Bₓ)(c)ₓ-Bₓ)+(一)ᵧ-Bᵧ)(c)ᵧ-Bᵧ)

如果𝐚' 和𝐜' 是𝐚-𝐛 和𝐜-𝐛 这分别是公正的

a'ₓc'ₓ+a'ᵧc'ᵧ, 或的点积𝐚' 和𝐜'.

norm_ba = math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
norm_bc = math.sqrt((c[0]-b[0])**2 + (c[1]-b[1])**2)

norm_ba=√[(a)ₓ-Bₓ)²+(a)ᵧ-Bᵧ)²](和norm_bc同样)

这看起来像是斜边的长度𝐚' (及𝐜' (分别)

norm_babc = norm_ba * norm_bc

然后我们把它们相乘

radian = math.acos(babc/norm_babc)

我们使用反余弦(反余弦,cos^-1)函数,以相乘斜边的长度作为斜边,点积作为相邻长度

degree = math.degrees(radian)
return round(degree, 1)

但这是弧度,所以我们转换成度,并将其四舍五入以获得良好的格式


好的,现在是数学,而不是Python,但这仍然不是很容易理解

(旁注:这就是为什么描述性变量名和文档是每个人的朋友!)

相关问题 更多 >