我有一个脚本,它贯穿三角形的一组坐标,并确定它们是否是一个直角三角形。其中一部分使用了余弦规则,在检查恰好落在一行中的某组点时,我遇到了一个问题。这是造成问题的部分:
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
对这里可能出现的问题有什么想法?
答案 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。