From: Vincent Pit Date: Wed, 21 Jul 2010 14:56:49 +0000 (+0200) Subject: Introduce LaTeX::TikZ::Set::Arc X-Git-Tag: v0.01~25 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FLaTeX-TikZ.git;a=commitdiff_plain;h=1918fdf5100058cd6a4281bc8b04ec8977841e5e Introduce LaTeX::TikZ::Set::Arc --- diff --git a/MANIFEST b/MANIFEST index a9a373a..9d59a92 100644 --- a/MANIFEST +++ b/MANIFEST @@ -22,6 +22,7 @@ lib/LaTeX/TikZ/Point.pm lib/LaTeX/TikZ/Point/Math/Complex.pm lib/LaTeX/TikZ/Scope.pm lib/LaTeX/TikZ/Set.pm +lib/LaTeX/TikZ/Set/Arc.pm lib/LaTeX/TikZ/Set/Circle.pm lib/LaTeX/TikZ/Set/Line.pm lib/LaTeX/TikZ/Set/Mutable.pm diff --git a/Makefile.PL b/Makefile.PL index cb0515a..5625d46 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -12,13 +12,15 @@ my $dist = 'LaTeX-TikZ'; $file = "lib/$file.pm"; my %PREREQ_PM = ( - 'Any::Moose' => 0, - 'Carp' => 0, - 'List::Util' => 0, - 'Mouse' => '0.63', # register_type_constraint - 'Scope::Guard' => 0, - 'Sub::Name' => 0, - 'constant' => 0, + 'Any::Moose' => 0, + 'Carp' => 0, + 'List::Util' => 0, + 'Math::Complex' => 0, + 'Math::Trig' => 0, + 'Mouse' => '0.63', # register_type_constraint + 'Scope::Guard' => 0, + 'Sub::Name' => 0, + 'constant' => 0, ); my %META = ( diff --git a/lib/LaTeX/TikZ/Interface.pm b/lib/LaTeX/TikZ/Interface.pm index 6496b06..0e902f5 100644 --- a/lib/LaTeX/TikZ/Interface.pm +++ b/lib/LaTeX/TikZ/Interface.pm @@ -66,6 +66,7 @@ sub load { require LaTeX::TikZ::Set::Polyline; # polyline, closed_polyline require LaTeX::TikZ::Set::Rectangle; # rectangle require LaTeX::TikZ::Set::Circle; # circle + require LaTeX::TikZ::Set::Arc; # arc require LaTeX::TikZ::Mod::Raw; # raw_mod diff --git a/lib/LaTeX/TikZ/Set/Arc.pm b/lib/LaTeX/TikZ/Set/Arc.pm new file mode 100644 index 0000000..3ac58e0 --- /dev/null +++ b/lib/LaTeX/TikZ/Set/Arc.pm @@ -0,0 +1,101 @@ +package LaTeX::TikZ::Set::Arc; + +use strict; +use warnings; + +=head1 NAME + +LaTeX::TikZ::Set::Arc - A combined set object representing an arc. + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +use Carp (); +use Math::Complex (); +use Math::Trig (); + +use LaTeX::TikZ::Point; + +use LaTeX::TikZ::Set::Circle; +use LaTeX::TikZ::Set::Polyline; + +use LaTeX::TikZ::Tools; + +use Any::Moose 'Util::TypeConstraints' => [ 'find_type_constraint' ]; + +my $ltp_tc = find_type_constraint('LaTeX::TikZ::Point::Autocoerce'); + +use LaTeX::TikZ::Interface arc => sub { + shift; + Carp::confess('Tikz->arc($first_point, $second_point, $center)') if @_ < 3; + my ($a, $b, $c) = @_; + + for ($a, $b, $c) { + my $p = $ltp_tc->coerce($_); + $_ = Math::Complex->make($p->x, $p->y); + } + + my $r = abs($a - $c); + Carp::confess("The two first points aren't on a circle of center the last") + unless LaTeX::TikZ::Tools::numeq(abs($b - $c), $r); + + my $set = LaTeX::TikZ::Set::Circle->new( + center => $c, + radius => $r, + ); + + my $factor = 1/32; + + my $theta = (($b - $c) / ($a - $c))->arg; + my $points = int(abs($theta) / abs(Math::Trig::acos(0.95))); + $theta /= $points + 1; + my $rho = (1 / cos($theta)) / (1 - $factor); + + my $ua = ($a - $c) * (1 - $factor) + $c; + my $ub = ($b - $c) * (1 - $factor) + $c; + + my @outside = map { $_ * $rho + $c } ( + $a - $c, + (map { ($a - $c) * Math::Complex->emake(1, $_ * $theta) } 1 .. $points), + $b - $c, + ); + + $set->clip( + LaTeX::TikZ::Set::Polyline->new( + points => [ $ua, @outside, $ub ], + closed => 1, + ), + ); +}; + +=head1 AUTHOR + +Vincent Pit, C<< >>, L. + +You can contact me by mail or on C (vincent). + +=head1 BUGS + +Please report any bugs or feature requests to C, or through the web interface at L. +I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc LaTeX::TikZ + +=head1 COPYRIGHT & LICENSE + +Copyright 2010 Vincent Pit, all rights reserved. + +This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. + +=cut + +1; # End of LaTeX::TikZ::Set::Arc diff --git a/t/00-load.t b/t/00-load.t index 33cfe89..11f9eef 100644 --- a/t/00-load.t +++ b/t/00-load.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 30; +use Test::More tests => 31; BEGIN { use_ok( 'LaTeX::TikZ' ); @@ -25,6 +25,7 @@ BEGIN { use_ok( 'LaTeX::TikZ::Point::Math::Complex' ); use_ok( 'LaTeX::TikZ::Scope' ); use_ok( 'LaTeX::TikZ::Set' ); + use_ok( 'LaTeX::TikZ::Set::Arc' ); use_ok( 'LaTeX::TikZ::Set::Circle' ); use_ok( 'LaTeX::TikZ::Set::Line' ); use_ok( 'LaTeX::TikZ::Set::Mutable' ); diff --git a/t/01-api.t b/t/01-api.t index dc15124..106ebbe 100644 --- a/t/01-api.t +++ b/t/01-api.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 5 + 15 + 12; +use Test::More tests => 5 + 16 + 12; use LaTeX::TikZ; @@ -31,7 +31,7 @@ is(prototype('Tikz'), '', 'main::Tikz is actually a constant'); my @methods = qw/ raw path seq - point line polyline closed_polyline rectangle circle + point line polyline closed_polyline rectangle circle arc raw_mod clip layer width color fill diff --git a/t/12-geo.t b/t/12-geo.t index 3a7eef7..afbc1e7 100644 --- a/t/12-geo.t +++ b/t/12-geo.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => (11 + 2 * 5) + 2 * (10 + 2 * 3); +use Test::More tests => (14 + 2 * 5) + 2 * (11 + 2 * 3); use Math::Complex; @@ -188,3 +188,33 @@ eval { }; like $@, qr/isn't a non-negative real number/, 'creating a circle with a negative radius croaks'; + +# Arc + +$tikz = Tikz->formatter( + format => "%.03f" +); + +my $arc = eval { + Tikz->arc(1, i, $o); +}; +is $@, '', 'creating a simple arc doesn\'t croak'; + +check $arc, 'simple arc', <<'RES'; +\begin{scope} +\clip (0.969cm,0.000cm) -- (1.085cm,0.000cm) -- (1.032cm,0.335cm) -- (0.878cm,0.638cm) -- (0.638cm,0.878cm) -- (0.335cm,1.032cm) -- (0.000cm,1.085cm) -- (0.000cm,0.969cm) -- cycle ; +\draw (0.000cm,0.000cm) circle (1.000cm) ; +\end{scope} +RES + +eval { + Tikz->arc(0, 1); +}; +my $err = quotemeta 'Tikz->arc($first_point, $second_point, $center)'; +like $@, qr/^$err/, 'creating an arc from only two points croaks'; + +eval { + Tikz->arc(0, 1, i); +}; +like $@, qr/The two first points aren't on a circle of center the last/, + 'creating an arc with two points not on a circle of center c croaks';