Skip to content

Instantly share code, notes, and snippets.

@allanon
Last active April 9, 2018 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allanon/134d6494cbc9c3f569afda5aca17c460 to your computer and use it in GitHub Desktop.
Save allanon/134d6494cbc9c3f569afda5aca17c460 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
###############################################################################
# Calculate "y = mx + b" form of line equation from two points on the line.
# Use rational numbers instead of decimals.
#
use strict;
use warnings;
usage() if @ARGV != 4;
my ( $x0, $y0, $x1, $y1 ) = @ARGV;
# Calculate "m" numerator and denominator, and "b" numerator and denominator.
my $mn = $y1 - $y0;
my $md = $x1 - $x0;
my $bn = $y1 * ( $x1 - $x0 ) - $x1 * ( $y1 - $y0 );
my $bd = $x1 - $x0;
printf "y = %s/%sx + %s/%s\n", $mn, $md, $bn, $bd;
# Reduce fractions.
( $mn, $md ) = ( $mn / gcd( $mn, $md ), $md / gcd( $mn, $md ) );
( $bn, $bd ) = ( $bn / gcd( $bn, $bd ), $bd / gcd( $bn, $bd ) );
( $mn, $md ) = ( -$mn, -$md ) if $md < 0;
( $bn, $bd ) = ( -$bn, -$bd ) if $bd < 0;
printf "y = %s/%sx + %s/%s\n", $mn, $md, $bn, $bd;
# Prettify the output.
my $m = "$mn/$md"; # "5/3x"
$m = $mn if $md == 1; # "5/1x" => "5x"
$m = '-' if $mn == -1 && $md == 1; # "-1/1x" => "-x"
$m = '' if $mn == 1 && $md == 1; # "1/1x" => "x"
my $b = abs( $bn ) . "/$bd"; # "-5/3" => "5/3"
$b = abs( $bn ) if $bd == 1; # "5/1" => "5"
$b = $bn >= 0 ? "+ $b" : "- $b"; # "-5/3" => "- 5/3" OR "5/3" => "+ 5/3"
$b = '' if $bn == 0; # "0/3" => ""
printf "y = %sx %s\n", $m, $b;
# Euclidian GCD algorithm.
sub gcd {
my ( $a, $b ) = @_;
( $a, $b ) = ( abs $a, abs $b );
( $a, $b ) = ( $b, $a ) if $a < $b;
( $a, $b ) = ( $b, $a % $b ) while $b;
$a;
}
sub usage {
print "$0 x0 y0 x1 y1\n";
print " x0 y0 - coordinates of first point\n";
print " x1 y1 - coordinates of second point\n";
exit;
}
__END__
y = mx + b
Y = mX + b
y-Y = m(x-X)
(y-Y)/(x-X) = m
y = (y-Y)/(x-X)x + b
(y(x-X) - x(y-Y))/(x-X) = b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment