7

私は、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]  

これは私が得るエラーです:

>>> 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
4

4 に答える 4

9

この例外は、cos_angleがの有効なパラメータではないことを意味しますmath.acos

具体的には、この例では、-1のすぐ下にあり、acos定義外です。

あなたはおそらく次のようなものであなたの帰国を強制しようとすることができcos_angleます[-1,1]

def clean_cos(cos_angle):
    return min(1,max(cos_angle,-1))

ただし、はあなたの例では多かれ少なかれ等しいSQUAREので、これは戻りません。したがって、はになります。例外の前の計算におそらく問題があります。cos_angle-1angle180

于 2012-11-30T01:05:28.793 に答える
1

コードを実行すると、取得するスタックトレースは次のようになります。

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

私は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.001abs(cos_angle) < 0.001

編集

この行にエラーがあると思います:

cos_angle = float((hypo**2 - (d3)**2 + (d4)**2) / ((-2.0)*(d4)*(d3)))

おそらく次のようになります。

cos_angle = float((hypo**2 - ((d3)**2 + (d4)**2)) / ((-2.0)*(d4)*(d3)))

の周りの余分な括弧に注意してください(d3)**2 + (d4)**2。これにより、からその数量を減算する前にhypo**2、加算が行われるようになります。

于 2012-11-30T00:59:43.320 に答える