package  Line; sub new { my ($c, $a) = @_; my $self = { P0 => $a->{P0}, u => $a->{u} } } 
package Plane; sub new { my ($c, $a) = @_; my $self = { V0 => $a->{V0}, n => $a->{n} } } 

package main;

sub dot { my $p; $p    += $_[0][$_] * $_[1][$_] for 0..@{$_[0]}-1; $p } 
sub vd  { my @v; $v[$_] = $_[0][$_] - $_[1][$_] for 0..@{$_[0]}-1; @v } 
sub va  { my @v; $v[$_] = $_[0][$_] + $_[1][$_] for 0..@{$_[0]}-1; @v } 
sub vp  { my @v; $v[$_] = $_[0][$_] * $_[1][$_] for 0..@{$_[0]}-1; @v } 

sub line_plane_intersection {
    my($L, $P) = @_;

    my $cos = dot($L->{u}, $P->{n});     
    return 'Vectors are orthogonol; no intersection or line within plane' if $cos == 0;

    my @W = vd($L->{P0},$P->{V0});       
    my $SI = -dot($P->{n}, \@W) / $cos;  

    my @a = vp($L->{u},[($SI)x3]);
    my @b = va($P->{V0},\@a);
    va(\@W,\@b);
}

my $L =  Line->new({ P0=>[0,0,10], u=>[0,-1,-1]});
my $P = Plane->new({ V0=>[0,0,5 ], n=>[0, 0, 1]});
print 'Intersection at point: ', join(' ', line_plane_intersection($L, $P)) . "\n";