File Coverage

blib/lib/Math/Shape/Line.pm
Criterion Covered Total %
statement 38 39 97.4
branch 22 26 84.6
condition n/a
subroutine 9 9 100.0
pod 3 4 75.0
total 72 78 92.3


line stmt bran cond sub pod time code
1 7     7   691 use strict;
  7         12  
  7         189  
2 7     7   34 use warnings;
  7         10  
  7         342  
3             package Math::Shape::Line;
4             $Math::Shape::Line::VERSION = '0.15';
5 7     7   133 use 5.008;
  7         21  
6 7     7   99 use Carp;
  7         14  
  7         403  
7 7     7   37 use Math::Shape::Vector;
  7         12  
  7         3027  
8              
9             # ABSTRACT: a 2d vector-based infinite line
10              
11              
12             sub new {
13 39 50   39 1 182 croak 'incorrect number of args' unless @_ == 5;
14 39         68 my ($class, $x1, $y1, $x2, $y2) = @_;
15 39         177 bless { base => Math::Shape::Vector->new($x1, $y1),
16             direction => Math::Shape::Vector->new($x2, $y2),
17             }, $class;
18             }
19              
20              
21             sub is_equivalent
22             {
23 8 50   8 1 40 croak 'must pass a line object' unless $_[1]->isa('Math::Shape::Line');
24 8 100       33 unless( $_[0]->{direction}->is_parallel($_[1]->{direction}) )
25             {
26 3         14 0;
27             }
28             else
29             {
30 5         20 my $base = $_[0]->{base}->subtract_vector($_[1]->{base});
31 5         16 $base->is_parallel($_[0]->{direction});
32             }
33             }
34              
35              
36             sub on_one_side
37             {
38 20 50   20 0 81 croak 'project not called with argument of type Math::Shape::Line' unless $_[1]->isa('Math::Shape::LineSegment');
39 20         28 my ($self, $segment) = @_;
40              
41 20         67 my $vector_d1 = $segment->{start}->subtract_vector($self->{base});
42 20         66 my $vector_d2 = $segment->{end}->subtract_vector($self->{base});
43 20         56 my $vector_n = $self->{direction}->rotate_90;
44              
45 20 100       50 $vector_n->dot_product($vector_d1) * $vector_n->dot_product($vector_d2)
46             > 0 ? 1 : 0;
47             }
48              
49              
50              
51             sub collides
52             {
53 21     21 1 40 my ($self, $other_obj) = @_;
54              
55 21 100       171 if ($other_obj->isa('Math::Shape::Line'))
    100          
    100          
    100          
    100          
    50          
56             {
57 7 100       28 if($self->{direction}->is_parallel($other_obj->{direction}))
58             {
59 4         12 $self->is_equivalent($other_obj);
60             }
61             else
62             {
63 3         12 1;
64             }
65             }
66             elsif ($other_obj->isa('Math::Shape::LineSegment'))
67             {
68 6 100       15 $self->on_one_side($other_obj) ? 0 : 1;
69             }
70             elsif ($other_obj->isa('Math::Shape::OrientedRectangle'))
71             {
72 2         8 $other_obj->collides($self);
73             }
74             elsif ($other_obj->isa('Math::Shape::Circle'))
75             {
76 2         7 $other_obj->collides($self);
77             }
78             elsif ($other_obj->isa('Math::Shape::Rectangle'))
79             {
80 2         8 $other_obj->collides($self);
81             }
82             elsif ($other_obj->isa('Math::Shape::Vector'))
83             {
84 2         14 $other_obj->collides($self);
85             }
86             else
87             {
88 0           croak 'collides must be called with a Math::Shape::Vector library object';
89             }
90             }
91              
92              
93              
94             1;
95              
96             __END__