File Coverage

lib/SVG/Estimate/Path/CubicBezier.pm
Criterion Covered Total %
statement 16 16 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod 0 1 0.0
total 21 22 95.4


line stmt bran cond sub pod time code
1             package SVG::Estimate::Path::CubicBezier;
2             $SVG::Estimate::Path::CubicBezier::VERSION = '1.0113';
3 10     10   1232 use Moo;
  10         21  
  10         54  
4 10     10   2619 use List::Util qw/min max/;
  10         15  
  10         669  
5 10     10   1492 use Clone qw/clone/;
  10         8173  
  10         3907  
6              
7             extends 'SVG::Estimate::Path::Command';
8             with 'SVG::Estimate::Role::Pythagorean';
9             with 'SVG::Estimate::Role::SegmentLength';
10             with 'SVG::Estimate::Role::EndToPoint';
11              
12             =head1 NAME
13              
14             SVG::Estimate::Path::CubicBezier - Handles estimating cubic bezier curves.
15              
16             =head1 VERSION
17              
18             version 1.0113
19              
20             =head1 SYNOPSIS
21              
22             my $curve = SVG::Estimate::Path::CubicBezier->new(
23             transformer => $transform,
24             start_point => [13, 19],
25             point => [45,13],
26             control1 => [10,3],
27             control2 => [157,40],
28             );
29              
30             my $length = $curve->length;
31              
32             =head1 INHERITANCE
33              
34             This class extends L and consumes L, L, and L.
35              
36             =head1 METHODS
37              
38             =head2 new()
39              
40             Constructor.
41              
42             =over
43              
44             =item point
45              
46             An array ref containing two floats that represent a point.
47              
48             =item control1
49              
50             An array ref containing two floats that represent a point.
51              
52             =item control2
53              
54             An array ref containing two floats that represent a point.
55              
56             =back
57              
58             =cut
59              
60             has point => (
61             is => 'ro',
62             required => 1,
63             );
64              
65             has control1 => (
66             is => 'ro',
67             required => 1,
68             );
69              
70             has control2 => (
71             is => 'ro',
72             required => 1,
73             );
74              
75             sub BUILDARGS {
76             my ($class, @args) = @_;
77             ##Upgrade to hashref
78             my $args = @args % 2 ? $args[0] : { @args };
79             if ($args->{transformer}->has_transforms) {
80             $args->{point} = $args->{transformer}->transform($args->{point});
81             $args->{control1} = $args->{transformer}->transform($args->{control1});
82             $args->{control2} = $args->{transformer}->transform($args->{control2});
83             }
84             $args->{end_point} = clone $args->{point};
85              
86             my $start = $class->this_point($args, 0);
87             my $end = $class->this_point($args, 1);
88             $args->{min_x} = $start->[0] < $end->[0] ? $start->[0] : $end->[0];
89             $args->{max_x} = $start->[0] > $end->[0] ? $start->[0] : $end->[0];
90             $args->{min_y} = $start->[1] < $end->[1] ? $start->[1] : $end->[1];
91             $args->{max_y} = $start->[1] > $end->[1] ? $start->[1] : $end->[1];
92              
93             $args->{shape_length} = $class->segment_length($args, 0, 1, $start, $end, 1e-4, 5, 0);
94             $args->{travel_length} = 0;
95              
96             return $args;
97             }
98              
99             sub _this_point {
100 122610     122610   111362 shift;
101 122610         135787 my ($t, $s, $c1, $c2, $p) = @_;
102 122610         333431 return ((1 - $t)**3 * $s)
103             + (3 * (1 - $t)**2 * $t * $c1)
104             + (3 * (1 - $t) * $t**2 * $c2)
105             + ($t**3 * $p)
106             ;
107             }
108              
109             sub this_point {
110 61305     61305 0 60990 my $class = shift;
111 61305         53043 my $args = shift;
112 61305         53747 my $t = shift;
113             return [
114             $class->_this_point($t, $args->{start_point}->[0], $args->{control1}->[0], $args->{control2}->[0], $args->{point}->[0]),
115 61305         94398 $class->_this_point($t, $args->{start_point}->[1], $args->{control1}->[1], $args->{control2}->[1], $args->{point}->[1])
116             ];
117             }
118              
119              
120             1;