File Coverage

blib/lib/Graph/Maker/GosperIsland.pm
Criterion Covered Total %
statement 6 8 75.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 9 11 81.8


line stmt bran cond sub pod time code
1             # Copyright 2017 Kevin Ryde
2             #
3             # This file is part of Graph-Maker-Other.
4             #
5             # This file is free software; you can redistribute it and/or modify it
6             # under the terms of the GNU General Public License as published by the Free
7             # Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # This file is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Graph-Maker-Other. See the file COPYING. If not, see
17             # .
18              
19             package Graph::Maker::GosperIsland;
20 1     1   85280 use 5.004;
  1         8  
21 1     1   5 use strict;
  1         1  
  1         15  
22 1     1   581 use Graph::Maker;
  0            
  0            
23              
24             use vars '$VERSION','@ISA';
25             $VERSION = 8;
26             @ISA = ('Graph::Maker');
27              
28              
29             sub _default_graph_maker {
30             require Graph;
31             return Graph->new(@_);
32             }
33             sub _make_graph {
34             my ($params) = @_;
35             my $graph_maker = delete($params->{'graph_maker'}) || \&_default_graph_maker;
36             return $graph_maker->(%$params);
37             }
38              
39             sub _mul {
40             my ($x,$y) = @_;
41             return ((5*$x - 3*$y)/2, ($x+5*$y)/2);
42             }
43             sub _add {
44             my ($v, $ax,$ay) = @_;
45             my ($x,$y) = split /,/, $v;
46             $x += $ax;
47             $y += $ay;
48             return "$x,$y";
49             }
50             sub _rotate_plus60 {
51             my ($x, $y) = @_;
52             return (($x-3*$y)/2, # rotate +60
53             ($x+$y)/2);
54             }
55              
56             my @level_0 = ('2,0', '1,1', '-1,1', '-2,0', '-1,-1', '1,-1');
57              
58             sub init {
59             my ($self, %params) = @_;
60              
61             my $level = delete($params{'level'}) || 0;
62              
63             my $graph = _make_graph(\%params);
64             $graph->set_graph_attribute (name => "Gosper Island $level");
65             $graph->set_graph_attribute (vertex_name_type_xy => 1);
66             $graph->set_graph_attribute (vertex_name_type_xy_triangular => 1);
67             my $multiedged = $graph->is_countedged || $graph->is_multiedged;
68              
69             $graph->add_cycle(@level_0);
70             if ($graph->is_directed) { $graph->add_cycle(reverse @level_0); }
71              
72             my $cx = 3;
73             my $cy = 1;
74             foreach my $i (1 .. $level) {
75             foreach my $edge ($graph->edges) {
76             foreach (1 .. 6) {
77             my ($u,$v) = @$edge;
78             $u = _add($u, $cx,$cy);
79             $v = _add($v, $cx,$cy);
80             if (! $multiedged || ! $graph->has_edge($u,$v)) { # no duplicates
81             $graph->add_edge($u,$v);
82             }
83             ($cx,$cy) = _rotate_plus60($cx,$cy);
84             }
85             }
86             ($cx,$cy) = _mul($cx,$cy);
87             }
88             return $graph;
89             }
90              
91             Graph::Maker->add_factory_type('Gosper_island' => __PACKAGE__);
92             1;
93              
94             __END__