#! /usr/bin/perl -w
# Here is another way to do it, using a trigonometry 'toolkit'
# approach and a different interface. Sides are $a, $b, and $c, and
# corresponding opposing angles are $A, $B, and $C. Note that
# pathological cases will break the program (e.g., using two angles
# whose sum is greater than 180); more robust error checking is
# required.
use strict;
test();
main();
sub main {
print "Enter an angle (in degrees) and its opposing side:\n";
print 'Angle: ';
chomp(my $A = <STDIN>);
print 'Side : ';
chomp(my $a = <STDIN>);
print q/Enter 'a' if you have an angle, 's' if you have a side: /;
GET_WHAT:
chomp(my $what = lc <STDIN>);
if ($what eq 'a') {
print 'Other angle: ';
chomp(my $B = <STDIN>);
my $C = 180 - $A - $B;
my $b = aAB_to_b($a, $A, $B);
my $c = aAB_to_b($a, $A, $C);
printf 'The other two sides are %.2f and %.2f, '
. "and the other angle is %.2f\n",
$b, $c, $C;
}
elsif ($what eq 's') {
print 'Other side: ';
chomp(my $b = <STDIN>);
my $B = aAb_to_B($a, $A, $b);
my $C = 180 - $A - $B;
my $c = aAB_to_b($a, $A, $C);
printf 'The other side is %.2f, '
. "and the other two angles are %.2f and %.2f\n",
$c, $B, $C;
}
else {
print q/Please enter 'a' or 's': /;
goto GET_WHAT;
}
}
sub aAb_to_B {
my ($a, $A, $b) = @_;
return rad2deg(asin($b * sin(deg2rad($A)) / $a));
}
sub aAB_to_b {
my ($a, $A, $B) = @_;
return sin(deg2rad($B)) * $a / sin(deg2rad($A));
}
sub asin {
my $sine = shift;
return undef unless $sine >= -1 && $sine <= 1;
return atan2($sine, sqrt(1 - $sine * $sine));
}
use constant PI => 4 * atan2(1, 1);
sub deg2rad { $_[0] / 180 * PI }
sub rad2deg { $_[0] / PI * 180 }
sub test {
# More tests would be welcome.
expect('aAB_to_b', 10, 5, 30, 90);
expect('aAb_to_B', 90, 5, 30, 10);
}
sub expect {
my ($sub, $exp, @args) = @_;
no strict 'refs';
my $got = $sub->(@args);
return if abs($got - $exp) < 0.0001;
local $" = ', ';
printf "Expected $sub(@args) to give $exp, but got %.2f\n", $got;
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.