1 | # Tangent function of numerical and symbolic arguments
|
2 |
|
3 |
|
4 |
|
5 | Eval_tan = ->
|
6 | push(cadr(p1))
|
7 | Eval()
|
8 | tangent()
|
9 |
|
10 | tangent = ->
|
11 | save()
|
12 | yytangent()
|
13 | restore()
|
14 |
|
15 | yytangent = ->
|
16 | n = 0
|
17 | d = 0.0
|
18 |
|
19 | p1 = pop()
|
20 |
|
21 | if (car(p1) == symbol(ARCTAN))
|
22 | push(cadr(p1))
|
23 | return
|
24 |
|
25 | if (isdouble(p1))
|
26 | d = Math.tan(p1.d)
|
27 | if (Math.abs(d) < 1e-10)
|
28 | d = 0.0
|
29 | push_double(d)
|
30 | return
|
31 |
|
32 | # tan function is antisymmetric, tan(-x) = -tan(x)
|
33 |
|
34 | if (isnegative(p1))
|
35 | push(p1)
|
36 | negate()
|
37 | tangent()
|
38 | negate()
|
39 | return
|
40 |
|
41 | # multiply by 180/pi to go from radians to degrees.
|
42 | # we go from radians to degrees because it's much
|
43 | # easier to calculate symbolic results of most (not all) "classic"
|
44 | # angles (e.g. 30,45,60...) if we calculate the degrees
|
45 | # and the we do a switch on that.
|
46 | # Alternatively, we could look at the fraction of pi
|
47 | # (e.g. 60 degrees is 1/3 pi) but that's more
|
48 | # convoluted as we'd need to look at both numerator and
|
49 | # denominator.
|
50 |
|
51 | push(p1)
|
52 | push_integer(180)
|
53 | multiply()
|
54 | if evaluatingAsFloats
|
55 | push_double(Math.PI)
|
56 | else
|
57 | push_symbol(PI)
|
58 | divide()
|
59 |
|
60 | n = pop_integer()
|
61 |
|
62 | # most "good" (i.e. compact) trigonometric results
|
63 | # happen for a round number of degrees. There are some exceptions
|
64 | # though, e.g. 22.5 degrees, which we don't capture here.
|
65 | if (n < 0 || isNaN(n))
|
66 | push(symbol(TAN))
|
67 | push(p1)
|
68 | list(2)
|
69 | return
|
70 |
|
71 | switch (n % 360)
|
72 | when 0, 180
|
73 | push_integer(0)
|
74 | when 30, 210
|
75 | push_rational(1, 3)
|
76 | push_integer(3)
|
77 | push_rational(1, 2)
|
78 | power()
|
79 | multiply()
|
80 | when 150, 330
|
81 | push_rational(-1, 3)
|
82 | push_integer(3)
|
83 | push_rational(1, 2)
|
84 | power()
|
85 | multiply()
|
86 | when 45, 225
|
87 | push_integer(1)
|
88 | when 135, 315
|
89 | push_integer(-1)
|
90 | when 60, 240
|
91 | push_integer(3)
|
92 | push_rational(1, 2)
|
93 | power()
|
94 | when 120, 300
|
95 | push_integer(3)
|
96 | push_rational(1, 2)
|
97 | power()
|
98 | negate()
|
99 | else
|
100 | push(symbol(TAN))
|
101 | push(p1)
|
102 | list(2)
|
103 |
|
104 |
|