#!/usr/bin/perl -w use strict; sub X() { 0 } sub Y() { 1 } # Given a line segment from point A to point B: my @A= splice @ARGV, 0, 2; my @B= splice @ARGV, 0, 2; # And another point P: my @P= splice @ARGV, 0, 2; # Translate point A to be the origin of the # plane (subtract A from the other points): my @B1= ( $B[X]-$A[X], $B[Y]-$A[Y] ); my @P1= ( $P[X]-$A[X], $P[Y]-$A[Y] ); # Rotate the plane so B is on the X axis: # (Also expands the plane by a factor # equal to the length of the line segment) @P1= ( $P1[X]*$B1[X] + $P1[Y]*$B1[Y], $P1[Y]*$B1[X] - $P1[X]*$B1[Y] ); @B1= ( $B1[X]*$B1[X] + $B1[Y]*$B1[Y], 0 ); # You can now find the closest point on the line: # (let $t=0 represent A and $t=1 represent B) my $t= $P1[X]/$B1[X]; my @I= ( (1-$t)*$A[X] + $t*$B[X], (1-$t)*$A[Y] + $t*$B[Y] ); # And/or, find the length of the line segment # and the distance from the point to the line: my $len= sqrt( $B1[X] ); # Add abs() if you don't want to know # which side of the line the point is on: my $dist= $P1[Y]/$len; # Might as well compute the area of our triangle: my $area= $len*abs($dist)/2; print "I=( $I[X], $I[Y] ) t=$t\n"; print "dist=$dist len=$len area=$area\n";