File Coverage

blib/lib/Tk/Image/Calculation.pm
Criterion Covered Total %
statement 477 505 94.4
branch 90 128 70.3
condition 24 48 50.0
subroutine 19 19 100.0
pod 15 16 93.7
total 625 716 87.2


line stmt bran cond sub pod time code
1             package Tk::Image::Calculation;
2            
3 1     1   78131 use strict;
  1         2  
  1         34  
4 1     1   6 use warnings;
  1         2  
  1         4518  
5            
6             #-------------------------------------------------
7             $Tk::Image::Calculation::VERSION = '0.05';
8             #-------------------------------------------------
9            
10             sub new
11             {
12 31     31 0 265 my ($class, @args) = @_;
13 31         164 my $self = {@args};
14 31   33     159 bless($self, $class || ref($class));
15            
16             #-------------------------------------------------
17 31 100 66     272 if(defined($self->{-points}) && defined($self->{-form}))
18             {
19             FORM:
20             {
21 30 50       123 $self->{-subset} = "all" if(!(defined($self->{-subset})));
  30         115  
22            
23             ($self->{-form} eq "oval") && do
24 30 100       134 {
25             OVAL:
26             {
27 10         28 ($self->{-subset} eq "lines_outside") && do
28 10 100       39 {
29 2         5 $self->GetLinesOutOval(@{$self->{-points}});
  2         11  
30 2         7 last(FORM);
31             };
32             ($self->{-subset} eq "points_outside") && do
33 8 100       26 {
34 2         5 $self->GetPointsOutOval(@{$self->{-points}});
  2         10  
35 2         14 last(FORM);
36             };
37             ($self->{-subset} eq "points_inside") && do
38 6 100       22 {
39 2         5 $self->GetPointsInOval(@{$self->{-points}});
  2         27  
40 2         12 last(FORM);
41             };
42             ($self->{-subset} eq "lines_inside") && do
43 4 100       16 {
44 2         5 $self->GetLinesInOval(@{$self->{-points}});
  2         11  
45 2         7 last(FORM);
46             };
47             ($self->{-subset} eq "all") && do
48 2 50       9 {
49 2         45 $self->GetPointsOval(@{$self->{-points}});
  2         14  
50 2         15 last(FORM);
51             };
52             }
53             };
54            
55             ($self->{-form} eq "circle") && do
56 20 100       88 {
57             CIRCLE:
58             {
59 10         20 ($self->{-subset} eq "lines_outside") && do
60 10 100       40 {
61 2         6 $self->GetLinesOutCircle(@{$self->{-points}});
  2         14  
62 2         7 last(FORM);
63             };
64             ($self->{-subset} eq "points_outside") && do
65 8 100       26 {
66 2         3 $self->GetPointsOutCircle(@{$self->{-points}});
  2         12  
67 2         14 last(FORM);
68             };
69             ($self->{-subset} eq "points_inside") && do
70 6 100       21 {
71 2         6 $self->GetPointsInCircle(@{$self->{-points}});
  2         14  
72 2         14 last(FORM);
73             };
74             ($self->{-subset} eq "lines_inside") && do
75 4 100       15 {
76 2         5 $self->GetLinesInCircle(@{$self->{-points}});
  2         11  
77 2         6 last(FORM);
78             };
79             ($self->{-subset} eq "all") && do
80 2 50       10 {
81 2         4 $self->GetPointsCircle(@{$self->{-points}});
  2         12  
82 2         13 last(FORM);
83             };
84             }
85             };
86            
87             ($self->{-form} eq "polygon") && do
88 10 50       48 {
89             POLYGON:
90             {
91 10         25 ($self->{-subset} eq "lines_outside") && do
92 10 100       43 {
93 2         7 $self->GetLinesOutPolygon(@{$self->{-points}});
  2         14  
94 2         11 last(FORM);
95             };
96             ($self->{-subset} eq "points_outside") && do
97 8 100       32 {
98 2         5 $self->GetPointsOutPolygon(@{$self->{-points}});
  2         28  
99 2         13 last(FORM);
100             };
101             ($self->{-subset} eq "lines_inside") && do
102 6 100       30 {
103 2         6 $self->GetLinesInPolygon(@{$self->{-points}});
  2         13  
104 2         12 last(FORM);
105             };
106             ($self->{-subset} eq "points_inside") && do
107 4 100       19 {
108 2         5 $self->GetPointsInPolygon(@{$self->{-points}});
  2         14  
109 2         11 last(FORM);
110             };
111             ($self->{-subset} eq "all") && do
112 2 50       9 {
113 2         6 $self->GetPointsPolygon(@{$self->{-points}});
  2         12  
114 2         17 last(FORM);
115             };
116             }
117             };
118            
119 0         0 warn("wrong args in call to Tk::Image::Calculation::new()\n");
120             }
121             }
122             #-------------------------------------------------
123 31         13792 return($self);
124             }
125            
126             #-------------------------------------------------
127             # OVAL
128             #-------------------------------------------------
129             sub GetPointsOval
130             {
131 4     4 1 16 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
132 4         25 my (@points_out, @points_in, @lines_out, @lines_in);
133 4         0 my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
134 4         0 my ($y, $y1, $y2);
135 4         0 my $diff;
136 4 50       15 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
137 4 50       16 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
138 4         10 my $width = ($p_x2 - $p_x1);
139 4         11 my $height= ($p_y2 - $p_y1);
140            
141 4 50 33     34 if(($width < 5) || ($height < 5))
142             {
143 0         0 $self->{points_outside} = [];
144 0         0 $self->{points_inside} = [];
145 0         0 $self->{lines_outside} = [];
146 0         0 $self->{lines_inside} = [];
147            
148             return({
149 0         0 points_outside => [],
150             points_inside => [],
151             lines_outside => [],
152             lines_inside => []
153             });
154             }
155            
156 4         16 my $a = ($width / 2);
157 4         11 my $a2 = $a ** 2;
158 4         9 my $b = ($height / 2);
159 4         12 my $c = ($b / $a);
160 4         8 my $pos_x = ($a + $p_x1);
161            
162 4         13 for(my $x = 0; $x <= $a; $x++)
163             {
164 124         277 $diff = int($c * sqrt($a2 - ($x ** 2)));
165 124         168 $y1 = ($b - $diff);
166 124         172 $y2 = ($b + $diff);
167 124         153 $pos_y1 = ($y1 + $p_y1);
168 124         163 $pos_y2 = ($y2 + $p_y1);
169 124         166 $pos_x_p = int($x + $pos_x);
170 124         164 $pos_x_n = int(-$x + $pos_x);
171            
172 124         237 push(@lines_out, [$pos_x_p, $p_y1, $pos_x_p, $pos_y1]);
173 124         239 push(@lines_out, [$pos_x_n, $p_y1, $pos_x_n, $pos_y1]);
174 124         258 push(@lines_in, [$pos_x_p, $pos_y1, $pos_x_p, $pos_y2]);
175 124         232 push(@lines_in, [$pos_x_n, $pos_y1, $pos_x_n, $pos_y2]);
176 124         242 push(@lines_out, [$pos_x_p, $pos_y2, $pos_x_p, $p_y2]);
177 124         237 push(@lines_out, [$pos_x_n, $pos_y2, $pos_x_n, $p_y2]);
178            
179 124         264 for($y = 0; $y <= $y1; $y++)
180             {
181 1418         1877 $pos_y1 = ($y + $p_y1);
182 1418         2376 push(@points_out, [$pos_x_p, $pos_y1]);
183 1418         3217 push(@points_out, [$pos_x_n, $pos_y1]);
184             }
185            
186 124         224 for($y = $y1; $y <= $y2; $y++)
187             {
188 8616         11025 $pos_y1 = ($y + $p_y1);
189 8616         13758 push(@points_in, [$pos_x_p, $pos_y1]);
190 8616         19049 push(@points_in, [$pos_x_n, $pos_y1]);
191             }
192            
193 124         240 for($y = $y2; $y <= $height; $y++)
194             {
195 1418         1780 $pos_y1 = ($y + $p_y1);
196 1418         2675 push(@points_out, [$pos_x_p, $pos_y1]);
197 1418         3275 push(@points_out, [$pos_x_n, $pos_y1]);
198             }
199             }
200 4         23 $self->{points_outside} = \@points_out;
201 4         14 $self->{points_inside} = \@points_in;
202 4         11 $self->{lines_outside} = \@lines_out;
203 4         10 $self->{lines_inside} = \@lines_in;
204            
205             return({
206 4         49 points_outside => \@points_out,
207             points_inside => \@points_in,
208             lines_outside => \@lines_out,
209             lines_inside => \@lines_in
210             });
211             }
212            
213             #-------------------------------------------------
214             sub GetPointsInOval
215             {
216 4     4 1 15 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
217 4         18 my ($pos_x_p, $pos_x_n, $pos_y1);
218 4         0 my ($y, $y1, $y2);
219 4         0 my $diff;
220 4 50       13 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
221 4 50       13 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
222 4         9 my $width = ($p_x2 - $p_x1);
223 4         8 my $height= ($p_y2 - $p_y1);
224            
225 4 50 33     20 if(($width < 5) || ($height < 5))
226             {
227 0         0 $self->{points_inside} = [];
228 0         0 return([]);
229             }
230            
231 4         13 my $a = ($width / 2);
232 4         10 my $a2 = ($a**2);
233 4         9 my $b = ($height / 2);
234 4         9 my $c = ($b / $a);
235 4         6 my $pos_x = ($a + $p_x1);
236 4         8 my @points_in;
237            
238 4         13 for(my $x = 0; $x <= $a; $x++)
239             {
240 124         282 $diff = int($c * sqrt($a2 - ($x**2)));
241 124         166 $y1 = ($b - $diff);
242 124         168 $y2 = ($b + $diff);
243 124         164 $pos_x_p = int($x + $pos_x);
244 124         169 $pos_x_n = int(-$x + $pos_x);
245            
246 124         220 for($y = $y1; $y <= $y2; $y++)
247             {
248 8616         11346 $pos_y1 = ($y + $p_y1);
249 8616         15838 push(@points_in, [$pos_x_p, $pos_y1]);
250 8616         19932 push(@points_in, [$pos_x_n, $pos_y1]);
251             }
252             }
253 4         17 $self->{points_inside} = \@points_in;
254 4         168 return(\@points_in);
255             }
256            
257             #-------------------------------------------------
258             sub GetPointsOutOval
259             {
260 4     4 1 15 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
261 4         18 my ($pos_x_p, $pos_x_n, $pos_y1);
262 4         0 my ($y, $y1, $y2);
263 4         0 my $diff;
264 4 50       11 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
265 4 50       14 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
266 4         10 my $width = ($p_x2 - $p_x1);
267 4         8 my $height= ($p_y2 - $p_y1);
268            
269 4 50 33     23 if(($width < 5) || ($height < 5))
270             {
271 0         0 $self->{points_outside} = [];
272 0         0 return([]);
273             }
274            
275 4         10 my $a = ($width / 2);
276 4         10 my $a2 = ($a**2);
277 4         9 my $b = ($height / 2);
278 4         9 my $c = ($b / $a);
279 4         8 my $pos_x = ($a + $p_x1);
280 4         7 my @points_out;
281            
282 4         14 for(my $x = 0; $x <= $a; $x++)
283             {
284 124         250 $diff = int($c * sqrt($a2 - ($x**2)));
285 124         170 $y1 = ($b - $diff);
286 124         161 $y2 = ($b + $diff);
287 124         160 $pos_x_p = int($x + $pos_x);
288 124         186 $pos_x_n = int(-$x + $pos_x);
289            
290 124         224 for($y = 0; $y <= $y1; $y++)
291             {
292 1418         1851 $pos_y1 = ($y + $p_y1);
293 1418         2638 push(@points_out, [$pos_x_p, $pos_y1]);
294 1418         3825 push(@points_out, [$pos_x_n, $pos_y1]);
295             }
296            
297 124         226 for($y = $y2; $y <= $height; $y++)
298             {
299 1418         1843 $pos_y1 = ($y + $p_y1);
300 1418         2514 push(@points_out, [$pos_x_p, $pos_y1]);
301 1418         3650 push(@points_out, [$pos_x_n, $pos_y1]);
302             }
303             }
304            
305 4         44 $self->{points_outside} = \@points_out;
306 4         76 return(\@points_out);
307             }
308            
309             #-------------------------------------------------
310             sub GetLinesInOval
311             {
312 4     4 1 13 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
313 4         16 my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
314 4         0 my ($y, $y1, $y2);
315 4         0 my $diff;
316 4 50       14 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
317 4 50       10 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
318 4         8 my $width = ($p_x2 - $p_x1);
319 4         8 my $height= ($p_y2 - $p_y1);
320            
321 4 50 33     19 if(($width < 5) || ($height < 5))
322             {
323 0         0 $self->{lines_inside} = [];
324 0         0 return([]);
325             }
326            
327 4         13 my $a = ($width / 2);
328 4         10 my $a2 = ($a**2);
329 4         10 my $b = ($height / 2);
330 4         8 my $c = ($b / $a);
331 4         8 my $pos_x = ($a + $p_x1);
332 4         7 my @lines_in;
333            
334 4         13 for(my $x = 0; $x <= $a; $x++)
335             {
336 124         195 $diff = int($c * sqrt($a2 - ($x**2)));
337 124         156 $y1 = ($b - $diff);
338 124         156 $y2 = ($b + $diff);
339 124         156 $pos_x_p = int($x + $pos_x);
340 124         194 $pos_x_n = int(-$x + $pos_x);
341 124         157 $pos_y1 = ($y1 + $p_y1);
342 124         153 $pos_y2 = ($y2 + $p_y1);
343 124         273 push(@lines_in, [$pos_x_p, $pos_y1, $pos_x_p, $pos_y2]);
344 124         285 push(@lines_in, [$pos_x_n, $pos_y1, $pos_x_n, $pos_y2]);
345             }
346            
347 4         16 $self->{lines_inside} = \@lines_in;
348 4         37 return(\@lines_in);
349             }
350            
351             #-------------------------------------------------
352             sub GetLinesOutOval
353             {
354 4     4 1 17 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
355 4         20 my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
356 4         0 my ($y, $y1, $y2);
357 4         0 my $diff;
358 4 50       16 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
359 4 50       10 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
360 4         8 my $width = ($p_x2 - $p_x1);
361 4         8 my $height= ($p_y2 - $p_y1);
362            
363 4 50 33     21 if(($width < 5) || ($height < 5))
364             {
365 0         0 $self->{lines_outside} = [];
366 0         0 return([]);
367             }
368            
369 4         12 my $a = ($width / 2);
370 4         11 my $a2 = ($a**2);
371 4         8 my $b = ($height / 2);
372 4         7 my $c = ($b / $a);
373 4         9 my $pos_x = ($a + $p_x1);
374 4         6 my @lines_out;
375            
376 4         15 for(my $x = 0; $x <= $a; $x++)
377             {
378 124         206 $diff = int($c * sqrt($a2 - ($x**2)));
379 124         149 $y1 = ($b - $diff);
380 124         162 $y2 = ($b + $diff);
381 124         155 $pos_x_p = int($x + $pos_x);
382 124         167 $pos_x_n = int(-$x + $pos_x);
383 124         153 $pos_y1 = ($y1 + $p_y1);
384 124         154 $pos_y2 = ($y2 + $p_y1);
385 124         214 push(@lines_out, [$pos_x_p, $p_y1, $pos_x_p, $pos_y1]);
386 124         212 push(@lines_out, [$pos_x_n, $p_y1, $pos_x_n, $pos_y1]);
387 124         283 push(@lines_out, [$pos_x_p, $pos_y2, $pos_x_p, $p_y2]);
388 124         308 push(@lines_out, [$pos_x_n, $pos_y2, $pos_x_n, $p_y2]);
389             }
390            
391 4         19 $self->{lines_outside} = \@lines_out;
392 4         24 return(\@lines_out);
393             }
394            
395             #-------------------------------------------------
396             # CIRCLE
397             #-------------------------------------------------
398             sub GetPointsCircle
399             {
400 4     4 1 14 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
401 4         26 my (@points_out, @points_in, @lines_out, @lines_in);
402 4         0 my ($x2py2, $pos_x, $pos_y1, $pos_y2);
403 4         0 my ($i_x2, $i_y);
404 4         0 my $diff_y;
405 4 50       15 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
406 4 50       15 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
407 4         9 my $width = ($p_x2 - $p_x1);
408 4         10 my $height= ($p_y2 - $p_y1);
409            
410 4 50 33     25 if(($width < 5) || ($height < 5))
411             {
412 0         0 $self->{points_outside} = [];
413 0         0 $self->{points_inside} = [];
414 0         0 $self->{lines_outside} = [];
415 0         0 $self->{lines_inside} = [];
416            
417             return({
418 0         0 points_outside => [],
419             points_inside => [],
420             lines_outside => [],
421             lines_inside => []
422             });
423             }
424            
425 4         14 my $r = int($width / 2);
426 4         9 my $r2 = ($r**2);
427 4         7 my $coord_x = ($p_x1 + $r);
428 4         8 my $coord_y = ($p_y1 + $r);
429 4         18 for(my $i_x = -$r; $i_x <= $r; $i_x++)
430             {
431 284         445 $i_x2 = ($i_x ** 2);
432 284         511 $diff_y = int(sqrt($r2 - $i_x2));
433 284         493 $pos_x = ($coord_x + $i_x);
434 284         414 $pos_y1 = ($coord_y + $diff_y);
435 284         399 $pos_y2 = ($coord_y - $diff_y);
436            
437 284         637 push(@lines_out, [$pos_x, $p_y1, $pos_x, $pos_y2]);
438 284         573 push(@lines_out, [$pos_x, $pos_y1, $pos_x, $p_y2]);
439 284         560 push(@lines_in, [$pos_x, $pos_y2, $pos_x, $pos_y1]);
440            
441 284         556 for($i_y = $r; $i_y >= -$r; $i_y--)
442             {
443 23764         30818 $pos_y1 = ($coord_y + $i_y);
444 23764         31961 $x2py2 = ($i_x2 + ($i_y ** 2));
445            
446 23764 100       38411 if($x2py2 < $r2)
    100          
447             {
448 18140         40110 push(@points_in, [$pos_x, $pos_y1]);
449             }
450             elsif($x2py2 > $r2)
451             {
452 5560         12626 push(@points_out, [$pos_x, $pos_y1]);
453             }
454             }
455             }
456            
457 4         44 $self->{points_outside} = \@points_out;
458 4         71 $self->{points_inside} = \@points_in;
459 4         12 $self->{lines_outside} = \@lines_out;
460 4         16 $self->{lines_inside} = \@lines_in;
461            
462             return({
463 4         56 points_outside => \@points_out,
464             points_inside => \@points_in,
465             lines_outside => \@lines_out,
466             lines_inside => \@lines_in
467             });
468             }
469            
470             #-------------------------------------------------
471             sub GetPointsInCircle
472             {
473 4     4 1 16 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
474 4         7 my ($x2py2, $i_y);
475 4 50       16 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
476 4 50       14 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
477 4         8 my $width = ($p_x2 - $p_x1);
478 4         9 my $height= ($p_y2 - $p_y1);
479            
480 4 50 33     26 if(($width < 5) || ($height < 5))
481             {
482 0         0 $self->{points_inside} = [];
483 0         0 return([]);
484             }
485            
486 4         15 my $r = int($width / 2);
487 4         9 my $r2 = ($r ** 2);
488 4         9 my $coord_x = ($p_x1 + $r);
489 4         9 my $coord_y = ($p_y1 + $r);
490 4         6 my @points_in;
491            
492 4         18 for(my $i_x = -$r; $i_x <= $r; $i_x++)
493             {
494 284         529 for($i_y = $r; $i_y >= -$r; $i_y--)
495             {
496 23764         33661 $x2py2 = (($i_x ** 2) + ($i_y ** 2));
497 23764 100       41391 if($x2py2 < $r2)
498             {
499 18140         39529 push(@points_in, [($coord_x + $i_x), ($coord_y + $i_y)]);
500             }
501             }
502             }
503            
504 4         29 $self->{points_inside} = \@points_in;
505 4         386 return(\@points_in);
506             }
507            
508             #-------------------------------------------------
509             sub GetPointsOutCircle
510             {
511 4     4 1 13 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
512 4         9 my ($x2py2, $i_y);
513 4 50       13 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
514 4 50       10 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
515 4         9 my $width = ($p_x2 - $p_x1);
516 4         9 my $height= ($p_y2 - $p_y1);
517            
518 4 50 33     20 if(($width < 5) || ($height < 5))
519             {
520 0         0 $self->{points_outside} = [];
521 0         0 return([]);
522             }
523            
524 4         15 my $r = int($width / 2);
525 4         26 my $r2 = ($r ** 2);
526 4         9 my $coord_x = ($p_x1 + $r);
527 4         9 my $coord_y = ($p_y1 + $r);
528 4         7 my @points_out;
529            
530 4         35 for(my $i_x = -$r; $i_x <= $r; $i_x++)
531             {
532 284         530 for($i_y = $r; $i_y >= -$r; $i_y--)
533             {
534 23764         33645 $x2py2 = (($i_x ** 2) + ($i_y ** 2));
535 23764 100       46421 if($x2py2 > $r2)
536             {
537 5560         13079 push(@points_out, [($coord_x + $i_x), ($coord_y + $i_y)]);
538             }
539             }
540             }
541            
542 4         77 $self->{points_outside} = \@points_out;
543 4         122 return(\@points_out);
544             }
545            
546             #-------------------------------------------------
547             sub GetLinesInCircle
548             {
549 4     4 1 13 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
550 4         8 my ($x2py2, $pos_x, $diff_y);
551 4 50       15 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
552 4 50       12 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
553 4         11 my $width = ($p_x2 - $p_x1);
554 4         8 my $height= ($p_y2 - $p_y1);
555            
556 4 50 33     22 if(($width < 5) || ($height < 5))
557             {
558 0         0 $self->{lines_inside} = [];
559 0         0 return([]);
560             }
561            
562 4         15 my $r = int($width / 2);
563 4         11 my $r2 = ($r ** 2);
564 4         7 my $coord_x = ($p_x1 + $r);
565 4         10 my $coord_y = ($p_y1 + $r);
566 4         5 my @lines_in;
567            
568 4         13 for(my $i_x = -$r; $i_x <= $r; $i_x++)
569             {
570 284         358 $pos_x = ($coord_x + $i_x);
571 284         409 $diff_y = int(sqrt($r2 - ($i_x ** 2)));
572 284         634 push(@lines_in, [$pos_x, ($coord_y - $diff_y), $pos_x, ($coord_y + $diff_y)]);
573             }
574            
575 4         23 $self->{lines_inside} = \@lines_in;
576 4         58 return(\@lines_in);
577             }
578            
579             #-------------------------------------------------
580             sub GetLinesOutCircle
581             {
582 4     4 1 12 my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
583 4         10 my ($x2py2, $pos_x, $diff_y);
584 4 50       17 ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
585 4 50       13 ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
586 4         10 my $width = ($p_x2 - $p_x1);
587 4         8 my $height= ($p_y2 - $p_y1);
588            
589 4 50 33     27 if(($width < 5) || ($height < 5))
590             {
591 0         0 $self->{lines_outside} = [];
592 0         0 return([]);
593             }
594            
595 4         12 my $r = int($width / 2);
596 4         9 my $r2 = ($r ** 2);
597 4         10 my $coord_x = ($p_x1 + $r);
598 4         9 my $coord_y = ($p_y1 + $r);
599 4         8 my @lines_out;
600            
601 4         16 for(my $i_x = -$r; $i_x <= $r; $i_x++)
602             {
603 284         362 $pos_x = ($coord_x + $i_x);
604 284         403 $diff_y = int(sqrt($r2 - ($i_x ** 2)));
605 284         529 push(@lines_out, [$pos_x, $p_y1, $pos_x, ($coord_y - $diff_y)]);
606 284         778 push(@lines_out, [$pos_x, ($coord_y + $diff_y), $pos_x, $p_y2]);
607             }
608            
609 4         34 $self->{lines_outside} = \@lines_out;
610 4         21 return(\@lines_out);
611             }
612            
613             #-------------------------------------------------
614             # POLYGON
615             #-------------------------------------------------
616             sub GetPointsPolygon
617             {
618 4     4 1 13 my ($self) = @_;
619 4         20 my $ref_p_x = _CalculatePolygon(@_);
620 4         15 my (@points_out, @points_in, @lines_out, @lines_in);
621 4         11 my $i_1 = my $i_2 = my $i_3 = 0;
622 4         11 my $p_x_temp;
623            
624 4         23 for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
625             {
626 1164         1726 $p_x_temp = $self->{min_x};
627 1164         1832 for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  2422         6400  
628             {
629 1258         3601 push(@lines_in, [$ref_p_x->[$i_1][$i_2], $p_y, $ref_p_x->[$i_1][$i_2 + 1], $p_y]);
630 1258         2882 for($i_3 = $ref_p_x->[$i_1][$i_2]; $i_3 <= $ref_p_x->[$i_1][$i_2 + 1]; $i_3++)
631             {
632 283914         672507 push(@points_in, [$i_3, $p_y]);
633             }
634            
635 1258         3214 push(@lines_out, [$p_x_temp, $p_y, $ref_p_x->[$i_1][$i_2], $p_y]);
636 1258         2907 for($i_3 = $p_x_temp; $i_3 <= $ref_p_x->[$i_1][$i_2]; $i_3++)
637             {
638 28138         65021 push(@points_out, [$i_3, $p_y]);
639             }
640            
641 1258         2502 $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
642             }
643            
644 1164         3192 push(@lines_out, [$p_x_temp, $p_y, $self->{max_x}, $p_y]);
645 1164         2672 for($i_3 = $p_x_temp; $i_3 <= $self->{max_x}; $i_3++)
646             {
647 148576         341084 push(@points_out, [$i_3, $p_y]);
648             }
649            
650 1164         2759 $i_1++;
651             }
652            
653 4         28 $self->{lines_outside} = \@lines_out;
654 4         69 $self->{lines_inside} = \@lines_in;
655 4         100 $self->{points_outside} = \@points_out;
656 4         226 $self->{points_inside} = \@points_in;
657            
658             return({
659 4         586 lines_outside => \@lines_out,
660             lines_inside => \@lines_in,
661             points_outside => \@points_out,
662             points_inside => \@points_in,
663             });
664             }
665            
666             #-------------------------------------------------
667             sub GetPointsInPolygon
668             {
669 4     4 1 15 my ($self) = @_;
670 4         21 my $ref_p_x = _CalculatePolygon(@_);
671 4         52 my @points_in = ();
672 4         14 my $i_1 = my $i_2 = my $i_3 = 0;
673            
674 4         27 for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
675             {
676 1164         1890 for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  2422         5663  
677             {
678 1258         2804 for($i_3 = $ref_p_x->[$i_1][$i_2]; $i_3 <= $ref_p_x->[$i_1][$i_2 + 1]; $i_3++)
679             {
680 283914         676855 push(@points_in, [$i_3, $p_y]);
681             }
682             }
683            
684 1164         2806 $i_1++;
685             }
686            
687 4         25 $self->{points_inside} = \@points_in;
688 4         36985 return(\@points_in);
689             }
690            
691             #-------------------------------------------------
692             sub GetPointsOutPolygon
693             {
694 4     4 1 15 my ($self) = @_;
695 4         19 my $ref_p_x = _CalculatePolygon(@_);
696 4         12 my @points_out = ();
697 4         12 my $i_1 = my $i_2 = my $i_3 = 0;
698 4         8 my $p_x_temp;
699            
700 4         25 for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
701             {
702 1164         1764 $p_x_temp = $self->{min_x};
703 1164         1581 for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  2422         4999  
704             {
705 1258         2722 for($i_3 = $p_x_temp; $i_3 <= $ref_p_x->[$i_1][$i_2]; $i_3++)
706             {
707 28138         60023 push(@points_out, [$i_3, $p_y]);
708             }
709 1258         2030 $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
710             }
711            
712 1164         2291 for($i_3 = $p_x_temp; $i_3 <= $self->{max_x}; $i_3++)
713             {
714 148576         301840 push(@points_out, [$i_3, $p_y]);
715             }
716            
717 1164         2349 $i_1++;
718             }
719            
720 4         8050 $self->{points_outside} = \@points_out;
721 4         13480 return(\@points_out);
722             }
723            
724             #-------------------------------------------------
725             sub GetLinesInPolygon
726             {
727 4     4 1 14 my ($self) = @_;
728 4         22 my $ref_p_x = _CalculatePolygon(@_);
729 4         17 my @lines_in = ();
730 4         11 my $i_1 = my $i_2 = 0;
731            
732 4         17 for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
733             {
734 1164         1632 for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  2422         5368  
735             {
736 1258         3431 push(@lines_in, [$ref_p_x->[$i_1][$i_2], $p_y, $ref_p_x->[$i_1][$i_2 + 1], $p_y]);
737             }
738            
739 1164         2363 $i_1++;
740             }
741            
742 4         621 $self->{lines_inside} = \@lines_in;
743 4         12839 return(\@lines_in);
744             }
745            
746             #-------------------------------------------------
747             sub GetLinesOutPolygon
748             {
749 4     4 1 15 my ($self) = @_;
750 4         21 my $ref_p_x = _CalculatePolygon(@_);
751 4         19 my @lines_out = ();
752 4         12 my $i_1 = my $i_2 = 0;
753 4         9 my $p_x_temp;
754            
755 4         31 for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
756             {
757 1164         1575 $p_x_temp = $self->{min_x};
758 1164         1574 for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  2422         5005  
759             {
760 1258         3309 push(@lines_out, [$p_x_temp, $p_y, $ref_p_x->[$i_1][$i_2], $p_y]);
761 1258         2043 $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
762             }
763            
764 1164         2623 push(@lines_out, [$p_x_temp, $p_y, $self->{max_x}, $p_y]);
765 1164         2119 $i_1++;
766             }
767            
768 4         1271 $self->{lines_outside} = \@lines_out;
769 4         553 return(\@lines_out);
770             }
771            
772             #-------------------------------------------------
773             sub _CalculatePolygon
774             {
775 20     20   77 my ($self, @points) = @_;
776 20         44 my @p;
777            
778 20         109 for(my $i = 0; $i <= $#points; $i += 2)
779             {
780 110         369 push(@p, { x => $points[$i], y => $points[$i + 1]});
781             }
782            
783 20         98 push(@p, {x => $points[0], y => $points[1]});
784 20         42 my $points_count = $#p;
785 20 50       83 return([]) if($points_count < 3);
786            
787 20         72 my ($index_1, $index_2, $index_count);
788 20         0 my ($p_y, $p_y1, $p_y2, $p_x1, $p_x2, $p_x_temp);
789 20         41 my @points_outline_x = ();
790 20         39 my @all_points_outline_x = ();
791 20         43 my ($i, $j);
792 20         76 $self->{min_y} = $self->{max_y} = $p[0]{y};
793 20         68 $self->{min_x} = $self->{max_x} = $p[0]{x};
794            
795 20         88 for(0..$#p)
796             {
797 130 50       282 $self->{min_y} = $p[$_]{y} if($self->{min_y} > $p[$_]{y});
798 130 100       296 $self->{max_y} = $p[$_]{y} if($self->{max_y} < $p[$_]{y});
799 130 100       266 $self->{min_x} = $p[$_]{x} if($self->{min_x} > $p[$_]{x});
800 130 100       360 $self->{max_x} = $p[$_]{x} if($self->{max_x} < $p[$_]{x});
801             }
802            
803 20         106 for($p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
804             {
805 5820         8090 $index_count = 0;
806 5820         8931 @points_outline_x = ();
807 5820         10463 for($i = 0; $i < $points_count; $i++)
808             {
809 41510 100       63418 if(!$i)
810             {
811 5820         7902 $index_1 = $points_count - 1;
812 5820         7688 $index_2 = 0;
813             }
814             else
815             {
816 35690         45109 $index_1 = $i - 1;
817 35690         45633 $index_2 = $i;
818             }
819            
820 41510         58864 $p_y1 = $p[$index_1]{y};
821 41510         54451 $p_y2 = $p[$index_2]{y};
822            
823 41510 100       70402 if($p_y1 < $p_y2)
    50          
824             {
825 20250         27805 $p_x1 = $p[$index_1]{x};
826 20250         27136 $p_x2 = $p[$index_2]{x};
827             }
828             elsif ($p_y1 > $p_y2)
829             {
830 21260         28174 $p_y2 = $p[$index_1]{y};
831 21260         29650 $p_y1 = $p[$index_2]{y};
832 21260         29300 $p_x2 = $p[$index_1]{x};
833 21260         28607 $p_x1 = $p[$index_2]{x};
834             }
835             else
836             {
837 0         0 next;
838             }
839            
840 41510 100 100     134914 if(($p_y >= $p_y1) && ($p_y < $p_y2))
    100 66        
      100        
841             {
842 12540         33630 $points_outline_x[$index_count++] = int((($p_y - $p_y1) * ($p_x2 - $p_x1)) / ($p_y2 - $p_y1) + 0.5 + $p_x1);
843             }
844             elsif(($p_y == $self->{max_y}) && ($p_y > $p_y1) && ($p_y <= $p_y2))
845             {
846 40         122 $points_outline_x[$index_count++] = int((($p_y - $p_y1) * ($p_x2 - $p_x1)) / ($p_y2 - $p_y1) + 0.5 + $p_x1);
847             }
848             }
849            
850 5820         11212 for($i = 1; $i < $index_count; $i++)
851             {
852 6760         9156 $p_x_temp = $points_outline_x[$i];
853 6760         8989 $j = $i;
854            
855 6760   100     19552 while(($j > 0) && ($points_outline_x[$j - 1] > $p_x_temp))
856             {
857 6700         9658 $points_outline_x[$j] = $points_outline_x[$j - 1];
858 6700         13643 $j--;
859             }
860            
861 6760         12631 $points_outline_x[$j] = $p_x_temp;
862             }
863            
864 5820         38259 push(@all_points_outline_x, [@points_outline_x]);
865             }
866            
867 20         269 return(\@all_points_outline_x);
868             }
869            
870             1; # /Tk::Image::Calculation
871            
872            
873            
874             __END__