File Coverage

blib/lib/Math/Shape/Line.pm
Criterion Covered Total %
statement 39 40 97.5
branch 22 26 84.6
condition n/a
subroutine 9 9 100.0
pod 3 4 75.0
total 73 79 92.4


line stmt bran cond sub pod time code
1 7     7   401 use strict;
  7         11  
  7         224  
2 7     7   33 use warnings;
  7         9  
  7         288  
3             package Math::Shape::Line;
4             $Math::Shape::Line::VERSION = '0.14';
5 7     7   101 use 5.008;
  7         17  
  7         190  
6 7     7   32 use Carp;
  7         12  
  7         358  
7 7     7   80 use Math::Shape::Vector;
  7         6  
  7         2278  
8              
9             # ABSTRACT: a 2d vector-based infinite line
10              
11              
12             sub new {
13 39 50   39 1 110 croak 'incorrect number of args' unless @_ == 5;
14 39         53 my ($class, $x1, $y1, $x2, $y2) = @_;
15 39         93 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 39 croak 'must pass a line object' unless $_[1]->isa('Math::Shape::Line');
24 8 100       26 unless( $_[0]->{direction}->is_parallel($_[1]->{direction}) )
25             {
26 3         9 0;
27             }
28             else
29             {
30 5         22 my $base = $_[0]->{base}->subtract_vector($_[1]->{base});
31 5         13 $base->is_parallel($_[0]->{direction});
32             }
33             }
34              
35              
36             sub on_one_side
37             {
38 20 50   20 0 74 croak 'project not called with argument of type Math::Shape::Line' unless $_[1]->isa('Math::Shape::LineSegment');
39 20         24 my ($self, $segment) = @_;
40              
41 20         59 my $vector_d1 = $segment->{start}->subtract_vector($self->{base});
42 20         47 my $vector_d2 = $segment->{end}->subtract_vector($self->{base});
43 20         48 my $vector_n = $self->{direction}->rotate_90;
44              
45 20 100       39 $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 34 my ($self, $other_obj) = @_;
54              
55 21 100       176 if ($other_obj->isa('Math::Shape::Line'))
    100          
    100          
    100          
    100          
    50          
56             {
57 7 100       25 if($self->{direction}->is_parallel($other_obj->{direction}))
58             {
59 4         9 $self->is_equivalent($other_obj);
60             }
61             else
62             {
63 3         10 1;
64             }
65             }
66             elsif ($other_obj->isa('Math::Shape::LineSegment'))
67             {
68 6 100       12 $self->on_one_side($other_obj) ? 0 : 1;
69             }
70             elsif ($other_obj->isa('Math::Shape::OrientedRectangle'))
71             {
72 2         6 $other_obj->collides($self);
73             }
74             elsif ($other_obj->isa('Math::Shape::Circle'))
75             {
76 2         6 $other_obj->collides($self);
77             }
78             elsif ($other_obj->isa('Math::Shape::Rectangle'))
79             {
80 2         6 $other_obj->collides($self);
81             }
82             elsif ($other_obj->isa('Math::Shape::Vector'))
83             {
84 2         5 $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__