File Coverage

blib/lib/Tk/Image/Calculation.pm
Criterion Covered Total %
statement 6 505 1.1
branch 0 128 0.0
condition 0 48 0.0
subroutine 2 19 10.5
pod 16 16 100.0
total 24 716 3.3


line stmt bran cond sub pod time code
1             #*** Calculation.pm ***#
2             # Copyright (C) 2006 by Torsten Knorr
3             # create-soft@tiscali.de
4             # All rights reserved!
5             #-------------------------------------------------
6             package Tk::Image::Calculation;
7             #-------------------------------------------------
8 1     1   35814 use strict;
  1         3  
  1         78  
9 1     1   6 use warnings;
  1         1  
  1         5392  
10             #-------------------------------------------------
11             $Tk::Image::Calculation::VERSION = '0.04';
12             #-------------------------------------------------
13             sub new
14             {
15 0     0 1   my ($class, @args) = @_;
16 0           my $self = {@args};
17 0   0       bless($self, $class || ref($class));
18             =head1
19             -form => circle oval polygon
20             -points => [x1, y1, x2, y2]
21             -subset => all points_outside points_inside lines_outside lines_inside
22             =cut
23             #-------------------------------------------------
24 0 0 0       if(defined($self->{-points}) && defined($self->{-form}))
25             {
26 0 0         FORM:
27             {
28 0           $self->{-subset} = "all" if(!(defined($self->{-subset})));
29             ($self->{-form} eq "oval") && do
30 0 0         {
31             OVAL:
32             {
33 0           ($self->{-subset} eq "lines_outside") && do
34 0 0         {
35 0           $self->GetLinesOutOval(@{$self->{-points}});
  0            
36 0           last(FORM);
37             };
38             ($self->{-subset} eq "points_outside") && do
39 0 0         {
40 0           $self->GetPointsOutOval(@{$self->{-points}});
  0            
41 0           last(FORM);
42             };
43             ($self->{-subset} eq "points_inside") && do
44 0 0         {
45 0           $self->GetPointsInOval(@{$self->{-points}});
  0            
46 0           last(FORM);
47             };
48             ($self->{-subset} eq "lines_inside") && do
49 0 0         {
50 0           $self->GetLinesInOval(@{$self->{-points}});
  0            
51 0           last(FORM);
52             };
53             ($self->{-subset} eq "all") && do
54 0 0         {
55 0           $self->GetPointsOval(@{$self->{-points}});
  0            
56 0           last(FORM);
57             };
58             }
59             };
60             ($self->{-form} eq "circle") && do
61 0 0         {
62             CIRCLE:
63             {
64 0           ($self->{-subset} eq "lines_outside") && do
65 0 0         {
66 0           $self->GetLinesOutCircle(@{$self->{-points}});
  0            
67 0           last(FORM);
68             };
69             ($self->{-subset} eq "points_outside") && do
70 0 0         {
71 0           $self->GetPointsOutCircle(@{$self->{-points}});
  0            
72 0           last(FORM);
73             };
74             ($self->{-subset} eq "points_inside") && do
75 0 0         {
76 0           $self->GetPointsInCircle(@{$self->{-points}});
  0            
77 0           last(FORM);
78             };
79             ($self->{-subset} eq "lines_inside") && do
80 0 0         {
81 0           $self->GetLinesInCircle(@{$self->{-points}});
  0            
82 0           last(FORM);
83             };
84             ($self->{-subset} eq "all") && do
85 0 0         {
86 0           $self->GetPointsCircle(@{$self->{-points}});
  0            
87 0           last(FORM);
88             };
89             }
90             };
91             ($self->{-form} eq "polygon") && do
92 0 0         {
93             POLYGON:
94             {
95 0           ($self->{-subset} eq "lines_outside") && do
96 0 0         {
97 0           $self->GetLinesOutPolygon(@{$self->{-points}});
  0            
98 0           last(FORM);
99             };
100             ($self->{-subset} eq "points_outside") && do
101 0 0         {
102 0           $self->GetPointsOutPolygon(@{$self->{-points}});
  0            
103 0           last(FORM);
104             };
105             ($self->{-subset} eq "lines_inside") && do
106 0 0         {
107 0           $self->GetLinesInPolygon(@{$self->{-points}});
  0            
108 0           last(FORM);
109             };
110             ($self->{-subset} eq "points_inside") && do
111 0 0         {
112 0           $self->GetPointsInPolygon(@{$self->{-points}});
  0            
113 0           last(FORM);
114             };
115             ($self->{-subset} eq "all") && do
116 0 0         {
117 0           $self->GetPointsPolygon(@{$self->{-points}});
  0            
118 0           last(FORM);
119             };
120             }
121             };
122 0           warn("wrong args in call to Tk::Image::Calculation::new()\n");
123             }
124             }
125             #-------------------------------------------------
126 0           return($self);
127             }
128             #-------------------------------------------------
129             # OVAL
130             #-------------------------------------------------
131             sub GetPointsOval
132             {
133 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
134 0           my (@points_out, @points_in, @lines_out, @lines_in);
135 0           my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
136 0           my ($y, $y1, $y2);
137 0           my $diff;
138 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
139 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
140 0           my $width = ($p_x2 - $p_x1);
141 0           my $height= ($p_y2 - $p_y1);
142 0 0 0       if(($width < 5) || ($height < 5))
143             {
144 0           $self->{points_outside} = [];
145 0           $self->{points_inside} = [];
146 0           $self->{lines_outside} = [];
147 0           $self->{lines_inside} = [];
148             return({
149 0           points_outside => [],
150             points_inside => [],
151             lines_outside => [],
152             lines_inside => []
153             });
154             }
155 0           my $a = ($width / 2);
156 0           my $a2 = $a ** 2;
157 0           my $b = ($height / 2);
158 0           my $c = ($b / $a);
159 0           my $pos_x = ($a + $p_x1);
160 0           for(my $x = 0; $x <= $a; $x++)
161             {
162 0           $diff = int($c * sqrt($a2 - ($x ** 2)));
163 0           $y1 = ($b - $diff);
164 0           $y2 = ($b + $diff);
165 0           $pos_y1 = ($y1 + $p_y1);
166 0           $pos_y2 = ($y2 + $p_y1);
167 0           $pos_x_p = int($x + $pos_x);
168 0           $pos_x_n = int(-$x + $pos_x);
169 0           push(@lines_out, [$pos_x_p, $p_y1, $pos_x_p, $pos_y1]);
170 0           push(@lines_out, [$pos_x_n, $p_y1, $pos_x_n, $pos_y1]);
171 0           push(@lines_in, [$pos_x_p, $pos_y1, $pos_x_p, $pos_y2]);
172 0           push(@lines_in, [$pos_x_n, $pos_y1, $pos_x_n, $pos_y2]);
173 0           push(@lines_out, [$pos_x_p, $pos_y2, $pos_x_p, $p_y2]);
174 0           push(@lines_out, [$pos_x_n, $pos_y2, $pos_x_n, $p_y2]);
175 0           for($y = 0; $y <= $y1; $y++)
176             {
177 0           $pos_y1 = ($y + $p_y1);
178 0           push(@points_out, [$pos_x_p, $pos_y1]);
179 0           push(@points_out, [$pos_x_n, $pos_y1]);
180             }
181 0           for($y = $y1; $y <= $y2; $y++)
182             {
183 0           $pos_y1 = ($y + $p_y1);
184 0           push(@points_in, [$pos_x_p, $pos_y1]);
185 0           push(@points_in, [$pos_x_n, $pos_y1]);
186             }
187 0           for($y = $y2; $y <= $height; $y++)
188             {
189 0           $pos_y1 = ($y + $p_y1);
190 0           push(@points_out, [$pos_x_p, $pos_y1]);
191 0           push(@points_out, [$pos_x_n, $pos_y1]);
192             }
193             }
194 0           $self->{points_outside} = \@points_out;
195 0           $self->{points_inside} = \@points_in;
196 0           $self->{lines_outside} = \@lines_out;
197 0           $self->{lines_inside} = \@lines_in;
198             return({
199 0           points_outside => \@points_out,
200             points_inside => \@points_in,
201             lines_outside => \@lines_out,
202             lines_inside => \@lines_in
203             });
204             }
205             #-------------------------------------------------
206             sub GetPointsInOval
207             {
208 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
209 0           my ($pos_x_p, $pos_x_n, $pos_y1);
210 0           my ($y, $y1, $y2);
211 0           my $diff;
212 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
213 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
214 0           my $width = ($p_x2 - $p_x1);
215 0           my $height= ($p_y2 - $p_y1);
216 0 0 0       if(($width < 5) || ($height < 5))
217             {
218 0           $self->{points_inside} = [];
219 0           return([]);
220             }
221 0           my $a = ($width / 2);
222 0           my $a2 = ($a**2);
223 0           my $b = ($height / 2);
224 0           my $c = ($b / $a);
225 0           my $pos_x = ($a + $p_x1);
226 0           my @points_in;
227 0           for(my $x = 0; $x <= $a; $x++)
228             {
229 0           $diff = int($c * sqrt($a2 - ($x**2)));
230 0           $y1 = ($b - $diff);
231 0           $y2 = ($b + $diff);
232 0           $pos_x_p = int($x + $pos_x);
233 0           $pos_x_n = int(-$x + $pos_x);
234 0           for($y = $y1; $y <= $y2; $y++)
235             {
236 0           $pos_y1 = ($y + $p_y1);
237 0           push(@points_in, [$pos_x_p, $pos_y1]);
238 0           push(@points_in, [$pos_x_n, $pos_y1]);
239             }
240             }
241 0           $self->{points_inside} = \@points_in;
242 0           return(\@points_in);
243             }
244             #-------------------------------------------------
245             sub GetPointsOutOval
246             {
247 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
248 0           my ($pos_x_p, $pos_x_n, $pos_y1);
249 0           my ($y, $y1, $y2);
250 0           my $diff;
251 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
252 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
253 0           my $width = ($p_x2 - $p_x1);
254 0           my $height= ($p_y2 - $p_y1);
255 0 0 0       if(($width < 5) || ($height < 5))
256             {
257 0           $self->{points_outside} = [];
258 0           return([]);
259             }
260 0           my $a = ($width / 2);
261 0           my $a2 = ($a**2);
262 0           my $b = ($height / 2);
263 0           my $c = ($b / $a);
264 0           my $pos_x = ($a + $p_x1);
265 0           my @points_out;
266 0           for(my $x = 0; $x <= $a; $x++)
267             {
268 0           $diff = int($c * sqrt($a2 - ($x**2)));
269 0           $y1 = ($b - $diff);
270 0           $y2 = ($b + $diff);
271 0           $pos_x_p = int($x + $pos_x);
272 0           $pos_x_n = int(-$x + $pos_x);
273 0           for($y = 0; $y <= $y1; $y++)
274             {
275 0           $pos_y1 = ($y + $p_y1);
276 0           push(@points_out, [$pos_x_p, $pos_y1]);
277 0           push(@points_out, [$pos_x_n, $pos_y1]);
278             }
279 0           for($y = $y2; $y <= $height; $y++)
280             {
281 0           $pos_y1 = ($y + $p_y1);
282 0           push(@points_out, [$pos_x_p, $pos_y1]);
283 0           push(@points_out, [$pos_x_n, $pos_y1]);
284             }
285             }
286 0           $self->{points_outside} = \@points_out;
287 0           return(\@points_out);
288             }
289             #-------------------------------------------------
290             sub GetLinesInOval
291             {
292 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
293 0           my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
294 0           my ($y, $y1, $y2);
295 0           my $diff;
296 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
297 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
298 0           my $width = ($p_x2 - $p_x1);
299 0           my $height= ($p_y2 - $p_y1);
300 0 0 0       if(($width < 5) || ($height < 5))
301             {
302 0           $self->{lines_inside} = [];
303 0           return([]);
304             }
305 0           my $a = ($width / 2);
306 0           my $a2 = ($a**2);
307 0           my $b = ($height / 2);
308 0           my $c = ($b / $a);
309 0           my $pos_x = ($a + $p_x1);
310 0           my @lines_in;
311 0           for(my $x = 0; $x <= $a; $x++)
312             {
313 0           $diff = int($c * sqrt($a2 - ($x**2)));
314 0           $y1 = ($b - $diff);
315 0           $y2 = ($b + $diff);
316 0           $pos_x_p = int($x + $pos_x);
317 0           $pos_x_n = int(-$x + $pos_x);
318 0           $pos_y1 = ($y1 + $p_y1);
319 0           $pos_y2 = ($y2 + $p_y1);
320 0           push(@lines_in, [$pos_x_p, $pos_y1, $pos_x_p, $pos_y2]);
321 0           push(@lines_in, [$pos_x_n, $pos_y1, $pos_x_n, $pos_y2]);
322             }
323 0           $self->{lines_inside} = \@lines_in;
324 0           return(\@lines_in);
325             }
326             #-------------------------------------------------
327             sub GetLinesOutOval
328             {
329 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
330 0           my ($pos_x_p, $pos_x_n, $pos_y1, $pos_y2);
331 0           my ($y, $y1, $y2);
332 0           my $diff;
333 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
334 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
335 0           my $width = ($p_x2 - $p_x1);
336 0           my $height= ($p_y2 - $p_y1);
337 0 0 0       if(($width < 5) || ($height < 5))
338             {
339 0           $self->{lines_outside} = [];
340 0           return([]);
341             }
342 0           my $a = ($width / 2);
343 0           my $a2 = ($a**2);
344 0           my $b = ($height / 2);
345 0           my $c = ($b / $a);
346 0           my $pos_x = ($a + $p_x1);
347 0           my @lines_out;
348 0           for(my $x = 0; $x <= $a; $x++)
349             {
350 0           $diff = int($c * sqrt($a2 - ($x**2)));
351 0           $y1 = ($b - $diff);
352 0           $y2 = ($b + $diff);
353 0           $pos_x_p = int($x + $pos_x);
354 0           $pos_x_n = int(-$x + $pos_x);
355 0           $pos_y1 = ($y1 + $p_y1);
356 0           $pos_y2 = ($y2 + $p_y1);
357 0           push(@lines_out, [$pos_x_p, $p_y1, $pos_x_p, $pos_y1]);
358 0           push(@lines_out, [$pos_x_n, $p_y1, $pos_x_n, $pos_y1]);
359 0           push(@lines_out, [$pos_x_p, $pos_y2, $pos_x_p, $p_y2]);
360 0           push(@lines_out, [$pos_x_n, $pos_y2, $pos_x_n, $p_y2]);
361             }
362 0           $self->{lines_outside} = \@lines_out;
363 0           return(\@lines_out);
364             }
365             #-------------------------------------------------
366             # CIRCLE
367             #-------------------------------------------------
368             sub GetPointsCircle
369             {
370 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
371 0           my (@points_out, @points_in, @lines_out, @lines_in);
372 0           my ($x2py2, $pos_x, $pos_y1, $pos_y2);
373 0           my ($i_x2, $i_y);
374 0           my $diff_y;
375 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
376 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
377 0           my $width = ($p_x2 - $p_x1);
378 0           my $height= ($p_y2 - $p_y1);
379 0 0 0       if(($width < 5) || ($height < 5))
380             {
381 0           $self->{points_outside} = [];
382 0           $self->{points_inside} = [];
383 0           $self->{lines_outside} = [];
384 0           $self->{lines_inside} = [];
385             return({
386 0           points_outside => [],
387             points_inside => [],
388             lines_outside => [],
389             lines_inside => []
390             });
391             }
392 0           my $r = int($width / 2);
393 0           my $r2 = ($r**2);
394 0           my $coord_x = ($p_x1 + $r);
395 0           my $coord_y = ($p_y1 + $r);
396 0           for(my $i_x = -$r; $i_x <= $r; $i_x++)
397             {
398 0           $i_x2 = ($i_x ** 2);
399 0           $diff_y = int(sqrt($r2 - $i_x2));
400 0           $pos_x = ($coord_x + $i_x);
401 0           $pos_y1 = ($coord_y + $diff_y);
402 0           $pos_y2 = ($coord_y - $diff_y);
403 0           push(@lines_out, [$pos_x, $p_y1, $pos_x, $pos_y2]);
404 0           push(@lines_out, [$pos_x, $pos_y1, $pos_x, $p_y2]);
405 0           push(@lines_in, [$pos_x, $pos_y2, $pos_x, $pos_y1]);
406 0           for($i_y = $r; $i_y >= -$r; $i_y--)
407             {
408 0           $pos_y1 = ($coord_y + $i_y);
409 0           $x2py2 = ($i_x2 + ($i_y ** 2));
410 0 0         if($x2py2 < $r2)
    0          
411             {
412 0           push(@points_in, [$pos_x, $pos_y1]);
413             }
414             elsif($x2py2 > $r2)
415             {
416 0           push(@points_out, [$pos_x, $pos_y1]);
417             }
418             }
419             }
420 0           $self->{points_outside} = \@points_out;
421 0           $self->{points_inside} = \@points_in;
422 0           $self->{lines_outside} = \@lines_out;
423 0           $self->{lines_inside} = \@lines_in;
424             return({
425 0           points_outside => \@points_out,
426             points_inside => \@points_in,
427             lines_outside => \@lines_out,
428             lines_inside => \@lines_in
429             });
430             }
431             #-------------------------------------------------
432             sub GetPointsInCircle
433             {
434 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
435 0           my ($x2py2, $i_y);
436 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
437 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
438 0           my $width = ($p_x2 - $p_x1);
439 0           my $height= ($p_y2 - $p_y1);
440 0 0 0       if(($width < 5) || ($height < 5))
441             {
442 0           $self->{points_inside} = [];
443 0           return([]);
444             }
445 0           my $r = int($width / 2);
446 0           my $r2 = ($r ** 2);
447 0           my $coord_x = ($p_x1 + $r);
448 0           my $coord_y = ($p_y1 + $r);
449 0           my @points_in;
450 0           for(my $i_x = -$r; $i_x <= $r; $i_x++)
451             {
452 0           for($i_y = $r; $i_y >= -$r; $i_y--)
453             {
454 0           $x2py2 = (($i_x ** 2) + ($i_y ** 2));
455 0 0         if($x2py2 < $r2)
456             {
457 0           push(@points_in, [($coord_x + $i_x), ($coord_y + $i_y)]);
458             }
459             }
460             }
461 0           $self->{points_inside} = \@points_in;
462 0           return(\@points_in);
463             }
464             #-------------------------------------------------
465             sub GetPointsOutCircle
466             {
467 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
468 0           my ($x2py2, $i_y);
469 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
470 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
471 0           my $width = ($p_x2 - $p_x1);
472 0           my $height= ($p_y2 - $p_y1);
473 0 0 0       if(($width < 5) || ($height < 5))
474             {
475 0           $self->{points_outside} = [];
476 0           return([]);
477             }
478 0           my $r = int($width / 2);
479 0           my $r2 = ($r ** 2);
480 0           my $coord_x = ($p_x1 + $r);
481 0           my $coord_y = ($p_y1 + $r);
482 0           my @points_out;
483 0           for(my $i_x = -$r; $i_x <= $r; $i_x++)
484             {
485 0           for($i_y = $r; $i_y >= -$r; $i_y--)
486             {
487 0           $x2py2 = (($i_x ** 2) + ($i_y ** 2));
488 0 0         if($x2py2 > $r2)
489             {
490 0           push(@points_out, [($coord_x + $i_x), ($coord_y + $i_y)]);
491             }
492             }
493             }
494 0           $self->{points_outside} = \@points_out;
495 0           return(\@points_out);
496             }
497             #-------------------------------------------------
498             sub GetLinesInCircle
499             {
500 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
501 0           my ($x2py2, $pos_x, $diff_y);
502 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
503 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
504 0           my $width = ($p_x2 - $p_x1);
505 0           my $height= ($p_y2 - $p_y1);
506 0 0 0       if(($width < 5) || ($height < 5))
507             {
508 0           $self->{lines_inside} = [];
509 0           return([]);
510             }
511 0           my $r = int($width / 2);
512 0           my $r2 = ($r ** 2);
513 0           my $coord_x = ($p_x1 + $r);
514 0           my $coord_y = ($p_y1 + $r);
515 0           my @lines_in;
516 0           for(my $i_x = -$r; $i_x <= $r; $i_x++)
517             {
518 0           $pos_x = ($coord_x + $i_x);
519 0           $diff_y = int(sqrt($r2 - ($i_x ** 2)));
520 0           push(@lines_in, [$pos_x, ($coord_y - $diff_y), $pos_x, ($coord_y + $diff_y)]);
521             }
522 0           $self->{lines_inside} = \@lines_in;
523 0           return(\@lines_in);
524             }
525             #-------------------------------------------------
526             sub GetLinesOutCircle
527             {
528 0     0 1   my ($self, $p_x1, $p_y1, $p_x2, $p_y2) = @_;
529 0           my ($x2py2, $pos_x, $diff_y);
530 0 0         ($p_x1, $p_x2) = ($p_x2, $p_x1) if($p_x1 > $p_x2);
531 0 0         ($p_y1, $p_y2) = ($p_y2, $p_y1) if($p_y1 > $p_y2);
532 0           my $width = ($p_x2 - $p_x1);
533 0           my $height= ($p_y2 - $p_y1);
534 0 0 0       if(($width < 5) || ($height < 5))
535             {
536 0           $self->{lines_outside} = [];
537 0           return([]);
538             }
539 0           my $r = int($width / 2);
540 0           my $r2 = ($r ** 2);
541 0           my $coord_x = ($p_x1 + $r);
542 0           my $coord_y = ($p_y1 + $r);
543 0           my @lines_out;
544 0           for(my $i_x = -$r; $i_x <= $r; $i_x++)
545             {
546 0           $pos_x = ($coord_x + $i_x);
547 0           $diff_y = int(sqrt($r2 - ($i_x ** 2)));
548 0           push(@lines_out, [$pos_x, $p_y1, $pos_x, ($coord_y - $diff_y)]);
549 0           push(@lines_out, [$pos_x, ($coord_y + $diff_y), $pos_x, $p_y2]);
550             }
551 0           $self->{lines_outside} = \@lines_out;
552 0           return(\@lines_out);
553             }
554             #-------------------------------------------------
555             # POLYGON
556             #-------------------------------------------------
557             sub GetPointsPolygon
558             {
559 0     0 1   my ($self) = @_;
560 0           my $ref_p_x = _CalculatePolygon(@_);
561 0           my (@points_out, @points_in, @lines_out, @lines_in);
562 0           my $i_1 = my $i_2 = my $i_3 = 0;
563 0           my $p_x_temp;
564 0           for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
565             {
566 0           $p_x_temp = $self->{min_x};
567 0           for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  0            
568             {
569 0           push(@lines_in, [$ref_p_x->[$i_1][$i_2], $p_y, $ref_p_x->[$i_1][$i_2 + 1], $p_y]);
570 0           for($i_3 = $ref_p_x->[$i_1][$i_2]; $i_3 <= $ref_p_x->[$i_1][$i_2 + 1]; $i_3++)
571             {
572 0           push(@points_in, [$i_3, $p_y]);
573             }
574 0           push(@lines_out, [$p_x_temp, $p_y, $ref_p_x->[$i_1][$i_2], $p_y]);
575 0           for($i_3 = $p_x_temp; $i_3 <= $ref_p_x->[$i_1][$i_2]; $i_3++)
576             {
577 0           push(@points_out, [$i_3, $p_y]);
578             }
579 0           $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
580             }
581 0           push(@lines_out, [$p_x_temp, $p_y, $self->{max_x}, $p_y]);
582 0           for($i_3 = $p_x_temp; $i_3 <= $self->{max_x}; $i_3++)
583             {
584 0           push(@points_out, [$i_3, $p_y]);
585             }
586 0           $i_1++;
587             }
588 0           $self->{lines_outside} = \@lines_out;
589 0           $self->{lines_inside} = \@lines_in;
590 0           $self->{points_outside} = \@points_out;
591 0           $self->{points_inside} = \@points_in;
592             return({
593 0           lines_outside => \@lines_out,
594             lines_inside => \@lines_in,
595             points_outside => \@points_out,
596             points_inside => \@points_in,
597             });
598             }
599             #-------------------------------------------------
600             sub GetPointsInPolygon
601             {
602 0     0 1   my ($self) = @_;
603 0           my $ref_p_x = _CalculatePolygon(@_);
604 0           my @points_in = ();
605 0           my $i_1 = my $i_2 = my $i_3 = 0;
606 0           for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
607             {
608 0           for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  0            
609             {
610 0           for($i_3 = $ref_p_x->[$i_1][$i_2]; $i_3 <= $ref_p_x->[$i_1][$i_2 + 1]; $i_3++)
611             {
612 0           push(@points_in, [$i_3, $p_y]);
613             }
614             }
615 0           $i_1++;
616             }
617 0           $self->{points_inside} = \@points_in;
618 0           return(\@points_in);
619             }
620             #-------------------------------------------------
621             sub GetPointsOutPolygon
622             {
623 0     0 1   my ($self) = @_;
624 0           my $ref_p_x = _CalculatePolygon(@_);
625 0           my @points_out = ();
626 0           my $i_1 = my $i_2 = my $i_3 = 0;
627 0           my $p_x_temp;
628 0           for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
629             {
630 0           $p_x_temp = $self->{min_x};
631 0           for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  0            
632             {
633 0           for($i_3 = $p_x_temp; $i_3 <= $ref_p_x->[$i_1][$i_2]; $i_3++)
634             {
635 0           push(@points_out, [$i_3, $p_y]);
636             }
637 0           $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
638             }
639 0           for($i_3 = $p_x_temp; $i_3 <= $self->{max_x}; $i_3++)
640             {
641 0           push(@points_out, [$i_3, $p_y]);
642             }
643 0           $i_1++;
644             }
645 0           $self->{points_outside} = \@points_out;
646 0           return(\@points_out);
647             }
648             #-------------------------------------------------
649             sub GetLinesInPolygon
650             {
651 0     0 1   my ($self) = @_;
652 0           my $ref_p_x = _CalculatePolygon(@_);
653 0           my @lines_in = ();
654 0           my $i_1 = my $i_2 = 0;
655 0           for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
656             {
657 0           for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  0            
658             {
659 0           push(@lines_in, [$ref_p_x->[$i_1][$i_2], $p_y, $ref_p_x->[$i_1][$i_2 + 1], $p_y]);
660             }
661 0           $i_1++;
662             }
663 0           $self->{lines_inside} = \@lines_in;
664 0           return(\@lines_in);
665             }
666             #-------------------------------------------------
667             sub GetLinesOutPolygon
668             {
669 0     0 1   my ($self) = @_;
670 0           my $ref_p_x = _CalculatePolygon(@_);
671 0           my @lines_out = ();
672 0           my $i_1 = my $i_2 = 0;
673 0           my $p_x_temp;
674 0           for(my $p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
675             {
676 0           $p_x_temp = $self->{min_x};
677 0           for($i_2 = 0; $i_2 <= $#{$ref_p_x->[$i_1]}; $i_2 += 2)
  0            
678             {
679 0           push(@lines_out, [$p_x_temp, $p_y, $ref_p_x->[$i_1][$i_2], $p_y]);
680 0           $p_x_temp = $ref_p_x->[$i_1][$i_2 + 1];
681             }
682 0           push(@lines_out, [$p_x_temp, $p_y, $self->{max_x}, $p_y]);
683 0           $i_1++;
684             }
685 0           $self->{lines_outside} = \@lines_out;
686 0           return(\@lines_out);
687             }
688             #-------------------------------------------------
689             sub _CalculatePolygon
690             {
691 0     0     my ($self, @points) = @_;
692 0           my @p;
693 0           for(my $i = 0; $i <= $#points; $i += 2)
694             {
695 0           push(@p, { x => $points[$i], y => $points[$i + 1]});
696             }
697 0           push(@p, {x => $points[0], y => $points[1]});
698 0           my $points_count = $#p;
699 0 0         return([]) if($points_count < 3);
700 0           my ($index_1, $index_2, $index_count);
701 0           my ($p_y, $p_y1, $p_y2, $p_x1, $p_x2, $p_x_temp);
702 0           my @points_outline_x = ();
703 0           my @all_points_outline_x = ();
704 0           my ($i, $j);
705 0           $self->{min_y} = $self->{max_y} = $p[0]{y};
706 0           $self->{min_x} = $self->{max_x} = $p[0]{x};
707 0           for(0..$#p)
708             {
709 0 0         $self->{min_y} = $p[$_]{y} if($self->{min_y} > $p[$_]{y});
710 0 0         $self->{max_y} = $p[$_]{y} if($self->{max_y} < $p[$_]{y});
711 0 0         $self->{min_x} = $p[$_]{x} if($self->{min_x} > $p[$_]{x});
712 0 0         $self->{max_x} = $p[$_]{x} if($self->{max_x} < $p[$_]{x});
713             }
714 0           for($p_y = $self->{min_y}; $p_y <= $self->{max_y}; $p_y++)
715             {
716 0           $index_count = 0;
717 0           @points_outline_x = ();
718 0           for($i = 0; $i < $points_count; $i++)
719             {
720 0 0         if(!$i)
721             {
722 0           $index_1 = $points_count - 1;
723 0           $index_2 = 0;
724             }
725             else
726             {
727 0           $index_1 = $i - 1;
728 0           $index_2 = $i;
729             }
730 0           $p_y1 = $p[$index_1]{y};
731 0           $p_y2 = $p[$index_2]{y};
732 0 0         if($p_y1 < $p_y2)
    0          
733             {
734 0           $p_x1 = $p[$index_1]{x};
735 0           $p_x2 = $p[$index_2]{x};
736             }
737             elsif ($p_y1 > $p_y2)
738             {
739 0           $p_y2 = $p[$index_1]{y};
740 0           $p_y1 = $p[$index_2]{y};
741 0           $p_x2 = $p[$index_1]{x};
742 0           $p_x1 = $p[$index_2]{x};
743             }
744             else
745             {
746 0           next;
747             }
748 0 0 0       if(($p_y >= $p_y1) && ($p_y < $p_y2))
    0 0        
      0        
749             {
750 0           $points_outline_x[$index_count++] = int((($p_y - $p_y1) * ($p_x2 - $p_x1)) / ($p_y2 - $p_y1) + 0.5 + $p_x1);
751             }
752             elsif(($p_y == $self->{max_y}) && ($p_y > $p_y1) && ($p_y <= $p_y2))
753             {
754 0           $points_outline_x[$index_count++] = int((($p_y - $p_y1) * ($p_x2 - $p_x1)) / ($p_y2 - $p_y1) + 0.5 + $p_x1);
755             }
756             }
757 0           for($i = 1; $i < $index_count; $i++)
758             {
759 0           $p_x_temp = $points_outline_x[$i];
760 0           $j = $i;
761 0   0       while(($j > 0) && ($points_outline_x[$j - 1] > $p_x_temp))
762             {
763 0           $points_outline_x[$j] = $points_outline_x[$j - 1];
764 0           $j--;
765             }
766 0           $points_outline_x[$j] = $p_x_temp;
767             }
768 0           push(@all_points_outline_x, [@points_outline_x]);
769             }
770 0           return(\@all_points_outline_x);
771             }
772             #-------------------------------------------------
773             1;
774             #-------------------------------------------------
775             __END__