annotate GD/Polyline.pm @ 0:e94de0ea3351 draft default tip

Uploaded
author dereeper
date Wed, 11 Sep 2013 09:08:15 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
1 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
2 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
3 # Polyline.pm
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
4 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
5 # Author: Dan Harasty
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
6 # Email: harasty@cpan.org
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
7 # Version: 0.2
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
8 # Date: 2002/08/06
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
9 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
10 # For usage documentation: see POD at end of file
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
11 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
12 # For changes: see "Changes" file included with distribution
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
13 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
14
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
15 use strict;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
16
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
17 package GD::Polyline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
18
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
19 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
20 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
21 # GD::Polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
22 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
23 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
24 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
25 # What's this? A class with nothing but a $VERSION and and @ISA?
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
26 # Below, this module overrides and adds several modules to
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
27 # the parent class, GD::Polygon. Those updated/new methods
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
28 # act on polygons and polylines, and sometimes those behaviours
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
29 # vary slightly based on whether the object is a polygon or polyine.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
30 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
31
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
32 use vars qw($VERSION @ISA);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
33 $VERSION = "0.2";
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
34 @ISA = qw(GD::Polygon);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
35
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
36
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
37 package GD::Polygon;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
38
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
39 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
40 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
41 # new methods on GD::Polygon
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
42 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
43 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
44
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
45 use GD;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
46 use Carp 'croak','carp';
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
47
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
48 use vars qw($bezSegs $csr);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
49 $bezSegs = 20; # number of bezier segs -- number of segments in each portion of the spline produces by toSpline()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
50 $csr = 1/3; # control seg ratio -- the one possibly user-tunable parameter in the addControlPoints() algorithm
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
51
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
52
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
53 sub rotate {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
54 my ($self, $angle, $cx, $cy) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
55 $self->offset(-$cx,-$cy) if $cx or $cy;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
56 $self->transform(cos($angle),sin($angle),-sin($angle),cos($angle),$cx,$cy);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
57 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
58
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
59 sub centroid {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
60 my ($self, $scale) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
61 my ($cx,$cy);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
62 $scale = 1 unless defined $scale;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
63
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
64 map {$cx += $_->[0]; $cy += $_->[1]} $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
65
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
66 $cx *= $scale / $self->length();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
67 $cy *= $scale / $self->length();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
68
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
69 return ($cx, $cy);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
70 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
71
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
72
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
73 sub segLength {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
74 my $self = shift;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
75 my @points = $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
76
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
77 my ($p1, $p2, @segLengths);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
78
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
79 $p1 = shift @points;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
80
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
81 # put the first vertex on the end to "close" a polygon, but not a polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
82 push @points, $p1 unless $self->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
83
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
84 while ($p2 = shift @points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
85 push @segLengths, _len($p1, $p2);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
86 $p1 = $p2;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
87 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
88
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
89 return @segLengths if wantarray;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
90
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
91 my $sum;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
92 map {$sum += $_} @segLengths;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
93 return $sum;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
94 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
95
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
96 sub segAngle {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
97 my $self = shift;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
98 my @points = $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
99
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
100 my ($p1, $p2, @segAngles);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
101
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
102 $p1 = shift @points;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
103
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
104 # put the first vertex on the end to "close" a polygon, but not a polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
105 push @points, $p1 unless $self->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
106
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
107 while ($p2 = shift @points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
108 push @segAngles, _angle_reduce2(_angle($p1, $p2));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
109 $p1 = $p2;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
110 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
111
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
112 return @segAngles;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
113 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
114
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
115 sub vertexAngle {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
116 my $self = shift;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
117 my @points = $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
118
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
119 my ($p1, $p2, $p3, @vertexAngle);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
120
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
121 $p1 = $points[$#points]; # last vertex
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
122 $p2 = shift @points; # current point -- the first vertex
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
123
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
124 # put the first vertex on the end to "close" a polygon, but not a polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
125 push @points, $p2 unless $self->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
126
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
127 while ($p3 = shift @points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
128 push @vertexAngle, _angle_reduce2(_angle($p1, $p2, $p3));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
129 ($p1, $p2) = ($p2, $p3);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
130 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
131
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
132 $vertexAngle[0] = undef if defined $vertexAngle[0] and $self->isa("GD::Polyline");
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
133
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
134 return @vertexAngle if wantarray;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
135
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
136 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
137
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
138
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
139
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
140 sub toSpline {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
141 my $self = shift;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
142 my @points = $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
143
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
144 # put the first vertex on the end to "close" a polygon, but not a polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
145 push @points, [$self->getPt(0)] unless $self->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
146
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
147 unless (@points > 1 and @points % 3 == 1) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
148 carp "Attempt to call toSpline() with invalid set of control points";
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
149 return undef;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
150 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
151
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
152 my ($ap1, $dp1, $dp2, $ap2); # ap = anchor point, dp = director point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
153 $ap1 = shift @points;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
154
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
155 my $bez = new ref($self);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
156
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
157 $bez->addPt(@$ap1);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
158
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
159 while (@points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
160 ($dp1, $dp2, $ap2) = splice(@points, 0, 3);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
161
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
162 for (1..$bezSegs) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
163 my ($t0, $t1, $c1, $c2, $c3, $c4, $x, $y);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
164
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
165 $t1 = $_/$bezSegs;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
166 $t0 = (1 - $t1);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
167
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
168 # possible optimization:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
169 # these coefficient could be calculated just once and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
170 # cached in an array for a given value of $bezSegs
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
171
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
172 $c1 = $t0 * $t0 * $t0;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
173 $c2 = 3 * $t0 * $t0 * $t1;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
174 $c3 = 3 * $t0 * $t1 * $t1;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
175 $c4 = $t1 * $t1 * $t1;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
176
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
177 $x = $c1 * $ap1->[0] + $c2 * $dp1->[0] + $c3 * $dp2->[0] + $c4 * $ap2->[0];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
178 $y = $c1 * $ap1->[1] + $c2 * $dp1->[1] + $c3 * $dp2->[1] + $c4 * $ap2->[1];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
179
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
180 $bez->addPt($x, $y);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
181 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
182
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
183 $ap1 = $ap2;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
184 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
185
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
186 # remove the last anchor point if this is a polygon -- since it will autoclose without it
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
187 $bez->deletePt($bez->length()-1) unless $self->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
188
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
189 return $bez;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
190 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
191
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
192 sub addControlPoints {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
193 my $self = shift;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
194 my @points = $self->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
195
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
196 unless (@points > 1) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
197 carp "Attempt to call addControlPoints() with too few vertices in polyline";
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
198 return undef;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
199 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
200
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
201 my $points = scalar(@points);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
202 my @segAngles = $self->segAngle();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
203 my @segLengths = $self->segLength();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
204
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
205 my ($prevLen, $nextLen, $prevAngle, $thisAngle, $nextAngle);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
206 my ($controlSeg, $pt, $ptX, $ptY, @controlSegs);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
207
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
208 # this loop goes about creating polylines -- here called control segments --
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
209 # that hold the control points for the final set of control points
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
210
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
211 # each control segment has three points, and these are colinear
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
212
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
213 # the first and last will ultimately be "director points", and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
214 # the middle point will ultimately be an "anchor point"
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
215
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
216 for my $i (0..$#points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
217
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
218 $controlSeg = new GD::Polyline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
219
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
220 $pt = $points[$i];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
221 ($ptX, $ptY) = @$pt;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
222
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
223 if ($self->isa('GD::Polyline') and ($i == 0 or $i == $#points)) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
224 $controlSeg->addPt($ptX, $ptY); # director point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
225 $controlSeg->addPt($ptX, $ptY); # anchor point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
226 $controlSeg->addPt($ptX, $ptY); # director point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
227 next;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
228 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
229
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
230 $prevLen = $segLengths[$i-1];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
231 $nextLen = $segLengths[$i];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
232 $prevAngle = $segAngles[$i-1];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
233 $nextAngle = $segAngles[$i];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
234
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
235 # make a control segment with control points (director points)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
236 # before and after the point from the polyline (anchor point)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
237
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
238 $controlSeg->addPt($ptX - $csr * $prevLen, $ptY); # director point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
239 $controlSeg->addPt($ptX , $ptY); # anchor point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
240 $controlSeg->addPt($ptX + $csr * $nextLen, $ptY); # director point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
241
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
242 # note that:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
243 # - the line is parallel to the x-axis, as the points have a common $ptY
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
244 # - the points are thus clearly colinear
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
245 # - the director point is a distance away from the anchor point in proportion to the length of the segment it faces
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
246
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
247 # now, we must come up with a reasonable angle for the control seg
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
248 # first, "unwrap" $nextAngle w.r.t. $prevAngle
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
249 $nextAngle -= 2*pi() until $nextAngle < $prevAngle + pi();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
250 $nextAngle += 2*pi() until $nextAngle > $prevAngle - pi();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
251 # next, use seg lengths as an inverse weighted average
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
252 # to "tip" the control segment toward the *shorter* segment
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
253 $thisAngle = ($nextAngle * $prevLen + $prevAngle * $nextLen) / ($prevLen + $nextLen);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
254
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
255 # rotate the control segment to $thisAngle about it's anchor point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
256 $controlSeg->rotate($thisAngle, $ptX, $ptY);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
257
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
258 } continue {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
259 # save the control segment for later
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
260 push @controlSegs, $controlSeg;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
261
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
262 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
263
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
264 # post process
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
265
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
266 my $controlPoly = new ref($self);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
267
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
268 # collect all the control segments' points in to a single control poly
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
269
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
270 foreach my $cs (@controlSegs) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
271 foreach my $pt ($cs->vertices()) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
272 $controlPoly->addPt(@$pt);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
273 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
274 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
275
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
276 # final clean up based on poly type
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
277
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
278 if ($controlPoly->isa('GD::Polyline')) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
279 # remove the first and last control point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
280 # since they are director points ...
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
281 $controlPoly->deletePt(0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
282 $controlPoly->deletePt($controlPoly->length()-1);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
283 } else {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
284 # move the first control point to the last control point
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
285 # since it is supposed to end with two director points ...
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
286 $controlPoly->addPt($controlPoly->getPt(0));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
287 $controlPoly->deletePt(0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
288 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
289
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
290 return $controlPoly;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
291 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
292
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
293
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
294 # The following helper functions are for internal
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
295 # use of this module. Input arguments of "points"
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
296 # refer to an array ref of two numbers, [$x, $y]
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
297 # as is used internally in the GD::Polygon
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
298 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
299 # _len()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
300 # Find the length of a segment, passing in two points.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
301 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
302 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
303 sub _len {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
304 # my ($p1, $p2) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
305 # return sqrt(($p2->[0]-$p1->[0])**2 + ($p2->[1]-$p1->[1])**2);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
306 my $pt = _subtract(@_);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
307 return sqrt($pt->[0] ** 2 + $pt->[1] **2);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
308 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
309
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
310 use Math::Trig;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
311
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
312 # _angle()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
313 # Find the angle of... well, depends on the number of arguments:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
314 # - one point: the angle from x-axis to the point (origin is the center)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
315 # - two points: the angle of the vector defined from point1 to point2
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
316 # - three points:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
317 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
318 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
319 sub _angle {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
320 my ($p1, $p2, $p3) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
321 my $angle = undef;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
322 if (@_ == 1) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
323 return atan2($p1->[1], $p1->[0]);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
324 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
325 if (@_ == 2) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
326 return _angle(_subtract($p1, $p2));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
327 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
328 if (@_ == 3) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
329 return _angle(_subtract($p2, $p3)) - _angle(_subtract($p2, $p1));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
330 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
331 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
332
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
333 # _subtract()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
334 # Find the difference of two points; returns a point.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
335 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
336 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
337 sub _subtract {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
338 my ($p1, $p2) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
339 # print(_print_point($p2), "-", _print_point($p1), "\n");
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
340 return [$p2->[0]-$p1->[0], $p2->[1]-$p1->[1]];
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
341 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
342
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
343 # _print_point()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
344 # Returns a string suitable for displaying the value of a point.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
345 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
346 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
347 sub _print_point {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
348 my ($p1) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
349 return "[" . join(", ", @$p1) . "]";
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
350 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
351
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
352 # _angle_reduce1()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
353 # "unwraps" angle to interval -pi < angle <= +pi
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
354 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
355 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
356 sub _angle_reduce1 {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
357 my ($angle) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
358 $angle += 2 * pi() while $angle <= -pi();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
359 $angle -= 2 * pi() while $angle > pi();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
360 return $angle;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
361 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
362
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
363 # _angle_reduce2()
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
364 # "unwraps" angle to interval 0 <= angle < 2 * pi
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
365 # Internal function; NOT a class or object method.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
366 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
367 sub _angle_reduce2 {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
368 my ($angle) = @_;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
369 $angle += 2 * pi() while $angle < 0;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
370 $angle -= 2 * pi() while $angle >= 2 * pi();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
371 return $angle;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
372 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
373
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
374 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
375 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
376 # new methods on GD::Image
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
377 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
378 ############################################################################
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
379
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
380 sub GD::Image::polyline {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
381 my $self = shift; # the GD::Image
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
382 my $p = shift; # the GD::Polyline (or GD::Polygon)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
383 my $c = shift; # the color
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
384
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
385 my @points = $p->vertices();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
386 my $p1 = shift @points;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
387 my $p2;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
388 while ($p2 = shift @points) {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
389 $self->line(@$p1, @$p2, $c);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
390 $p1 = $p2;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
391 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
392 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
393
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
394 sub GD::Image::polydraw {
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
395 my $self = shift; # the GD::Image
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
396 my $p = shift; # the GD::Polyline or GD::Polygon
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
397 my $c = shift; # the color
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
398
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
399 return $self->polyline($p, $c) if $p->isa('GD::Polyline');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
400 return $self->polygon($p, $c);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
401 }
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
402
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
403
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
404 1;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
405 __END__
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
406
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
407 =pod
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
408
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
409 =head1 NAME
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
410
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
411 GD::Polyline - Polyline object and Polygon utilities (including splines) for use with GD
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
412
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
413 =head1 SYNOPSIS
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
414
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
415 use GD;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
416 use GD::Polyline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
417
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
418 # create an image
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
419 $image = new GD::Image (500,300);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
420 $white = $image->colorAllocate(255,255,255);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
421 $black = $image->colorAllocate( 0, 0, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
422 $red = $image->colorAllocate(255, 0, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
423
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
424 # create a new polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
425 $polyline = new GD::Polyline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
426
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
427 # add some points
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
428 $polyline->addPt( 0, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
429 $polyline->addPt( 0,100);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
430 $polyline->addPt( 50,125);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
431 $polyline->addPt(100, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
432
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
433 # polylines can use polygon methods (and vice versa)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
434 $polyline->offset(200,100);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
435
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
436 # rotate 60 degrees, about the centroid
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
437 $polyline->rotate(3.14159/3, $polyline->centroid());
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
438
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
439 # scale about the centroid
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
440 $polyline->scale(1.5, 2, $polyline->centroid());
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
441
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
442 # draw the polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
443 $image->polydraw($polyline,$black);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
444
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
445 # create a spline, which is also a polyine
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
446 $spline = $polyline->addControlPoints->toSpline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
447 $image->polydraw($spline,$red);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
448
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
449 # output the png
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
450 binmode STDOUT;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
451 print $image->png;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
452
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
453 =head1 DESCRIPTION
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
454
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
455 B<Polyline.pm> extends the GD module by allowing you to create polylines. Think
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
456 of a polyline as "an open polygon", that is, the last vertex is not connected
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
457 to the first vertex (unless you expressly add the same value as both points).
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
458
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
459 For the remainder of this doc, "polyline" will refer to a GD::Polyline,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
460 "polygon" will refer to a GD::Polygon that is not a polyline, and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
461 "polything" and "$poly" may be either.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
462
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
463 The big feature added to GD by this module is the means
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
464 to create splines, which are approximations to curves.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
465
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
466 =head1 The Polyline Object
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
467
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
468 GD::Polyline defines the following class:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
469
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
470 =over 5
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
471
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
472 =item C<GD::Polyline>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
473
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
474 A polyline object, used for storing lists of vertices prior to
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
475 rendering a polyline into an image.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
476
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
477 =item C<new>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
478
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
479 C<GD::Polyline-E<gt>new> I<class method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
480
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
481 Create an empty polyline with no vertices.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
482
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
483 $polyline = new GD::Polyline;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
484
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
485 $polyline->addPt( 0, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
486 $polyline->addPt( 0,100);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
487 $polyline->addPt( 50,100);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
488 $polyline->addPt(100, 0);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
489
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
490 $image->polydraw($polyline,$black);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
491
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
492 In fact GD::Polyline is a subclass of GD::Polygon,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
493 so all polygon methods (such as B<offset> and B<transform>)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
494 may be used on polylines.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
495 Some new methods have thus been added to GD::Polygon (such as B<rotate>)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
496 and a few updated/modified/enhanced (such as B<scale>) I<in this module>.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
497 See section "New or Updated GD::Polygon Methods" for more info.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
498
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
499 =back
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
500
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
501 Note that this module is very "young" and should be
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
502 considered subject to change in future releases, and/or
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
503 possibly folded in to the existing polygon object and/or GD module.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
504
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
505 =head1 Updated Polygon Methods
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
506
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
507 The following methods (defined in GD.pm) are OVERRIDDEN if you use this module.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
508
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
509 All effort has been made to provide 100% backward compatibility, but if you
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
510 can confirm that has not been achieved, please consider that a bug and let the
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
511 the author of Polyline.pm know.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
512
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
513 =over 5
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
514
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
515 =item C<scale>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
516
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
517 C<$poly-E<gt>scale($sx, $sy, $cx, $cy)> I<object method -- UPDATE to GD::Polygon::scale>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
518
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
519 Scale a polything in along x-axis by $sx and along the y-axis by $sy,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
520 about centery point ($cx, $cy).
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
521
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
522 Center point ($cx, $cy) is optional -- if these are omitted, the function
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
523 will scale about the origin.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
524
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
525 To flip a polything, use a scale factor of -1. For example, to
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
526 flip the polything top to bottom about line y = 100, use:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
527
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
528 $poly->scale(1, -1, 0, 100);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
529
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
530 =back
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
531
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
532 =head1 New Polygon Methods
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
533
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
534 The following methods are added to GD::Polygon, and thus can be used
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
535 by polygons and polylines.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
536
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
537 Don't forget: a polyline is a GD::Polygon, so GD::Polygon methods
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
538 like offset() can be used, and they can be used in
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
539 GD::Image methods like filledPolygon().
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
540
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
541 =over 5
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
542
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
543 =item C<rotate>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
544
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
545 C<$poly-E<gt>rotate($angle, $cx, $cy)> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
546
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
547 Rotate a polything through $angle (clockwise, in radians) about center point ($cx, $cy).
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
548
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
549 Center point ($cx, $cy) is optional -- if these are omitted, the function
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
550 will rotate about the origin
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
551
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
552 In this function and other angle-oriented functions in GD::Polyline,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
553 positive $angle corrensponds to clockwise rotation. This is opposite
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
554 of the usual Cartesian sense, but that is because the raster is opposite
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
555 of the usual Cartesian sense in that the y-axis goes "down".
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
556
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
557 =item C<centroid>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
558
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
559 C<($cx, $cy) = $poly-E<gt>centroid($scale)> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
560
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
561 Calculate and return ($cx, $cy), the centroid of the vertices of the polything.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
562 For example, to rotate something 180 degrees about it's centroid:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
563
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
564 $poly->rotate(3.14159, $poly->centroid());
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
565
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
566 $scale is optional; if supplied, $cx and $cy are multiplied by $scale
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
567 before returning. The main use of this is to shift an polything to the
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
568 origin like this:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
569
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
570 $poly->offset($poly->centroid(-1));
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
571
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
572 =item C<segLength>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
573
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
574 C<@segLengths = $poly-E<gt>segLength()> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
575
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
576 In array context, returns an array the lengths of the segments in the polything.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
577 Segment n is the segment from vertex n to vertex n+1.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
578 Polygons have as many segments as vertices; polylines have one fewer.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
579
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
580 In a scalar context, returns the sum of the array that would have been returned
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
581 in the array context.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
582
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
583 =item C<segAngle>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
584
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
585 C<@segAngles = $poly-E<gt>segAngle()> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
586
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
587 Returns an array the angles of each segment from the x-axis.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
588 Segment n is the segment from vertex n to vertex n+1.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
589 Polygons have as many segments as vertices; polylines have one fewer.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
590
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
591 Returned angles will be on the interval 0 <= $angle < 2 * pi and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
592 angles increase in a clockwise direction.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
593
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
594 =item C<vertexAngle>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
595
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
596 C<@vertexAngles = $poly-E<gt>vertexAngle()> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
597
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
598 Returns an array of the angles between the segment into and out of each vertex.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
599 For polylines, the vertex angle at vertex 0 and the last vertex are not defined;
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
600 however $vertexAngle[0] will be undef so that $vertexAngle[1] will correspond to
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
601 vertex 1.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
602
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
603 Returned angles will be on the interval 0 <= $angle < 2 * pi and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
604 angles increase in a clockwise direction.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
605
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
606 Note that this calculation does not attempt to figure out the "interior" angle
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
607 with respect to "inside" or "outside" the polygon, but rather,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
608 just the angle between the adjacent segments
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
609 in a clockwise sense. Thus a polygon with all right angles will have vertex
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
610 angles of either pi/2 or 3*pi/2, depending on the way the polygon was "wound".
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
611
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
612 =item C<toSpline>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
613
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
614 C<$poly-E<gt>toSpline()> I<object method & factory method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
615
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
616 Create a new polything which is a reasonably smooth curve
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
617 using cubic spline algorithms, often referred to as Bezier
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
618 curves. The "source" polything is called the "control polything".
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
619 If it is a polyline, the control polyline must
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
620 have 4, 7, 10, or some number of vertices of equal to 3n+1.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
621 If it is a polygon, the control polygon must
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
622 have 3, 6, 9, or some number of vertices of equal to 3n.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
623
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
624 $spline = $poly->toSpline();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
625 $image->polydraw($spline,$red);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
626
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
627 In brief, groups of four points from the control polyline
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
628 are considered "control
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
629 points" for a given portion of the spline: the first and
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
630 fourth are "anchor points", and the spline passes through
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
631 them; the second and third are "director points". The
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
632 spline does not pass through director points, however the
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
633 spline is tangent to the line segment from anchor point to
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
634 adjacent director point.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
635
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
636 The next portion of the spline reuses the previous portion's
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
637 last anchor point. The spline will have a cusp
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
638 (non-continuous slope) at an anchor point, unless the anchor
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
639 points and its adjacent director point are colinear.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
640
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
641 In the current implementation, toSpline() return a fixed
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
642 number of segments in the returned polyline per set-of-four
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
643 control points. In the future, this and other parameters of
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
644 the algorithm may be configurable.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
645
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
646 =item C<addControlPoints>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
647
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
648 C<$polyline-E<gt>addControlPoints()> I<object method & factory method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
649
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
650 So you say: "OK. Splines sound cool. But how can I
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
651 get my anchor points and its adjacent director point to be
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
652 colinear so that I have a nice smooth curves from my
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
653 polyline?" Relax! For The Lazy: addControlPoints() to the
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
654 rescue.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
655
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
656 addControlPoints() returns a polyline that can serve
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
657 as the control polyline for toSpline(), which returns
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
658 another polyline which is the spline. Is your head spinning
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
659 yet? Think of it this way:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
660
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
661 =over 5
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
662
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
663 =item +
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
664
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
665 If you have a polyline, and you have already put your
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
666 control points where you want them, call toSpline() directly.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
667 Remember, only every third vertex will be "on" the spline.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
668
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
669 You get something that looks like the spline "inscribed"
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
670 inside the control polyline.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
671
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
672 =item +
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
673
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
674 If you have a polyline, and you want all of its vertices on
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
675 the resulting spline, call addControlPoints() and then
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
676 toSpline():
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
677
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
678 $control = $polyline->addControlPoints();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
679 $spline = $control->toSpline();
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
680 $image->polyline($spline,$red);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
681
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
682 You get something that looks like the control polyline "inscribed"
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
683 inside the spline.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
684
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
685 =back
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
686
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
687 Adding "good" control points is subjective; this particular
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
688 algorithm reveals its author's tastes.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
689 In the future, you may be able to alter the taste slightly
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
690 via parameters to the algorithm. For The Hubristic: please
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
691 build a better one!
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
692
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
693 And for The Impatient: note that addControlPoints() returns a
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
694 polyline, so you can pile up the the call like this,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
695 if you'd like:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
696
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
697 $image->polyline($polyline->addControlPoints()->toSpline(),$mauve);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
698
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
699 =back
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
700
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
701 =head1 New GD::Image Methods
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
702
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
703 =over 5
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
704
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
705 =item C<polyline>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
706
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
707 C<$image-E<gt>polyline(polyline,color)> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
708
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
709 $image->polyline($polyline,$black)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
710
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
711 This draws a polyline with the specified color.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
712 Both real color indexes and the special
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
713 colors gdBrushed, gdStyled and gdStyledBrushed can be specified.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
714
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
715 Neither the polyline() method or the polygon() method are very
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
716 picky: you can call either method with either a GD::Polygon or a GD::Polyline.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
717 The I<method> determines if the shape is "closed" or "open" as drawn, I<not>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
718 the object type.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
719
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
720 =item C<polydraw>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
721
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
722 C<$image-E<gt>polydraw(polything,color)> I<object method>
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
723
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
724 $image->polydraw($poly,$black)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
725
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
726 This method draws the polything as expected (polygons are closed,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
727 polylines are open) by simply checking the object type and calling
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
728 either $image->polygon() or $image->polyline().
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
729
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
730 =back
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
731
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
732 =head1 Examples
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
733
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
734 Please see file "polyline-examples.pl" that is included with the distribution.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
735
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
736 =head1 See Also
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
737
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
738 For more info on Bezier splines, see http://www.webreference.com/dlab/9902/bezier.html.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
739
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
740 =head1 Future Features
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
741
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
742 On the drawing board are additional features such as:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
743
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
744 - polygon winding algorithms (to determine if a point is "inside" or "outside" the polygon)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
745
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
746 - new polygon from bounding box
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
747
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
748 - find bounding polygon (tightest fitting simple convex polygon for a given set of vertices)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
749
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
750 - addPts() method to add many points at once
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
751
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
752 - clone() method for polygon
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
753
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
754 - functions to interwork GD with SVG
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
755
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
756 Please provide input on other possible features you'd like to see.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
757
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
758 =head1 Author
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
759
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
760 This module has been written by Daniel J. Harasty.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
761 Please send questions, comments, complaints, and kudos to him
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
762 at harasty@cpan.org.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
763
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
764 Thanks to Lincoln Stein for input and patience with me and this,
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
765 my first CPAN contribution.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
766
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
767 =head1 Copyright Information
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
768
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
769 The Polyline.pm module is copyright 2002, Daniel J. Harasty. It is
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
770 distributed under the same terms as Perl itself. See the "Artistic
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
771 License" in the Perl source code distribution for licensing terms.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
772
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
773 The latest version of Polyline.pm is available at
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
774 your favorite CPAN repository and/or
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
775 along with GD.pm by Lincoln D. Stein at http://stein.cshl.org/WWW/software/GD.
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
776
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
777 =cut
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
778
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
779 # future:
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
780 # addPts
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
781 # boundingPolygon
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
782 # addControlPoints('method' => 'fitToSegments', 'numSegs' => 10)
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
783 # toSpline('csr' => 1/4);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
784
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
785 # GD::Color
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
786 # colorMap('x11' | 'svg' | <filename> )
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
787 # colorByName($image, 'orange');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
788 # setImage($image);
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
789 # cbn('orange');
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
790 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
791 #
e94de0ea3351 Uploaded
dereeper
parents:
diff changeset
792 #