release 1.12.1
[descalc.git] / 33_trig.pm
1 # trigonometry for DCT, by Shiar
2
3 # 1.11.2 200411032120 - check for menu module before addmenu()
4 # 1.11.1 200410282330 - cardial mode setting; rad/deg to switch to radians/degrees
5 #                     - convert from/to radians for trig commands if rad mode set
6 # 1.11.0 200410152320 - a?(sin|cos|tan)h? actions from math; links in main submenu trig
7
8 use strict;
9 use warnings;
10
11 my $pi = atan2(1, 1) * 4;
12
13 $set{card} = 1;  # degrees radians grades
14
15 %action = (
16         %action,
17
18         'pi'   => [0, sub { $pi }], # pi constant
19
20         'deg'  => [-1, sub { $set{card} = 1 }], # set degrees
21         'rad'  => [-1, sub { $set{card} = 2 }], # set radians
22
23         # trigonometric
24         'sin'  => [1, sub { sin $_[0] }], # sine
25         'asin' => [1, sub { atan2($_[0], sqrt(1 - $_[0]*$_[0])) }], # inverse sine
26         'cos'  => [1, sub { cos $_[0] }], # cosine
27         'acos' => [1, sub { atan2(sqrt(1 - $_[0]*$_[0]), $_[0]) }], # inverse cosine
28         'tan'  => [1, sub { sin($_[0]) / cos($_[0]) }], # tangent
29         'atan' => [1, sub { atan2($_[0], 1) }], # arctangent
30
31         # hyperbolic
32         'sinh' => [1, sub { (exp($_[0]) - exp(-$_[0])) / 2 }], # hyperbolic sine
33         'cosh' => [1, sub { (exp($_[0]) + exp(-$_[0])) / 2 }], # hyperbolic cosine
34         'tanh' => [1, sub { (exp($_[0]) - exp(-$_[0])) / (exp($_[0]) + exp(-$_[0])) }], # hyperbolic tangent (sinh/cosh)
35         'asinh'=> [1, sub { log(sqrt($_[0]**2+1) + $_[0]) }], # inverse hyperbolic sine
36         'acosh'=> [1, sub { log(sqrt($_[0]**2-1) + $_[0]) }], # inverse hyperbolic cosine
37         'atanh'=> [1, sub { log((1+$_[0]) / (1-$_[0])) / 2 }], # inverse hyperbolic tangent
38 ); # action
39
40 push @{$hook{preaction}}, sub {
41         return unless $set{card}==2;
42         # convert user input from radians if necessary
43         $stack[0] /= 360/$pi if $_[1] =~ /^(?:sin|cos|tan)h?$/;
44 }; # preaction
45 push @{$hook{postaction}}, sub {
46         return unless $set{card}==2;
47         # convert command output to radians if necessary
48         $stack[0] *= 360/$pi if $_[1] =~ /^a(?:sin|cos|tan)h?$/;
49 }; # postaction
50
51 addmenu(["main", 0], "trig", #todo: in math, not in main
52         qw(sin cos tan asin acos atan),
53         qw(sinh cosh tanh asinh acosh atanh),
54         qw(expm lnp1),
55 ) if defined &addmenu;
56
57 return {
58         author  => "Shiar",
59         title   => "trigonometry",
60         version => "1.11.2",
61 };
62