我写了一个名为的函数analyze_the_shape,它接受一个2D顶点列表,使得列表按照2D欧几里德空间中顶点的顺时针遍历顺序排列.
我在解释器中调用它并给出[(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)]输入但是我得到了ValueError : math domain error.我希望看到return ["SQUARE", 4.0].我能做什么 ?
import math
def analyze_the_shape(liste):
if len(liste) == 2 :
d = ( (liste[1][0] - liste[0][0])**2 + (liste[1][1] - liste[0][1])**2 )**(0.5)
return ["LINESEGMENT", d ]
if len(liste) == 4 :
d1 = abs(( (liste[1][0] - liste[0][0])**2 + (liste[1][1] - liste[0][1])**2 )**(0.5))
d2 = abs(( (liste[2][0] - liste[1][0])**2 + (liste[2][1] - liste[1][1])**2 )**(0.5))
d3 = abs(( (liste[3][0] - liste[2][0])**2 + (liste[3][1] - liste[2][1])**2 )**(0.5))
d4 = abs(( (liste[0][0] - liste[3][0])**2 + (liste[0][1] - liste[3][1])**2 )**(0.5))
hypo = abs(( (liste[2][1] - liste[0][1])**2 + (liste[2][0] - liste[0][0])**2 )**(0.5))
cos_angle = float((hypo**2 - (d3)**2 + (d4)**2) / ((-2.0)*(d4)*(d3)))
angle = math.degrees(math.acos(cos_angle))
if d1 == d2 == d3 == d4 and abs(angle - 90.0) < 0.001 :
return ["SQUARE", d1]
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
>>> import a
>>> a.analyze_the_shape([(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 15, in analyze_the_shape
ValueError: math domain error
Run Code Online (Sandbox Code Playgroud)
此异常意味着它cos_angle不是有效参数math.acos.
具体来说,在这个例子中,它刚好低于-1,这超出了acos定义.
您可能会尝试强制退回cos_angle内部[-1,1],例如:
def clean_cos(cos_angle):
return min(1,max(cos_angle,-1))
Run Code Online (Sandbox Code Playgroud)
但是,这不会返回SQUARE,因为在您的示例中cos_angle或多或少等于-1,angle因此等于180.在异常之前计算可能存在问题.
当我运行你的代码时,我得到的堆栈跟踪是:
Traceback (most recent call last):
File "md.py", line 22, in <module>
analyze_the_shape([(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)])
File "md.py", line 18, in analyze_the_shape
angle = math.degrees(math.acos(cos_angle))
ValueError: math domain error
Run Code Online (Sandbox Code Playgroud)
我知道math.acos只接受这样的值-1.0 <= x <= 1.0。cos_angle < -1.0如果我在该行之前打印出来angle = math.degrees(math.acos(cos_angle)),它就会打印出来True。如果我打印出来cos_angle,它就会打印出来-1.0。
我猜这里的问题是 Python 存储的方式cos_angle并不完美,并且您生成的值cos_angle仅略小于-1.0.
abs(angle - 90.0) < 0.001如果您不检查 ,而是检查 if ,也许会更好abs(cos_angle) < 0.001。
编辑:
我认为你在这一行有一个错误:
cos_angle = float((hypo**2 - (d3)**2 + (d4)**2) / ((-2.0)*(d4)*(d3)))
Run Code Online (Sandbox Code Playgroud)
大概应该是:
cos_angle = float((hypo**2 - ((d3)**2 + (d4)**2)) / ((-2.0)*(d4)*(d3)))
Run Code Online (Sandbox Code Playgroud)
请注意 周围多余的括号(d3)**2 + (d4)**2。这可确保在从 中减去该数量之前hypo**2完成加法。