acos

时间:2016-09-20 18:48:25

标签: python math cosine

我有一个脚本,它贯穿三角形的一组坐标,并确定它们是否是一个直角三角形。其中一部分使用了余弦规则,在检查恰好落在一行中的某组点时,我遇到了一个问题。这是造成问题的部分:

s1 = math.sqrt(((x2-x1)**2)+((y2-y1)**2))
s2 = math.sqrt(((x3-x2)**2)+((y3-y2)**2))
s3 = math.sqrt(((x3-x1)**2)+((y3-y1)**2))
num1 = (s1**2)+(s2**2)-(s3**2)
den1 = (2)*(s1)*(s2)
theta1 = math.acos(num1/den1)
num2 = (s1**2)+(s3**2)-(s2**2)
den2 = (2)*(s1)*(s3)
theta2 = math.acos(num2/den2)
num3 = (s3**2)+(s2**2)-(s1**2)
den3 = (2)*(s3)*(s2)
theta3 = math.acos(num3/den3)

当我用三个点([0,0],[4,4],[1,1])运行时,我得到以下错误:

Traceback (most recent call last):
File "./i091.py", line 79, in <module>
    detect_right_triangle(xy1, xy2, xy3)
File "./i091.py", line 50, in detect_right_triangle
    theta2 = math.acos(num2/den2)
ValueError: math domain error

为了确保我没有超出余弦函数的范围,我让它打印了所有评估点的theta2的分子和分母,并得到了这个导致问题:

***** [[0, 0], [4, 2], [1, 1]]
>>> num2 =  12.0
>>> den2 =  12.6491106407
***** [[0, 0], [4, 3], [1, 1]]
>>> num2 =  14.0
>>> den2 =  14.1421356237
***** [[0, 0], [4, 4], [1, 1]]
>>> num2 =  16.0
>>> den2 =  16.0

我认为将两个数字划分为无论出于何种原因(16.0)存在问题,但是对于第二点它在[2,2]和[3,3]上工作正常: / p>

***** [[0, 0], [2, 2], [1, 1]]
>>> num2 =  8.0
>>> den2 =  8.0

...

***** [[0, 0], [3, 3], [1, 1]]
>>> num2 =  12.0
>>> den2 =  12.0

对这里可能出现的问题有什么想法?

1 个答案:

答案 0 :(得分:1)

当我运行你的代码时:

import math

def foo(x, y):
    x1, x2, x3 = x
    y1, y2, y3 = y
    s1 = math.sqrt(((x2-x1)**2)+((y2-y1)**2))
    s2 = math.sqrt(((x3-x2)**2)+((y3-y2)**2))
    s3 = math.sqrt(((x3-x1)**2)+((y3-y1)**2))
    num1 = (s1**2)+(s2**2)-(s3**2)
    den1 = (2)*(s1)*(s2)
    theta1 = math.acos(num1/den1)
    num2 = (s1**2)+(s3**2)-(s2**2)
    den2 = (2)*(s1)*(s3)
    print repr(num2), repr(den2)
    print repr(num2 / den2)
    theta2 = math.acos(num2/den2)
    num3 = (s3**2)+(s2**2)-(s1**2)
    den3 = (2)*(s3)*(s2)
    theta3 = math.acos(num3/den3)

foo([0, 4, 1], [0, 4, 1])

我得到num2/den2 == 1.0000000000000004。除非您打印出完整的精确度,否则您可能不会注意到num2 稍微大于den2,这会导致值略大于1。显然,由于余弦的最大值为1,因此你不能使用大于的数量的arcos而不是1。