File Coverage

lib/SVG/Estimate/Ellipse.pm
Criterion Covered Total %
statement 16 16 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod 0 2 0.0
total 20 22 90.9


line stmt bran cond sub pod time code
1             package SVG::Estimate::Ellipse;
2             $SVG::Estimate::Ellipse::VERSION = '1.0107';
3 3     3   1197 use Moo;
  3         3  
  3         18  
4 3     3   654 use Math::Trig qw/pi/;
  3         4  
  3         1191  
5              
6             extends 'SVG::Estimate::Shape';
7             with 'SVG::Estimate::Role::MakePolygon';
8             with 'SVG::Estimate::Role::ArgsWithUnits';
9              
10             =head1 NAME
11              
12             SVG::Estimate::Ellipse - Handles estimating ellipses.
13              
14             =head1 VERSION
15              
16             version 1.0107
17              
18             =head1 SYNOPSIS
19              
20             my $ellipse = SVG::Estimate::Ellipse->new(
21             transformer => $transform,
22             start_point => [45,13],
23             cx => 1,
24             cy => 3,
25             rx => 1,
26             ry => 1.5,
27             );
28              
29             my $length = $ellipse->length;
30              
31             =head1 INHERITANCE
32              
33             This class extends L.
34              
35             =head1 METHODS
36              
37             =head2 new()
38              
39             Constructor.
40              
41             =over
42              
43             =item cx
44              
45             Float representing center x.
46              
47             =item cy
48              
49             Float representing center y.
50              
51             =item rx
52              
53             Float representing the x radius.
54              
55             =item ry
56              
57             Float representing the y radius.
58              
59             =back
60              
61             =cut
62              
63             has cx => (
64             is => 'ro',
65             default => sub { 0 },
66             );
67              
68             has cy => (
69             is => 'ro',
70             default => sub { 0 },
71             );
72              
73             has rx => (
74             is => 'ro',
75             required => 1,
76             );
77              
78             has ry => (
79             is => 'ro',
80             required => 1,
81             );
82              
83             sub BUILDARGS {
84             my ($class, @args) = @_;
85             ##Upgrade to hashref
86             my $args = @args % 2 ? $args[0] : { @args };
87             my $center = [ $args->{cx}, $args->{cy} ];
88             if ($args->{transformer}->has_transforms) {
89             ##Approximate the circle with a polygon
90             my $poly = $class->make_polygon($args);
91             $args->{draw_start} = $poly->draw_start;
92             $args->{draw_end} = $poly->draw_end;
93             $args->{shape_length} = $poly->shape_length;
94             $args->{min_x} = $poly->min_x;
95             $args->{min_y} = $poly->min_y;
96             $args->{max_x} = $poly->max_x;
97             $args->{max_y} = $poly->max_y;
98             return $args;
99             }
100             $args->{draw_start} = [$args->{cx}+$args->{rx}, $args->{cy}];
101             $args->{draw_end} = $args->{draw_start};
102              
103             ##https://www.mathsisfun.com/geometry/ellipse-perimeter.html, Series #2
104             my $h = ($args->{rx} - $args->{ry})**2 / ($args->{rx} + $args->{ry}) **2;
105             my $len = pi * ( $args->{rx} + $args->{ry} ) * ( 1 + $h/4 + ($h**2)/64 + ($h**3)/256 + ($h**4 * (25/16384)));
106             $args->{shape_length} = $len;
107              
108             $args->{min_x} = $args->{cx} - $args->{rx};
109             $args->{min_y} = $args->{cy} - $args->{ry};
110             $args->{max_x} = $args->{cx} + $args->{rx};
111             $args->{max_y} = $args->{cy} + $args->{ry};
112             return $args;
113             }
114              
115             sub args_with_units {
116 4     4 0 12 return qw/rx ry/;
117             }
118              
119             sub this_point {
120 13     13 0 10 my $class = shift;
121 13         12 my $args = shift;
122 13         5 my $t = shift;
123 13         14 my $angle = $t * 2 * pi;
124 13         34 my $cosr = cos $angle;
125 13         16 my $sinr = sin $angle;
126 13         14 my $x = $cosr * $args->{rx} + $args->{cx};
127 13         10 my $y = $sinr * $args->{ry} + $args->{cy};
128 13         18 return [$x, $y];
129             }
130              
131             1;