Math-Bezier-0.01/0040755000076400007640000000000007173605075011673 5ustar abwabwMath-Bezier-0.01/Makefile.PL0100644000076400007640000000044207173260663013642 0ustar abwabwuse ExtUtils::MakeMaker; my %opts = ( 'NAME' => 'Math::Bezier', 'VERSION_FROM' => 'Bezier.pm', ); if ($ExtUtils::MakeMaker::VERSION >= 5.43) { $opts{ AUTHOR } = 'Andy Wardley '; $opts{ ABSTRACT } = 'solution of Bezier curves', } WriteMakefile( %opts ); Math-Bezier-0.01/Changes0100644000076400007640000000112507173260663013162 0ustar abwabw#======================================================================== # # Changes # # DESCRIPTION # Revision history for the Math::Bezier module. # # AUTHOR # Andy Wardley # #------------------------------------------------------------------------ # $Id: Changes,v 1.1.1.1 2000/10/18 08:39:15 abw Exp $ #======================================================================== #------------------------------------------------------------------------ # Version 0.01 2000/10/18 #------------------------------------------------------------------------ * initial version Math-Bezier-0.01/test.pl0100755000076400007640000000151407173260663013210 0ustar abwabw#!/usr/bin/perl -w # -*- perl -*- use strict; use vars qw( $loaded ); use lib qw( blib/lib ); my $DEBUG = 0; print "1..27\n"; my $n = 0; sub ok { shift or print "not "; print "ok ", ++$n, "\n"; } use Math::Bezier; ok( 1 ); my $control = [ 0, 0, 10, 20, 30, -20, 40, 0 ]; my $bezier1 = Math::Bezier->new(@$control); ok( $bezier1 ); foreach my $k (0 .. 10) { my @pt = $bezier1->point($k / 10); ok( scalar @pt == 2 ); print STDERR "point: @pt\n" if $DEBUG; } my @pts1 = $bezier1->curve(20); ok( scalar @pts1 == 40 ); my $bezier2 = Math::Bezier->new($control); ok( $bezier2 ); foreach my $k (0 .. 10) { my $pt = $bezier2->point($k / 10); ok( scalar @$pt == 2 ); print STDERR "point: @$pt\n" if $DEBUG; } my $pts2 = $bezier2->curve(); ok( scalar @$pts2 == 40 ); Math-Bezier-0.01/Bezier.pm0100644000076400007640000001325407173605027013450 0ustar abwabw#======================================================================== # Math::Bezier # # Module for the solution of Bezier curves based on the algorithm # presented by Robert D. Miller in Graphics Gems V, "Quick and Simple # Bezier Curve Drawing". # # Andy Wardley # # Copyright (C) 2000 Andy Wardley. All Rights Reserved. # # This module is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # #======================================================================== package Math::Bezier; use strict; use vars qw( $VERSION ); $VERSION = '0.01'; use constant X => 0; use constant Y => 1; use constant CX => 2; use constant CY => 3; #------------------------------------------------------------------------ # new($x1, $y1, $x2, $y2, ..., $xn, $yn) # # Constructor method to create a new Bezier curve form. #------------------------------------------------------------------------ sub new { my $class = shift; my @points = ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_; my $size = scalar @points; my @ctrl; die "invalid control points, expects (x1, y1, x2, y2, ..., xn, yn)\n" if $size % 2; while (@points) { push(@ctrl, [ splice(@points, 0, 2) ]); } $size = scalar @ctrl; my $n = $size - 1; my $choose; for (my $k = 0; $k <= $n; $k++) { if ($k == 0) { $choose = 1; } elsif ($k == 1) { $choose = $n; } else { $choose *= ($n - $k + 1) / $k; } $ctrl[$k]->[CX] = $ctrl[$k]->[X] * $choose; $ctrl[$k]->[CY] = $ctrl[$k]->[Y] * $choose; } bless \@ctrl, $class; } #------------------------------------------------------------------------ # point($theta) # # Calculate (x, y) point on curve at position $theta (in the range 0 - 1) # along the curve. Returns a list ($x, $y) or reference to a list # [$x, $y] when called in list or scalar context respectively. #------------------------------------------------------------------------ sub point { my ($self, $t) = @_; my $size = scalar @$self; my (@points, $point); my $n = $size - 1; my $u = $t; push(@points, [ $self->[0]->[CX], $self->[0]->[CY] ]); for (my $k = 1; $k <= $n; $k++) { push(@points, [ $self->[$k]->[CX] * $u, $self->[$k]->[CY] * $u ]); $u *= $t; } $point = [ @{ $points[$n] } ]; my $t1 = 1 - $t; my $tt = $t1; for (my $k = $n - 1; $k >= 0; $k--) { $point->[X] += $points[$k]->[X] * $tt; $point->[Y] += $points[$k]->[Y] * $tt; $tt = $tt * $t1; } return wantarray ? (@$point) : $point; } #------------------------------------------------------------------------ # curve($npoints) # # Sample curve at $npoints points. Returns a list or reference to a list # of (x, y) points along the curve, when called in list or scalar context # respectively. #------------------------------------------------------------------------ sub curve { my ($self, $npoints) = @_; $npoints = 20 unless defined $npoints; my @points; $npoints--; foreach (my $t = 0; $t <= $npoints; $t++) { push(@points, ($self->point($t / $npoints))); } return wantarray ? (@points) : \@points; } 1; __END__ =head1 NAME Math::Bezier - solution of Bezier Curves =head1 SYNOPSIS use Math::Bezier; # create curve passing list of (x, y) control points my $bezier = Math::Bezier->new($x1, $y1, $x2, $y2, ..., $xn, $yn); # or pass reference to list of control points my $bezier = Math::Bezier->new([ $x1, $y1, $x2, $y2, ..., $xn, $yn]); # determine (x, y) at point along curve, range 0 -> 1 my ($x, $y) = $bezier->point(0.5); # returns list ref in scalar context my $xy = $bezier->point(0.5); # return list of 20 (x, y) points along curve my @curve = $bezier->curve(20); # returns list ref in scalar context my $curve = $bezier->curve(20); =head1 DESCRIPTION This module implements the algorithm for the solution of Bezier curves as presented by Robert D. Miller in Graphics Gems V, "Quick and Simple Bezier Curve Drawing". A new Bezier curve is created using the new() constructor, passing a list of (x, y) control points. use Math::Bezier; my @control = ( 0, 0, 10, 20, 30, -20, 40, 0 ); my $bezier = Math::Bezier->new(@control); Alternately, a reference to a list of control points may be passed. my $bezier = Math::Bezier->new(\@control); The point($theta) method can then be called on the object, passing a value in the range 0 to 1 which represents the distance along the curve. When called in list context, the method returns the x and y coordinates of that point on the Bezier curve. my ($x, $y) = $bezier->point(0.5); print "x: $x y: $y\n When called in scalar context, it returns a reference to a list containing the x and y coordinates. my $point = $bezier->point(0.5); print "x: $point->[0] y: $point->[1]\n"; The curve($n) method can be used to return a set of points sampled along the length of the curve (i.e. in the range 0 <= $theta <= 1). The parameter indicates the number of sample points required, defaulting to 20 if undefined. The method returns a list of ($x1, $y1, $x2, $y2, ..., $xn, $yn) points when called in list context, or a reference to such an array when called in scalar context. my @points = $bezier->curve(10); while (@points) { my ($x, $y) = splice(@points, 0, 2); print "x: $x y: $y\n"; } my $points = $bezier->curve(10); while (@$points) { my ($x, $y) = splice(@$points, 0, 2); print "x: $x y: $y\n"; } =head1 AUTHOR Andy Wardley Eabw@kfs.orgE =head1 SEE ALSO Graphics Gems 5, edited by Alan W. Paeth, Academic Press, 1995, ISBN 0-12-543455-3. Section IV.8, 'Quick and Simple Bezier Curve Drawing' by Robert D. Miller, pages 206-209. =cut Math-Bezier-0.01/README0100644000076400007640000000540707173605032012547 0ustar abwabwNAME Math::Bezier - solution of Bezier Curves SYNOPSIS use Math::Bezier; # create curve passing list of (x, y) control points my $bezier = Math::Bezier->new($x1, $y1, $x2, $y2, ..., $xn, $yn); # or pass reference to list of control points my $bezier = Math::Bezier->new([ $x1, $y1, $x2, $y2, ..., $xn, $yn]); # determine (x, y) at point along curve, range 0 -> 1 my ($x, $y) = $bezier->point(0.5); # returns list ref in scalar context my $xy = $bezier->point(0.5); # return list of 20 (x, y) points along curve my @curve = $bezier->curve(20); # returns list ref in scalar context my $curve = $bezier->curve(20); DESCRIPTION This module implements the algorithm for the solution of Bezier curves as presented by Robert D. Miller in Graphics Gems V, "Quick and Simple Bezier Curve Drawing". A new Bezier curve is created using the new() constructor, passing a list of (x, y) control points. use Math::Bezier; my @control = ( 0, 0, 10, 20, 30, -20, 40, 0 ); my $bezier = Math::Bezier->new(@control); Alternately, a reference to a list of control points may be passed. my $bezier = Math::Bezier->new(\@control); The point($theta) method can then be called on the object, passing a value in the range 0 to 1 which represents the distance along the curve. When called in list context, the method returns the x and y coordinates of that point on the Bezier curve. my ($x, $y) = $bezier->point(0.5); print "x: $x y: $y\n When called in scalar context, it returns a reference to a list containing the x and y coordinates. my $point = $bezier->point(0.5); print "x: $point->[0] y: $point->[1]\n"; The curve($n) method can be used to return a set of points sampled along the length of the curve (i.e. in the range 0 <= $theta <= 1). The parameter indicates the number of sample points required, defaulting to 20 if undefined. The method returns a list of ($x1, $y1, $x2, $y2, ..., $xn, $yn) points when called in list context, or a reference to such an array when called in scalar context. my @points = $bezier->curve(10); while (@points) { my ($x, $y) = splice(@points, 0, 2); print "x: $x y: $y\n"; } my $points = $bezier->curve(10); while (@$points) { my ($x, $y) = splice(@$points, 0, 2); print "x: $x y: $y\n"; } AUTHOR Andy Wardley SEE ALSO Graphics Gems 5, edited by Alan W. Paeth, Academic Press, 1995, ISBN 0-12-543455-3. Section IV.8, 'Quick and Simple Bezier Curve Drawing' by Robert D. Miller, pages 206-209. Math-Bezier-0.01/MANIFEST0100644000076400007640000000006607173260663013023 0ustar abwabwBezier.pm Changes Makefile.PL MANIFEST README test.pl