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.0113';
3 9     9   1778 use Moo;
  9         12  
  9         51  
4 9     9   2700 use Math::Trig qw/pi/;
  9         19  
  9         4367  
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.0113
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             $args->{cx} //= 0;
88             $args->{cy} //= 0;
89             my $center = [ $args->{cx}, $args->{cy} ];
90             if ($args->{transformer}->has_transforms) {
91             ##Approximate the circle with a polygon
92             my $poly = $class->make_polygon($args);
93             $args->{draw_start} = $poly->draw_start;
94             $args->{draw_end} = $poly->draw_end;
95             $args->{shape_length} = $poly->shape_length;
96             $args->{min_x} = $poly->min_x;
97             $args->{min_y} = $poly->min_y;
98             $args->{max_x} = $poly->max_x;
99             $args->{max_y} = $poly->max_y;
100             return $args;
101             }
102             $args->{draw_start} = [$args->{cx}+$args->{rx}, $args->{cy}];
103             $args->{draw_end} = $args->{draw_start};
104              
105             ##https://www.mathsisfun.com/geometry/ellipse-perimeter.html, Series #2
106             my $h = ($args->{rx} - $args->{ry})**2 / ($args->{rx} + $args->{ry}) **2;
107             my $len = pi * ( $args->{rx} + $args->{ry} ) * ( 1 + $h/4 + ($h**2)/64 + ($h**3)/256 + ($h**4 * (25/16384)));
108             $args->{shape_length} = $len;
109              
110             $args->{min_x} = $args->{cx} - $args->{rx};
111             $args->{min_y} = $args->{cy} - $args->{ry};
112             $args->{max_x} = $args->{cx} + $args->{rx};
113             $args->{max_y} = $args->{cy} + $args->{ry};
114             return $args;
115             }
116              
117             sub args_with_units {
118 5     5 0 15 return qw/rx ry/;
119             }
120              
121             sub this_point {
122 13     13 0 14 my $class = shift;
123 13         10 my $args = shift;
124 13         9 my $t = shift;
125 13         15 my $angle = $t * 2 * pi;
126 13         48 my $cosr = cos $angle;
127 13         18 my $sinr = sin $angle;
128 13         22 my $x = $cosr * $args->{rx} + $args->{cx};
129 13         15 my $y = $sinr * $args->{ry} + $args->{cy};
130 13         20 return [$x, $y];
131             }
132              
133             1;