math.acos math domain error within the range of acos
<p>I've got a script that runs through a set of coordinates for triangles and determines whether or not they're a right triangle.  Part of this uses the cosine rule, and I've come across a problem when checking a certain set of points that happen to fall in a line.  Here's the part that is causing problems:</p>

<pre><code>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)
</code></pre>

<p>When I run this through with the three points ([0,0],[4,4],[1,1]), I get the following error:</p>

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

<p>Just to be sure that I wasn't going outside of the bounds of the cosine function, I had it print the numerator and denominator of theta2 for all of the assessed points, and got this leading up to the point in question:</p>

<pre><code>***** [[0, 0], [4, 2], [1, 1]]
&gt;&gt;&gt; num2 =  12.0
&gt;&gt;&gt; den2 =  12.6491106407
***** [[0, 0], [4, 3], [1, 1]]
&gt;&gt;&gt; num2 =  14.0
&gt;&gt;&gt; den2 =  14.1421356237
***** [[0, 0], [4, 4], [1, 1]]
&gt;&gt;&gt; num2 =  16.0
&gt;&gt;&gt; den2 =  16.0
</code></pre>

<p>I would've thought that there was a problem with dividing two numbers that were the same for whatever reason (16.0), but it worked fine on [2,2] and [3,3] for the second point:</p>

<pre><code>***** [[0, 0], [2, 2], [1, 1]]
&gt;&gt;&gt; num2 =  8.0
&gt;&gt;&gt; den2 =  8.0
</code></pre>

<p>...</p>

<pre><code>***** [[0, 0], [3, 3], [1, 1]]
&gt;&gt;&gt; num2 =  12.0
&gt;&gt;&gt; den2 =  12.0
</code></pre>

<p>Any thoughts on what might be going wrong here?</p>

<p>When I run your code:</p>

<pre><code>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])
</code></pre>

<p>I get that <code>num2/den2 == 1.0000000000000004</code>.  Unless you print out the full precision, you might not notice that <code>num2</code> is <em>slightly</em> bigger than <code>den2</code> which results in a value slightly bigger than one.  Obviously, since the maximum of cosine is 1, then you can't take the arcos of a number <em>larger</em> than 1.</p>

python math cosine