math.acos acos范围内的数学域错误
math.acos math domain error within the range of acos
我有一个脚本可以 运行 通过一组三角形的坐标来确定它们是否是直角三角形。其中一部分使用了余弦规则,我在检查恰好落在一条直线上的一组特定点时遇到了一个问题。这是导致问题的部分:
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] 上效果很好:
***** [[0, 0], [2, 2], [1, 1]]
>>> num2 = 8.0
>>> den2 = 8.0
...
***** [[0, 0], [3, 3], [1, 1]]
>>> num2 = 12.0
>>> den2 = 12.0
想知道这里可能出了什么问题吗?
当我运行你的代码:
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,所以你不能取比 1 大的数的 arcos。
我有一个脚本可以 运行 通过一组三角形的坐标来确定它们是否是直角三角形。其中一部分使用了余弦规则,我在检查恰好落在一条直线上的一组特定点时遇到了一个问题。这是导致问题的部分:
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] 上效果很好:
***** [[0, 0], [2, 2], [1, 1]]
>>> num2 = 8.0
>>> den2 = 8.0
...
***** [[0, 0], [3, 3], [1, 1]]
>>> num2 = 12.0
>>> den2 = 12.0
想知道这里可能出了什么问题吗?
当我运行你的代码:
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,所以你不能取比 1 大的数的 arcos。