File Coverage

blib/lib/Math/Shape/LineSegment.pm
Criterion Covered Total %
statement 47 48 97.9
branch 19 22 86.3
condition n/a
subroutine 10 10 100.0
pod 3 3 100.0
total 79 83 95.1


line stmt bran cond sub pod time code
1 7     7   18989 use strict;
  7         11  
  7         215  
2 7     7   25 use warnings;
  7         10  
  7         280  
3             package Math::Shape::LineSegment;
4             $Math::Shape::LineSegment::VERSION = '0.13';
5 7     7   96 use 5.008;
  7         18  
  7         226  
6 7     7   26 use Carp;
  7         9  
  7         390  
7 7     7   469 use Math::Shape::Vector;
  7         11  
  7         135  
8 7     7   2747 use Math::Shape::Range;
  7         13  
  7         181  
9 7     7   1245 use Math::Shape::Line;
  7         9  
  7         2630  
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 275 croak 'incorrect number of args' unless @_ == 5;
16 102         128 my ($class, $x1, $y1, $x2, $y2) = @_;
17 102         208 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 196 croak 'project not called with argument of type Math::Shape::Vector' unless $_[1]->isa('Math::Shape::Vector');
26 80         78 my ($self, $vector) = @_;
27 80         139 my $unit_vector = $vector->convert_to_unit_vector;
28              
29 80         191 my $range = Math::Shape::Range->new(
30             $unit_vector->dot_product($self->{start}),
31             $unit_vector->dot_product($self->{end}),
32             );
33              
34 80         145 $range->sort;
35             }
36              
37              
38             sub collides
39             {
40 15     15 1 27 my ($self, $other_obj) = @_;
41              
42 15 100       144 if ($other_obj->isa('Math::Shape::LineSegment'))
    100          
    100          
    100          
    100          
    50          
43             {
44 5         22 my $vector_a = $self->{end}->subtract_vector($self->{start});
45 5         32 my $axis_a = Math::Shape::Line->new(
46             $self->{start}->{x},
47             $self->{start}->{y},
48             $vector_a->{x},
49             $vector_a->{y});
50              
51 5 100       17 return 0 if $axis_a->on_one_side($other_obj);
52              
53 4         17 my $vector_b = $other_obj->{end}->subtract_vector($other_obj->{start});
54 4         21 my $axis_b = Math::Shape::Line->new(
55             $other_obj->{start}->{x},
56             $other_obj->{start}->{y},
57             $vector_b->{x},
58             $vector_b->{y});
59              
60 4 100       13 return 0 if $axis_b->on_one_side($self);
61              
62 3 100       15 if ($axis_a->{direction}->is_parallel($axis_b->{direction}))
63             {
64 2         8 my $range_a = $self->project($axis_a->{direction});
65 2         5 my $range_b = $other_obj->project($axis_a->{direction});
66 2         6 return $range_a->is_overlapping($range_b);
67             }
68              
69 1         26 1;
70             }
71             elsif ($other_obj->isa('Math::Shape::Vector'))
72             {
73 2         7 $other_obj->collides($self);
74             }
75             elsif ($other_obj->isa('Math::Shape::Line'))
76             {
77 2         7 $other_obj->collides($self);
78             }
79             elsif ($other_obj->isa('Math::Shape::OrientedRectangle'))
80             {
81 2         7 $other_obj->collides($self);
82             }
83             elsif ($other_obj->isa('Math::Shape::Rectangle'))
84             {
85 2         7 $other_obj->collides($self);
86             }
87             elsif ($other_obj->isa('Math::Shape::Circle'))
88             {
89 2         6 $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__