
    ^j"                     ~    d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
mZ edz  Zd Zd Zd Zd Zdd
Zd Zd Zd Zd Zy	)a{  
Written by Steven Byrnes, http://sjbyrnes.com/

Download: https://pypi.python.org/pypi/trianglesolver/
Source code repository: https://github.com/sbyrnes321/trianglesolver

This little package applies the law of sines or cosines to find all the
sides and angles of a triangle, if you know some of the sides and/or
angles.

The main function defined by this package is solve(...). Simple example::

    from math import pi
    from trianglesolver import solve
    a,b,c,A,B,C = solve(b=7.6, c=8.3, A=pi/3)

Following the usual convention, lower-case letters are side lengths and
capital letters are angles. Corresponding letters are opposite each other,
e.g. side b is opposite angle B.

All angles are in radians! However, you can use the degree constant to
convert::

    from trianglesolver import solve, degree
    a,b,c,A,B,C = solve(b=7, A=5*degree, B=70*degree)
    print(C / degree)
    )divisionprint_function)sincospisqrtacosasinisclose   c                 z    |t        |       z  t        |      z  }|t        |      z  t        |      z  }|||| ||fS )= This function solves the triangle and returns (d,e,f,D,E,F) )r   )DEFfdes         G/opt/ringagent/.cad-venv/lib/python3.12/site-packages/trianglesolver.pyaaasr   &   s@    	CF
SVA	CF
SVAa!Aa=    c                     | |z   |kD  r||z   | kD  r|| z   |kD  sJ t        | dz  |dz  z   |dz  z
  d| z  |z  z        }t        | dz  |dz  z   |dz  z
  d| z  |z  z        }t        |z
  |z
  }| |||||fS r      )r	   r   )r   r   r   r   r   r   s         r   sssr   ,   s    q519Qq1uqy00adQTkAqD QUQY/0AadQTkAqD QUQY/0A
Q
Aa!Aa=r   c                 n    t        | dz  |dz  z   d| z  |z  t        |      z  z
        }t        | ||      S r   )r   r   r   )r   r   r   r   s       r   sasr   4   s<    QTAqD[1q519s1v--.Aq1:r   c                 
   |dv sJ d       t        |      |z  | z  }t        |d      r
t        dz  }n|dk  sJ d       t        |      }t        |z
  }dt        |z
  |z
  cxk  xr	 t        k  nc }dt        |z
  |z
  cxk  xr	 t        k  nc }	|dk(  r|sJ d       |}n<|dk(  r|	sJ d       |}n+|d	k(  sJ |r|	rt	        d
      |s|	st	        d      |r|n|}t        |z
  |z
  }
t        ||
||       \  }}} }}
}| |||||
fS )zu This function solves the triangle and returns (d,e,f,D,E,F)
    See docstring for solve() for definition of ssa_flag)acuteobtuseforbidzInvalid value of ssa_flag   r   zNo such triangler   r   r    r!   z,Two different triangles fit this description)r   r   r   r
   
ValueErrorr   )r   r   r   ssa_flagsinEr   E_acuteE_obtuseacute_is_validobtuse_is_validr   r   s               r   ssar*   :   s<    44Q6QQ4q6A:>D tQqDax+++xt*<rAv/525Q 17R7w!5#55>A!"6$66?Ax'''/ !OPP"_ !344)xA
Q
Aq1Q-KAa!Aaa!Aa=r   Nc           	         t        d | |||||fD              dk7  rt        d      t        d | ||fD              dk(  rt        d      t        d | |||||fD              sJ t        d |||fD              sJ |dv sJ t        d	 | ||fD              dk(  rt        | ||      \  } }}}}}| |||||fS t        d
 | ||fD              dk(  rt        d | ||fD              rt	        | |||      \  } }}}}}nbt        d | ||fD              rt	        | |||      \  } }}}}}n6t        d ||| fD              rt	        || ||      \  }} }}}}n
t        d |||fD              rt	        ||||      \  }}} }}}nt        d ||| fD              rt	        || ||      \  }} }}}}nt        d |||fD              rt	        ||||      \  }}} }}}nt        d | ||fD              rt        | ||      \  } }}}}}n_t        d |||fD              rt        |||      \  }}} }}}n5t        d || |fD              rt        || |      \  }} }}}}nt        d      | |||||fS t        d | ||fD              dk(  r|t        |z
  |z
  }n|t        |z
  |z
  }nt        |z
  |z
  }|dkD  r
|dkD  r|dkD  sJ |t        ||||      \  } }}}}}n-| t        ||||       \  }}} }}}nt        ||||      \  }} }}}}| |||||fS t        d      )u!  
    Solve to find all the information about a triangle, given partial
    information.

    a, b, c, A, B, and C are the three sides and angles. (e.g. A is the angle
    opposite the side of length a.) Out of these six possibilities, you need
    to tell the program exactly three. Then the program will tell you all six.

    It returns a tuple (a, b, c, A, B, C).

    "ssa" is the situation when you give two sides and an angle which is not
    between them. This is usually not enough information to specify a unique
    triangle. Usually there are two possible triangles—except for a special
    case with right triangles where the two possible triangles are the same
    (the equation has a "double root"), and some cases where one of the two
    possible triangles has a negative angle.

    Therefore there is an 'ssa_flag'. You can set it to'forbid' (raise an error
    if the answer is not unique - the default setting), or 'acute' (where the
    unknown angle across from the known side is chosen to be acute) or 'obtuse'
    (similarly).
    c              3   $   K   | ]  }|d u 
 y wN .0xs     r   	<genexpr>zsolve.<locals>.<genexpr>w   s     
0Q1D=
0      zMust provide exactly 3 inputsc              3   $   K   | ]  }|d u  
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>y   s     
&19
&r3   z#Must provide at least 1 side lengthc              3   ,   K   | ]  }||dkD    y w)Nr   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>{   s     =q}q1u=s   
c              3   4   K   | ]  }||t         k    y wr-   )r   r/   s     r   r2   zsolve.<locals>.<genexpr>|   s     8!!-q2v8s   )r!   r   r    c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>        
*Q1D=
*r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r9   r3   r   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   s     0q}0r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>        21$2r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   c              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r=   r3   z Oops, this code should never runc              3   $   K   | ]  }|d u 
 y wr-   r.   r/   s     r   r2   zsolve.<locals>.<genexpr>   r9   r3   r"   r   )sumr#   allr   r*   r   r   r   )abcABCr$   s          r   solverN   `   s   . 
01Qq1Q-
00A5899

&q1g
&&!+>??=q1Qqm====8!Aw88884444 
*1Qq'
**a/!Aaj!Aa!!Aa!} 
*1Qq'
**a/0q!Qi00aAx0KAa!Aa2Aq	22aAx0KAa!Aa2Aq	22aAx0KAa!Aa2Aq	22aAx0KAa!Aa2Aq	22aAx0KAa!Aa2Aq	22aAx0KAa!Aa 2Aq	22aA,KAa!Aa2Aq	22aA,KAa!Aa2Aq	22aA,KAa!Aa?@@!Aa!} 
*1Qq'
**a/9Q
AYQ
AQ
A1uQ1q5((=q1Q-KAa!Aa]q1Q-KAa!Aaq1Q-KAa!Aa!Aa!}
7
88r   c                 T     t         fdt        t                     D              S )Nc              3   B   K   | ]  }t        |   |           y wr-   )r   )r0   ir1   ys     r   r2   z tuple_isclose.<locals>.<genexpr>   s      :qwqtQqT":s   )rG   rangelen)r1   rR   s   ``r   tuple_iscloserU      s    :E#a&M:::r   c                    t        | t        |      z  |t        |      z        sJ t        | t        |      z  |t        |      z        sJ t        |dz  | dz  |dz  z   d| z  |z  t        |      z  z
        sJ t        | dz  |dz  |dz  z   d|z  |z  t        |      z  z
        sJ t        |dz  |dz  | dz  z   d|z  | z  t        |      z  z
        sJ y)zJ Check that the triangle satisfies the law of cosines and law of
    sinesr   N)r   r   r   )rH   rI   rJ   rK   rL   rM   s         r   test_trianglerW      s     1SV8Qs1vX&&&1SV8Qs1vX&&&1a4A1q1uqy3q6'99:::1a4A1q1uqy3q6'99:::1a4A1q1uqy3q6'99:::r   c           	         t        | ||      \  }}}}}}t        | ||f|||f      sJ t        | |||||       | |||||f}	t        |	t        | ||            sJ t        |	t        | ||            sJ t        |	t        |||            sJ t        |	t        | ||            sJ t        |	t        | ||            sJ t        |	t        | ||            sJ t        |	t        |||            sJ t        |	t        |||	            sJ t        |	t        |||
            sJ t        |	t        |||            sJ t        |	t        |||            sJ t        |	t        |||            sJ |t        dz  k  rdnd}
|t        dz  k  rdnd}|t        dz  k  rdnd}t        |	t        | |||            sJ t        |	t        | |||
            sJ t        |	t        | |||            sJ t        |	t        | |||
            sJ t        |	t        ||||            sJ t        |	t        ||||            sJ y)z< Test that the program works, for a triangle of sides a,b,c.rH   rI   rJ   )rH   rI   rM   )rH   rJ   rL   )rI   rJ   rK   )rH   rK   rL   )rH   rK   rM   )rH   rL   rM   )rI   rK   rL   )rI   rK   rM   )rI   rL   rM   )rJ   rK   rL   )rJ   rK   rM   )rJ   rL   rM   r   r   r    )rH   rI   rK   r$   )rH   rI   rL   r$   )rH   rJ   rK   r$   )rH   rJ   rM   r$   )rI   rJ   rL   r$   )rI   rJ   rM   r$   N)rN   rU   rW   r   )rH   rI   rJ   a1b1c1rK   rL   rM   triAtypeBtypeCtypes                r   test_solverra      sd    QQ'NBr"Qq!Aa2b*---!Aa!AQq1Q-C ea!a0111ea!a0111ea!a0111 ea12333ea12333ea12333ea12333ea12333ea12333ea12333ea12333ea123332a4xGXE2a4xGXE2a4xGXE ea1EBCCCea1EBCCCea1EBCCCea1EBCCCea1EBCCCea1EBCCCr   c                  J    dD ]  \  } }}t        | ||        t        d       y )N))      	   )      
   )rf   rh   rg   )rh   rf   rg   )rf         )ri   rf   rj   )ri   rj   rf   zAll tests pass!)ra   printrY   s      r   run_lots_of_testsrl      s0    ( !AAa 

r   )NNNNNNr!   )__doc__
__future__r   r   mathr   r   r   r   r	   r
   r   degreer   r   r   r*   rN   rU   rW   ra   rl   r.   r   r   <module>rq      sU   8 0 8 8 8 
C!LQ9n;;"DHr   