 Syntactic Confectionery Delight PerlMonks

### comment on

 Need Help??
Hello, fellow programmers of the cloth. I need some help. The wife of a good friend of mine is taking a trigonometry class. I thought that I'd whip up a quickie perl script that would perform the Law of Sines so she could quickly check her answers. After a bit of playing, I ended up with this:
```use Math::NumberCruncher;

sub asin {
my \$sine = shift;
return undef unless ( \$sine >= -1 && \$sine <= 1 );
return atan2( \$sine, sqrt( 1-\$sine * \$sine ) );
}

sub LawOfSines {
my ( \$A, \$a, \$B, \$b, \$C, \$c, \$format ) = @_;
return undef unless ( \$A && \$a ) || ( \$B && \$b ) || ( \$C && \$c );
return undef unless defined \$a or defined \$b or defined \$c;
return undef unless defined \$A or defined \$B or defined \$C;

my %angles = ();
my %sides = ();
my @angles = undef;
my ( \$var, \$other, \$sum ) = undef;

if ( \$format eq "d" ) {
if ( \$A ) {
\$angles{A} = \$A;
\$A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$A )
+ );
}
if ( \$B ) {
\$angles{B} = \$B;
\$B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$B )
+ );
}
if ( \$C ) {
\$angles{C} = \$C;
\$C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$C )
+ );
}
} else {
if ( \$A ) {
+eg( \$A ) );
}
if ( \$B ) {
+eg( \$B ) );
}
if ( \$C ) {
+eg( \$C ) );
}
}

unless ( \$A > 0 && \$B > 0 && \$C > 0 ) {
if ( \$A > 0 && \$B > 0 ) { \$var = "C" }
if ( \$A > 0 && \$C > 0 ) { \$var = "B" }
if ( \$B > 0 && \$C > 0 ) { \$var = "A" }
if ( \$var eq "C" ) {
\$sum = \$angles{B} + \$angles{A};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
\$C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$oth
+er ) );
} elsif ( \$var eq "B" ) {
\$sum = \$angles{A} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
\$B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$oth
+er ) );
} elsif ( \$var eq "A" ) {
\$sum = \$angles{B} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
\$A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( \$oth
+er ) );
}
undef \$var;
}

if ( \$a ) {
\$sides{a} = \$a;
}
if ( \$b ) {
\$sides{b} = \$b;
}
if ( \$c ) {
\$sides{c} = \$c;
}

if ( \$A > 0 && \$a ) {
my \$x = \$a / sin( \$A );
if ( \$b && \$B == 0 ) {
my \$sin_B = ( 1/\$x ) * \$b;
\$B = asin( \$sin_B );
+eg( \$B ) );
} elsif ( !\$b && \$B > 0 ) {
\$b = sprintf( "%.3f", ( \$x * sin( \$B ) ) );
\$sides{b} = \$b;
}

unless ( \$A > 0 && \$B > 0 && \$C > 0 ) {
if ( \$A > 0 && \$B > 0 ) { \$var = "C" }
if ( \$A > 0 && \$C > 0 ) { \$var = "B" }
if ( \$B > 0 && \$C > 0 ) { \$var = "A" }
if ( \$var eq "C" ) {
\$sum = \$angles{B} + \$angles{A};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "B" ) {
\$sum = \$angles{A} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "A" ) {
\$sum = \$angles{B} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
}
undef \$var;
}

if ( \$c && \$C == 0 ) {
my \$sin_C = ( 1/\$x ) * \$c;
\$C = asin( \$sin_C );
+eg( \$C ) );
} elsif ( !\$c && \$C > 0 ) {
\$c = sprintf( "%.3f", ( \$x * sin( \$C ) ) );
\$sides{c} = \$c;
}
} elsif ( \$B > 0 && \$b ) {
my \$x = \$b / sin( \$B );
if ( \$a && \$A == 0 ) {
my \$sin_A = ( 1/\$x ) * \$a;
\$A = asin( \$sin_A );
+eg( \$A ) );
} elsif ( !\$a && \$A > 0 ) {
\$a = sprintf( "%.3f", ( \$x * sin( \$A ) ) );
\$sides{a} = \$a;
}

unless ( \$A > 0 && \$B > 0 && \$C > 0 ) {
if ( \$A > 0 && \$B > 0 ) { \$var = "C" }
if ( \$A > 0 && \$C > 0 ) { \$var = "B" }
if ( \$B > 0 && \$C > 0 ) { \$var = "A" }
if ( \$var eq "C" ) {
\$sum = \$angles{B} + \$angles{A};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "B" ) {
\$sum = \$angles{A} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "A" ) {
\$sum = \$angles{B} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
}
undef \$var;
}

if ( \$c && \$C == 0 ) {
my \$sin_C = ( 1/\$x ) * \$c;
\$C = asin( \$sin_C );
+eg( \$C ) );
} elsif ( !\$c && \$C > 0 ) {
\$c = sprintf( "%.3f", ( \$x * sin( \$C ) ) );
\$sides{c} = \$c;
}
} elsif ( \$C > 0 && \$c ) {
my \$x = \$c / sin( \$C );
if ( \$a && \$A == 0 ) {
my \$sin_A = ( 1/\$x ) * \$a;
\$A = asin( \$sin_A );
+eg( \$A ) );
} elsif ( !\$a && \$A > 0 ) {
\$a = sprintf( "%.3f", ( \$x * sin( \$A ) ) );
\$sides{a} = \$a;
}

unless ( \$A > 0 && \$B > 0 && \$C > 0 ) {
if ( \$A > 0 && \$B > 0 ) { \$var = "C" }
if ( \$A > 0 && \$C > 0 ) { \$var = "B" }
if ( \$B > 0 && \$C > 0 ) { \$var = "A" }
if ( \$var eq "C" ) {
\$sum = \$angles{B} + \$angles{A};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "B" ) {
\$sum = \$angles{A} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "A" ) {
\$sum = \$angles{B} + \$angles{C};
print ("Sum: \$sum\n");
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
}
undef \$var;
}

if ( \$b && \$B == 0 ) {
my \$sin_B = ( 1/\$x ) * \$b;
\$B = asin( \$sin_B );
+eg( \$B ) );
} elsif ( !\$b && \$B > 0 ) {
\$b = sprintf( "%.3f", ( \$x * sin( \$B ) ) );
\$sides{b} = \$b;
}

unless ( \$A > 0 && \$B > 0 && \$C > 0 ) {
if ( \$A > 0 && \$B > 0 ) { \$var = "C" }
if ( \$A > 0 && \$C > 0 ) { \$var = "B" }
if ( \$B > 0 && \$C > 0 ) { \$var = "A" }
if ( \$var eq "C" ) {
\$sum = \$angles{B} + \$angles{A};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "B" ) {
\$sum = \$angles{A} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
} elsif ( \$var eq "A" ) {
\$sum = \$angles{B} + \$angles{C};
\$other = 180 - \$sum;
\$angles{\$var} = \$other;
+\$other ) );
}
undef \$var;
}

if ( \$a && \$A == 0 ) {
my \$sin_A = ( 1/\$x ) * \$a;
\$A = asin( \$sin_A );
+eg( \$A ) );
} elsif ( !\$a && \$A > 0 ) {
\$a = sprintf( "%.3f", ( \$x * sin( \$A ) ) );
\$sides{a} = \$a;
}

}

if ( \$format eq "d" ) {
\$A = sprintf( "%.3f", Math::NumberCruncher::rad2deg( \$A ) );
\$B = sprintf( "%.3f", Math::NumberCruncher::rad2deg( \$B ) );
\$C = sprintf( "%.3f", Math::NumberCruncher::rad2deg( \$C ) );
}
\$A = sprintf( "%.3f", \$A );
\$a = sprintf( "%.3f", \$a );
\$B = sprintf( "%.3f", \$B );
\$b = sprintf( "%.3f", \$b );
\$C = sprintf( "%.3f", \$C );
\$c = sprintf( "%.3f", \$c );
return ( \$A, \$B, \$C, \$a, \$b, \$c );
}

print <<END;
Enter the triangle items you have available. You must enter at least
three items, including at least one side and at least one angle. In ad
+dition,
two of the three must be an angle and its opposing side. (i.e., B and
+b ).
END

print ("A: ");
chomp(\$A = <STDIN>);
print ("a: ");
chomp(\$a = <STDIN>);
print ("B: ");
chomp(\$B = <STDIN>);
print ("b: ");
chomp(\$b = <STDIN>);
print ("C: ");
chomp(\$C = <STDIN>);
print ("c: ");
chomp(\$c = <STDIN>);

( \$A1, \$B1, \$C1, \$a1, \$b1, \$c1 ) = LawOfSines( \$A, \$a, \$B, \$b, \$C, \$c,
+ "d" );

print <<END;
A: \$A1
a: \$a1
B: \$B1
b: \$b1
C: \$C1
c: \$c1
END
I was more interested in doing it quickly that I was in making it efficient or elegant. Now that I have the time, though, I want to clean it up. My problem is that after looking at it for as many hours as I have, I could really use someone else's input. I use Math::NumberCruncher to perform any degree/radian conversions. I'm really just doing this for fun (egad, did I just say that I'm doing the Law of Sines for fun? I need to get out more....), so there is no hurry, but if someone could take a look at my code and give me an assist in making it more efficient and/or elegant, I would appreciate it greatly.

Thanks a bunch.
___________________
Kurt

In reply to Help w/ Law of Sines script by sifukurt

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• 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.

Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2023-12-10 11:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
What's your preferred 'use VERSION' for new CPAN modules in 2023?

Results (39 votes). Check out past polls.

Notices?