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 ) { $angles{A} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $A ) ); } if ( $B ) { $angles{B} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $B ) ); } if ( $C ) { $angles{C} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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( $other ) ); } elsif ( $var eq "B" ) { $sum = $angles{A} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "A" ) { $sum = $angles{B} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } 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 ); $angles{B} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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; $C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "B" ) { $sum = $angles{A} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "A" ) { $sum = $angles{B} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } undef $var; } if ( $c && $C == 0 ) { my $sin_C = ( 1/$x ) * $c; $C = asin( $sin_C ); $angles{C} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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 ); $angles{A} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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; $C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "B" ) { $sum = $angles{A} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "A" ) { $sum = $angles{B} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } undef $var; } if ( $c && $C == 0 ) { my $sin_C = ( 1/$x ) * $c; $C = asin( $sin_C ); $angles{C} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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 ); $angles{A} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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; $C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "B" ) { $sum = $angles{A} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "A" ) { $sum = $angles{B} + $angles{C}; print ("Sum: $sum\n"); $other = 180 - $sum; $angles{$var} = $other; $A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } undef $var; } if ( $b && $B == 0 ) { my $sin_B = ( 1/$x ) * $b; $B = asin( $sin_B ); $angles{B} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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; $C = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "B" ) { $sum = $angles{A} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $B = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } elsif ( $var eq "A" ) { $sum = $angles{B} + $angles{C}; $other = 180 - $sum; $angles{$var} = $other; $A = sprintf( "%.10f", Math::NumberCruncher::deg2rad( $other ) ); } undef $var; } if ( $a && $A == 0 ) { my $sin_A = ( 1/$x ) * $a; $A = asin( $sin_A ); $angles{A} = sprintf( "%.10f", Math::NumberCruncher::rad2deg( $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 <); print ("a: "); chomp($a = ); print ("B: "); chomp($B = ); print ("b: "); chomp($b = ); print ("C: "); chomp($C = ); print ("c: "); chomp($c = ); ( $A1, $B1, $C1, $a1, $b1, $c1 ) = LawOfSines( $A, $a, $B, $b, $C, $c, "d" ); print <