File Coverage

blib/lib/Math/Zap/Line2.pm
Criterion Covered Total %
statement 53 66 80.3
branch 13 20 65.0
condition 6 9 66.6
subroutine 17 22 77.2
pod 17 17 100.0
total 106 134 79.1


line stmt bran cond sub pod time code
1            
2             =head1 Line2
3            
4             Lines in 2d space
5            
6             PhilipRBrenan@yahoo.com, 2004, Perl License
7            
8            
9             =head2 Synopsis
10            
11             Example t/line2.t
12            
13             #_ Vector _____________________________________________________________
14             # Test 2d lines
15             # philiprbrenan@yahoo.com, 2004, Perl License
16             #______________________________________________________________________
17            
18             use Math::Zap::Line2;
19             use Math::Zap::Vector2;
20             use Test::Simple tests=>12;
21            
22             my $x = vector2(1,0);
23             my $y = vector2(0,1);
24             my $c = vector2(0,0);
25            
26             my $a = line2( -$x, +$x);
27             my $b = line2( -$y, +$y);
28             my $B = line2(3*$y, 4*$y);
29            
30             ok($a->intersect($b) == $c);
31             ok($b->intersect($a) == $c);
32             ok($a->intersectWithin($b) == 1);
33             ok($a->intersectWithin($B) == 0);
34             ok($b->intersectWithin($a) == 1);
35             ok($B->intersectWithin($a) == 1);
36             ok($a->parallel($b) == 0);
37             ok($B->parallel($b) == 1);
38             ok(!$b->intersectWithin($B), 'Parallel intersection');
39             ok( line2(-$x, $x)->crossOver(line2(-$y, $y)), 'Crosses 1');
40             ok(!line2(-$x, $x)->crossOver(line2( $y * 0.5, $y)), 'Crosses 2');
41             ok(!line2( $x * 0.5, $x)->crossOver(line2( $y * 0.5, $y)), 'Crosses 3');
42            
43            
44            
45             =head2 Description
46            
47             Manipulate lines in 2D space
48            
49             =cut
50            
51            
52             package Math::Zap::Line2;
53             $VERSION=1.07;
54 5     5   2203 use Math::Zap::Vector2 check=>'vector2Check';
  5         10  
  5         144  
55 5     5   3042 use Math::Zap::Matrix2 new2v=>'matrix2New2v';
  5         35  
  5         138  
56 5     5   24 use Carp;
  5         9  
  5         297  
57 5     5   23 use constant debug => 0; # Debugging level
  5         9  
  5         5046  
58            
59            
60             =head2 Constructors
61            
62            
63             =head3 new
64            
65             Create a line from two vectors
66            
67             =cut
68            
69            
70 53     53 1 60 sub new($$)
71             {vector2Check(@_) if debug;
72 53         137 my $l = bless {a=>$_[0], b=>$_[1]};
73 53         116 short($l, 1);
74 53         223 $l;
75             }
76            
77            
78             =head3 line2
79            
80             Create a line from two vectors
81            
82             =cut
83            
84            
85 53     53 1 117 sub line2($$) {new($_[0],$_[1])};
86            
87            
88             =head2 Methods
89            
90            
91             =head3 accuracy
92            
93             Get/Set accuracy for comparisons
94            
95             =cut
96            
97            
98             my $accuracy = 1e-10;
99            
100             sub accuracy
101 0 0   0 1 0 {return $accuracy unless scalar(@_);
102 0         0 $accuracy = shift();
103             }
104            
105            
106             =head3 short
107            
108             Short line?
109            
110             =cut
111            
112            
113 53     53 1 65 sub short($$)
114             {my $l = shift; # Line
115 53         64 my $a = 1e-4; # Accuracy
116 53         67 my $A = shift; # Action 0: return indicator, 1: confess
117 53         250 my $n =
118             ($l->{a}{x}-$l->{b}{x})**2 + ($l->{a}{y}-$l->{b}{y})**2
119             < $a;
120 53 50 33     129 confess "Short line2" if $n and $A;
121 53         94 $n;
122             }
123            
124            
125             =head3 check
126            
127             Check its a line
128            
129             =cut
130            
131            
132 170 50       463 sub check(@)
133 85     85 1 97 {unless (debug)
134 85         135 {for my $l(@_)
135             {confess "$l is not a line" unless ref($l) eq __PACKAGE__;
136             }
137             }
138 85         180 @_;
139             }
140            
141            
142             =head3 is
143            
144             Test its a line
145            
146             =cut
147            
148            
149 0 0       0 sub is(@)
150 0     0 1 0 {for my $l(@_)
151             {return 0 unless ref($l) eq __PACKAGE__;
152             }
153 0         0 'line2';
154             }
155            
156            
157             =head3 a,b,ab,ba
158            
159             Components of line
160            
161             =cut
162            
163            
164 116     116 1 130 sub a($) {check(@_) if (debug); $_[0]->{a}}
  116         341  
165 36     36 1 43 sub b($) {check(@_) if (debug); $_[0]->{b}}
  36         123  
166 143     143 1 214 sub ab($) {check(@_) if (debug); vector2($_[0]->{b}{x}-$_[0]->{a}{x}, $_[0]->{b}{y}-$_[0]->{a}{y})}
  143         4375  
167 33     33 1 42 sub ba($) {check(@_) if (debug); $_[0]->a-$_[0]->b}
  33         78  
168            
169            
170             =head3 clone
171            
172             Create a line from another line
173            
174             =cut
175            
176            
177 0     0 1 0 sub clone($)
178             {my ($l) = check(@_); # Lines
179 0         0 bless {a=>$l->a, b=>$l->b};
180             }
181            
182            
183             =head3 print
184            
185             Print line
186            
187             =cut
188            
189            
190 0     0 1 0 sub print($)
191             {my ($l) = check(@_); # Lines
192 0         0 my ($a, $b) = ($l->a, $l->b);
193 0         0 my ($A, $B) = ($a->print, $b->print);
194 0         0 "line2($A, $B)";
195             }
196            
197            
198             =head3 angle
199            
200             Angle between two lines
201            
202             =cut
203            
204            
205 0     0 1 0 sub angle($$)
206             {my ($a, $b) = check(@_); # Lines
207 0         0 $a->a-$a->b < $b->a-$b->b;
208             }
209            
210            
211             =head3 parallel
212            
213             Are two lines parallel
214            
215             =cut
216            
217            
218 48     48 1 98 sub parallel($$)
219             {my ($a, $b) = check(@_); # Lines
220            
221             # return 1 if abs(1 - abs($a->ab->norm * $b->ab->norm)) < $accuracy;
222 48 100       115 return 1 if abs(1 - abs($a->ab->norm * $b->ab->norm)) < 1e-3;
223 40         269 0;
224             }
225            
226            
227             =head3 intersect
228            
229             Intersection of two lines
230            
231             =cut
232            
233            
234 14     14 1 39 sub intersect($$)
235             {my ($a, $b) = check(@_); # Lines
236            
237 14 50       37 return 0 if $a->parallel($b);
238 14         36 my $i = matrix2New2v($a->ab, $b->ba) / ($b->a - $a->a);
239            
240 14         88 $a->a+$i->x*$a->ab;
241             }
242            
243            
244             =head3 intersectWithin
245            
246             Intersection of two lines occurs within second line?
247            
248             =cut
249            
250            
251 11     11 1 35 sub intersectWithin($$)
252             {my ($a, $b) = check(@_); # Lines
253            
254 11 100       28 return 0 if $a->parallel($b);
255 10         25 my $i = matrix2New2v($a->ab, $b->ba) / ($b->a - $a->a);
256            
257 10 100       74 0 <= $i->y and $i->y <= 1;
258             }
259            
260            
261             =head3 crossOver
262            
263             Do the two line segments cross over each other?
264            
265             =cut
266            
267            
268 12     12 1 24 sub crossOver($$)
269             {my ($a, $b) = check(@_); # Lines
270            
271 12 100       28 return 0 if $a->parallel($b);
272 9         23 my $i = matrix2New2v($a->ab, $b->ba) / ($b->a - $a->a);
273            
274 9 100 66     53 0 <= $i->x and $i->x <= 1 and 0 <= $i->y and $i->y <= 1;
      100        
275             }
276            
277            
278             =head2 Exports
279            
280             Export L
281            
282             =cut
283            
284            
285 5         26 use Math::Zap::Exports qw(
286             line2 ($$)
287 5     5   27 );
  5         5  
288            
289             #_ Line2 ______________________________________________________________
290             # Package loaded successfully
291             #______________________________________________________________________
292            
293             1;
294            
295            
296             =head2 Credits
297            
298             =head3 Author
299            
300             philiprbrenan@yahoo.com
301            
302             =head3 Copyright
303            
304             philiprbrenan@yahoo.com, 2004
305            
306             =head3 License
307            
308             Perl License.
309            
310            
311             =cut