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