File Coverage

blib/lib/Math/Shape/LineSegment.pm
Criterion Covered Total %
statement 46 47 97.8
branch 19 22 86.3
condition n/a
subroutine 10 10 100.0
pod 3 3 100.0
total 78 82 95.1


line stmt bran cond sub pod time code
1 7     7   25069 use strict;
  7         12  
  7         176  
2 7     7   34 use warnings;
  7         10  
  7         408  
3             package Math::Shape::LineSegment;
4             $Math::Shape::LineSegment::VERSION = '0.15';
5 7     7   125 use 5.008;
  7         19  
6 7     7   69 use Carp;
  7         13  
  7         438  
7 7     7   637 use Math::Shape::Vector;
  7         14  
  7         3942  
8 7     7   3753 use Math::Shape::Range;
  7         13  
  7         165  
9 7     7   1680 use Math::Shape::Line;
  7         14  
  7         3309  
10              
11             # ABSTRACT: a 2d vector line segment; a line with start and end points
12              
13              
14             sub new {
15 102 50   102 1 254 croak 'incorrect number of args' unless @_ == 5;
16 102         157 my ($class, $x1, $y1, $x2, $y2) = @_;
17 102         267 bless { start => Math::Shape::Vector->new($x1, $y1),
18             end => Math::Shape::Vector->new($x2, $y2),
19             }, $class;
20             }
21              
22              
23             sub project
24             {
25 80 50   80 1 242 croak 'project not called with argument of type Math::Shape::Vector' unless $_[1]->isa('Math::Shape::Vector');
26 80         111 my ($self, $vector) = @_;
27 80         180 my $unit_vector = $vector->convert_to_unit_vector;
28              
29             my $range = Math::Shape::Range->new(
30             $unit_vector->dot_product($self->{start}),
31 80         233 $unit_vector->dot_product($self->{end}),
32             );
33              
34 80         202 $range->sort;
35             }
36              
37              
38             sub collides
39             {
40 15     15 1 26 my ($self, $other_obj) = @_;
41              
42 15 100       143 if ($other_obj->isa('Math::Shape::LineSegment'))
    100          
    100          
    100          
    100          
    50          
43             {
44 5         20 my $vector_a = $self->{end}->subtract_vector($self->{start});
45             my $axis_a = Math::Shape::Line->new(
46             $self->{start}->{x},
47             $self->{start}->{y},
48             $vector_a->{x},
49 5         27 $vector_a->{y});
50              
51 5 100       17 return 0 if $axis_a->on_one_side($other_obj);
52              
53 4         18 my $vector_b = $other_obj->{end}->subtract_vector($other_obj->{start});
54             my $axis_b = Math::Shape::Line->new(
55             $other_obj->{start}->{x},
56             $other_obj->{start}->{y},
57             $vector_b->{x},
58 4         17 $vector_b->{y});
59              
60 4 100       11 return 0 if $axis_b->on_one_side($self);
61              
62 3 100       13 if ($axis_a->{direction}->is_parallel($axis_b->{direction}))
63             {
64 2         7 my $range_a = $self->project($axis_a->{direction});
65 2         6 my $range_b = $other_obj->project($axis_a->{direction});
66 2         6 return $range_a->is_overlapping($range_b);
67             }
68              
69 1         12 1;
70             }
71             elsif ($other_obj->isa('Math::Shape::Vector'))
72             {
73 2         6 $other_obj->collides($self);
74             }
75             elsif ($other_obj->isa('Math::Shape::Line'))
76             {
77 2         6 $other_obj->collides($self);
78             }
79             elsif ($other_obj->isa('Math::Shape::OrientedRectangle'))
80             {
81 2         8 $other_obj->collides($self);
82             }
83             elsif ($other_obj->isa('Math::Shape::Rectangle'))
84             {
85 2         8 $other_obj->collides($self);
86             }
87             elsif ($other_obj->isa('Math::Shape::Circle'))
88             {
89 2         7 $other_obj->collides($self);
90             }
91             else
92             {
93 0           croak 'collides must be called with a Math::Shape::Vector library object';
94             }
95             }
96              
97             1;
98              
99             __END__