diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
| commit | 3282be229999dc36c197b264d63063a18d136331 (patch) | |
| tree | 98a42db29d955b39e7bed1b599fdcc56c3a29de9 /lib/GD/Graph/lines3d.pm | |
| parent | cfdd733c17cfa4f1a43b827a656e9e53cc2524ac (diff) | |
| download | xxv-3282be229999dc36c197b264d63063a18d136331.tar.gz xxv-3282be229999dc36c197b264d63063a18d136331.tar.bz2 | |
* Update installation list with required modules
* Remove unused/doubled provided external perl moduls
Diffstat (limited to 'lib/GD/Graph/lines3d.pm')
| -rw-r--r-- | lib/GD/Graph/lines3d.pm | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/lib/GD/Graph/lines3d.pm b/lib/GD/Graph/lines3d.pm deleted file mode 100644 index dfd60c7..0000000 --- a/lib/GD/Graph/lines3d.pm +++ /dev/null @@ -1,522 +0,0 @@ -#========================================================================== -# Module: GD::Graph::lines3d -# -# Copyright (C) 1999,2001 Wadsack-Allen. All Rights Reserved. -# -# Based on GD::Graph::lines.pm,v 1.10 2000/04/15 mgjv -# Copyright (c) 1995-1998 Martien Verbruggen -# -#-------------------------------------------------------------------------- -# Date Modification Author -# ------------------------------------------------------------------------- -# 1999SEP18 Created 3D line chart class (this module) JAW -# 1999SEP19 Finished overwrite 1 style JAW -# 1999SEP19 Polygon'd linewidth rendering JAW -# 2000SEP19 Converted to a GD::Graph class JAW -# 2000APR18 Modified for compatibility with GD::Graph 1.30 JAW -# 2000APR24 Fixed a lot of rendering bugs JAW -# 2000AUG19 Changed render code so lines have consitent width JAW -# 2000AUG21 Added 3d shading JAW -# 2000AUG24 Fixed shading top/botttom vs. postive/negative slope JAW -# 2000SEP04 For single point "lines" made a short segment JAW -# 2000OCT09 Fixed bug in rendering of legend JAW -#========================================================================== -# TODO -# ** The new mitred corners don't work well at data anomlies. Like -# the set (0,0,1,0,0,0,1,0,1) Looks really wrong! -# * Write a draw_data_set that draws the line so they appear to pass -# through one another. This means drawing a border edge at each -# intersection of the data lines so the points of pass-through show. -# Probably want to draw all filled polygons, then run through the data -# again finding intersections of line segments and drawing those edges. -#========================================================================== -package GD::Graph::lines3d; - -use strict; - -use GD; -use GD::Graph::axestype3d; -use Data::Dumper; - -@GD::Graph::lines3d::ISA = qw( GD::Graph::axestype3d ); -$GD::Graph::lines3d::VERSION = '0.63'; - -my $PI = 4 * atan2(1, 1); - -my %Defaults = ( - # The depth of the line in their extrusion - - line_depth => 10, -); - -sub initialise() -{ - my $self = shift; - - my $rc = $self->SUPER::initialise(); - - while( my($key, $val) = each %Defaults ) { - $self->{$key} = $val - - # *** [JAW] - # Should we reset the depth_3d param based on the - # line_depth, numsets and overwrite parameters, here? - # - } # end while - - return $rc; - -} # end initialize - -sub set -{ - my $s = shift; - my %args = @_; - - $s->{_set_error} = 0; - - for (keys %args) - { - /^line_depth$/ and do - { - $s->{line_depth} = $args{$_}; - delete $args{$_}; - next; - }; - } - - return $s->SUPER::set(%args); -} # end set - -# PRIVATE - -# [JAW] Changed to draw_data intead of -# draw_data_set to allow better control -# of multiple set rendering -sub draw_data -{ - my $self = shift; - my $d = $self->{_data}; - my $g = $self->{graph}; - - $self->draw_data_overwrite( $g, $d ); - - # redraw the 'zero' axis, front and right - if( $self->{zero_axis} ) { - $g->line( - $self->{left}, $self->{zeropoint}, - $self->{right}, $self->{zeropoint}, - $self->{fgci} ); - $g->line( - $self->{right}, $self->{zeropoint}, - $self->{right} + $self->{depth_3d}, $self->{zeropoint} - $self->{depth_3d}, - $self->{fgci} ); - } # end if - - # redraw the box face - if ( $self->{box_axis} ) { - # Axes box - $g->rectangle($self->{left}, $self->{top}, $self->{right}, $self->{bottom}, $self->{fgci}); - $g->line($self->{right}, $self->{top}, $self->{right} + $self->{depth_3d}, $self->{top} - $self->{depth_3d}, $self->{fgci}); - $g->line($self->{right}, $self->{bottom}, $self->{right} + $self->{depth_3d}, $self->{bottom} - $self->{depth_3d}, $self->{fgci}); - } # end if - - return $self; - -} # end draw_data - -# Copied from MVERB source -sub pick_line_type -{ - my $self = shift; - my $num = shift; - - ref $self->{line_types} ? - $self->{line_types}[ $num % (1 + $#{$self->{line_types}}) - 1 ] : - $num % 4 ? $num % 4 : 4 -} - -# ---------------------------------------------------------- -# Sub: draw_data_overwrite -# -# Args: $gd -# $gd The GD object to draw on -# -# Description: Draws each line segment for each set. Runs -# over sets, then points so that the appearance is better. -# ---------------------------------------------------------- -# Date Modification Author -# ---------------------------------------------------------- -# 19SEP1999 Added this for overwrite support. JW -# 20AUG2000 Changed structure to use points 'objects' JW -# ---------------------------------------------------------- -sub draw_data_overwrite { - my $self = shift; - my $g = shift; - my @points_cache; - - my $i; - for $i (0 .. $self->{_data}->num_points()) - { - my $j; - for $j (1 .. $self->{_data}->num_sets()) - { - my @values = $self->{_data}->y_values($j) or - return $self->_set_error( "Impossible illegal data set: $j", $self->{_data}->error ); - - if( $self->{_data}->num_points() == 1 && $i == 1 ) { - # Copy the first point to the "second" - $values[$i] = $values[0]; - } # end if - - next unless defined $values[$i]; - - # calculate offset of this line - # *** Should offset be the max of line_depth - # and depth_3d/numsets? [JAW] - # - my $offset = $self->{line_depth} * ($self->{_data}->num_sets() - $j); - - # Get the coordinates of the previous point, if this is the first - # point make a point object and start over (i.e. next;) - unless( $i ) { - my( $xb, $yb ); - if (defined($self->{x_min_value}) && defined($self->{x_max_value})) { - ($xb, $yb) = $self->val_to_pixel( $self->{_data}->get_x($i), $values[$i], $j ); - } else { - ($xb, $yb) = $self->val_to_pixel( $i + 1, $values[$i], $j ); - } # end if - $xb += $offset; - $yb -= $offset; - $points_cache[$i][$j] = { coords => [$xb, $yb] }; - next; - } # end unless - - # Pick a data colour, calc shading colors too, if requested - my( @rgb ) = $self->pick_data_clr( $j ); - my $dsci = $self->set_clr( @rgb ); - if( $self->{'3d_shading'} ) { - $self->{'3d_highlights'}[$dsci] = $self->set_clr( $self->_brighten( @rgb ) ); - $self->{'3d_shadows'}[$dsci] = $self->set_clr( $self->_darken( @rgb ) ); - } # end if - - # Get the type - my $type = $self->pick_line_type($j); - - # Get the coordinates of the this point - unless( ref $points_cache[$i][$j] ) { - my( $xe, $ye ); - if( defined($self->{x_min_value}) && defined($self->{x_max_value}) ) { - ( $xe, $ye ) = $self->val_to_pixel( $self->{_data}->get_x($i), $values[$i], $j ); - } else { - ( $xe, $ye ) = $self->val_to_pixel($i + 1, $values[$i], $j); - } # end if - $xe += $offset; - $ye -= $offset; - $points_cache[$i][$j] = { coords => [$xe, $ye] }; - } # end if - - # Find the coordinates of the next point - if( defined $values[$i + 1] ) { - my( $xe, $ye ); - if( defined($self->{x_min_value}) && defined($self->{x_max_value}) ) { - ( $xe, $ye ) = $self->val_to_pixel( $self->{_data}->get_x($i + 1), $values[$i + 1], $j ); - } else { - ( $xe, $ye ) = $self->val_to_pixel($i + 2, $values[$i + 1], $j); - } # end if - $xe += $offset; - $ye -= $offset; - $points_cache[$i + 1][$j] = { coords => [$xe, $ye] }; - } # end if - - if( $self->{_data}->num_points() == 1 && $i == 1 ) { - # Nudge the x coords back- and forwards - my $n = int(($self->{right} - $self->{left}) / 30); - $n = 2 if $n < 2; - $points_cache[$i][$j]{coords}[0] = $points_cache[$i - 1][$j]{coords}[0] + $n; - $points_cache[$i - 1][$j]{coords}[0] -= $n; - } # end if - - # Draw the line segment - $self->draw_line( $points_cache[$i - 1][$j], - $points_cache[$i][$j], - $points_cache[$i + 1][$j], - $type, - $dsci ); - - # Draw the end cap if last segment - if( $i >= $self->{_data}->num_points() - 1 ) { - my $poly = new GD::Polygon; - $poly->addPt( $points_cache[$i][$j]{face}[0], $points_cache[$i][$j]{face}[1] ); - $poly->addPt( $points_cache[$i][$j]{face}[2], $points_cache[$i][$j]{face}[3] ); - $poly->addPt( $points_cache[$i][$j]{face}[2] + $self->{line_depth}, $points_cache[$i][$j]{face}[3] - $self->{line_depth} ); - $poly->addPt( $points_cache[$i][$j]{face}[0] + $self->{line_depth}, $points_cache[$i][$j]{face}[1] - $self->{line_depth} ); - if( $self->{'3d_shading'} ) { - $g->filledPolygon( $poly, $self->{'3d_shadows'}[$dsci] ); - } else { - $g->filledPolygon( $poly, $dsci ); - } # end if - $g->polygon( $poly, $self->{fgci} ); - } # end if - - } # end for -- $self->{_data}->num_sets() - } # end for -- $self->{_data}->num_points() - -} # end sub draw_data_overwrite - -# ---------------------------------------------------------- -# Sub: draw_line -# -# Args: $prev, $this, $next, $type, $clr -# $prev A hash ref for the prev point's object -# $this A hash ref for this point's object -# $next A hash ref for the next point's object -# $type A predefined line type (2..4) = (dashed, dotted, dashed & dotted) -# $clr The color (colour) index to use for the fill -# -# Point "Object" has these properties: -# coords A 2 element array of the coordinates for the line -# (this should be filled in before calling) -# face An 4 element array of end points for the face -# polygon. This will be populated by this method. -# -# Description: Draws a line segment in 3d extrusion that -# connects the prev point the the this point. The next point -# is used to calculate the mitre at the joint. -# ---------------------------------------------------------- -# Date Modification Author -# ---------------------------------------------------------- -# 18SEP1999 Modified MVERB source to work on data -# point, not data set for better rendering JAW -# 19SEP1999 Ploygon'd line rendering for better effect JAW -# 19AUG2000 Made line width perpendicular JAW -# 19AUG2000 Changed parameters to use %line_seg hash/obj JAW -# 20AUG2000 Mitred joints of line segments JAW -# ---------------------------------------------------------- -sub draw_line -{ - my $self = shift; - my( $prev, $this, $next, $type, $clr ) = @_; - my $xs = $prev->{coords}[0]; - my $ys = $prev->{coords}[1]; - my $xe = $this->{coords}[0]; - my $ye = $this->{coords}[1]; - - my $lw = $self->{line_width}; - my $lts = $self->{line_type_scale}; - - my $style = gdStyled; - my @pattern = (); - - LINE: { - - ($type == 2) && do { - # dashed - - for (1 .. $lts) { push @pattern, $clr } - for (1 .. $lts) { push @pattern, gdTransparent } - - $self->{graph}->setStyle(@pattern); - - last LINE; - }; - - ($type == 3) && do { - # dotted, - - for (1 .. 2) { push @pattern, $clr } - for (1 .. 2) { push @pattern, gdTransparent } - - $self->{graph}->setStyle(@pattern); - - last LINE; - }; - - ($type == 4) && do { - # dashed and dotted - - for (1 .. $lts) { push @pattern, $clr } - for (1 .. 2) { push @pattern, gdTransparent } - for (1 .. 2) { push @pattern, $clr } - for (1 .. 2) { push @pattern, gdTransparent } - - $self->{graph}->setStyle(@pattern); - - last LINE; - }; - - # default: solid - $style = $clr; - } - - # [JAW] Removed the dataset loop for better results. - - # Need the setstyle to reset - $self->{graph}->setStyle(@pattern) if (@pattern); - - # - # Find the x and y offsets for the edge of the front face - # Do this by adjusting them perpendicularly from the line - # half the line width in front and in back. - # - my( $lwyoff, $lwxoff ); - if( $xe == $xs ) { - $lwxoff = $lw / 2; - $lwyoff = 0; - } elsif( $ye == $ys ) { - $lwxoff = 0; - $lwyoff = $lw / 2; - } else { - my $ln = sqrt( ($ys-$ye)**2 + ($xe-$xs)**2 ); - $lwyoff = ($xe-$xs) / $ln * $lw / 2; - $lwxoff = ($ys-$ye) / $ln * $lw / 2; - } # end if - - # For first line, figure beginning point - unless( defined $prev->{face}[0] ) { - $prev->{face} = []; - $prev->{face}[0] = $xs - $lwxoff; - $prev->{face}[1] = $ys - $lwyoff; - $prev->{face}[2] = $xs + $lwxoff; - $prev->{face}[3] = $ys + $lwyoff; - } # end unless - - # Calc and store this point's face coords - unless( defined $this->{face}[0] ) { - $this->{face} = []; - $this->{face}[0] = $xe - $lwxoff; - $this->{face}[1] = $ye - $lwyoff; - $this->{face}[2] = $xe + $lwxoff; - $this->{face}[3] = $ye + $lwyoff; - } # end if - - # Now find next point and nudge these coords to mitre - if( ref $next->{coords} eq 'ARRAY' ) { - my( $lwyo2, $lwxo2 ); - my( $x2, $y2 ) = @{$next->{coords}}; - if( $x2 == $xe ) { - $lwxo2 = $lw / 2; - $lwyo2 = 0; - } elsif( $y2 == $ye ) { - $lwxo2 = 0; - $lwyo2 = $lw / 2; - } else { - my $ln2 = sqrt( ($ye-$y2)**2 + ($x2-$xe)**2 ); - $lwyo2 = ($x2-$xe) / $ln2 * $lw / 2; - $lwxo2 = ($ye-$y2) / $ln2 * $lw / 2; - } # end if - $next->{face} = []; - $next->{face}[0] = $x2 - $lwxo2; - $next->{face}[1] = $y2 - $lwyo2; - $next->{face}[2] = $x2 + $lwxo2; - $next->{face}[3] = $y2 + $lwyo2; - - # Now get the intersecting coordinates - my $mt = ($ye - $ys)/($xe - $xs); - my $mn = ($y2 - $ye)/($x2 - $xe); - my $bt = $this->{face}[1] - $this->{face}[0] * $mt; - my $bn = $next->{face}[1] - $next->{face}[0] * $mn; - if( $mt != $mn ) { - $this->{face}[0] = ($bn - $bt) / ($mt - $mn); - } # end if - $this->{face}[1] = $mt * $this->{face}[0] + $bt; - $bt = $this->{face}[3] - $this->{face}[2] * $mt; - $bn = $next->{face}[3] - $next->{face}[2] * $mn; - if( $mt != $mn ) { - $this->{face}[2] = ($bn - $bt) / ($mt - $mn); - } # end if - $this->{face}[3] = $mt * $this->{face}[2] + $bt; - } # end if - - - # Make the top/bottom polygon - my $poly = new GD::Polygon; - if( ($ys-$ye)/($xe-$xs) > 1 ) { - $poly->addPt( $prev->{face}[2], $prev->{face}[3] ); - $poly->addPt( $this->{face}[2], $this->{face}[3] ); - $poly->addPt( $this->{face}[2] + $self->{line_depth}, $this->{face}[3] - $self->{line_depth} ); - $poly->addPt( $prev->{face}[2] + $self->{line_depth}, $prev->{face}[3] - $self->{line_depth} ); - if( $self->{'3d_shading'} && $style == $clr ) { - if( ($ys-$ye)/($xe-$xs) > 0 ) { - $self->{graph}->filledPolygon( $poly, $self->{'3d_shadows'}[$clr] ); - } else { - $self->{graph}->filledPolygon( $poly, $self->{'3d_highlights'}[$clr] ); - } # end if - } else { - $self->{graph}->filledPolygon( $poly, $style ); - } # end if - } else { - $poly->addPt( $prev->{face}[0], $prev->{face}[1] ); - $poly->addPt( $this->{face}[0], $this->{face}[1] ); - $poly->addPt( $this->{face}[0] + $self->{line_depth}, $this->{face}[1] - $self->{line_depth} ); - $poly->addPt( $prev->{face}[0] + $self->{line_depth}, $prev->{face}[1] - $self->{line_depth} ); - if( $self->{'3d_shading'} && $style == $clr ) { - if( ($ys-$ye)/($xe-$xs) < 0 ) { - $self->{graph}->filledPolygon( $poly, $self->{'3d_shadows'}[$clr] ); - } else { - $self->{graph}->filledPolygon( $poly, $self->{'3d_highlights'}[$clr] ); - } # end if - } else { - $self->{graph}->filledPolygon( $poly, $style ); - } # end if - } # end if - $self->{graph}->polygon( $poly, $self->{fgci} ); - - # *** This paints dashed and dotted patterns on the faces of - # the polygons. They don't look very good though. Would it - # be better to extrude the style as well as the lines? - # Otherwise could also be improved by using gdTiled instead of - # gdStyled and making the tile a transform of the line style - # for each face. [JAW] - - # Make the face polygon - $poly = new GD::Polygon; - $poly->addPt( $prev->{face}[0], $prev->{face}[1] ); - $poly->addPt( $this->{face}[0], $this->{face}[1] ); - $poly->addPt( $this->{face}[2], $this->{face}[3] ); - $poly->addPt( $prev->{face}[2], $prev->{face}[3] ); - - $self->{graph}->filledPolygon( $poly, $style ); - $self->{graph}->polygon( $poly, $self->{fgci} ); - -} # end draw line - -# ---------------------------------------------------------- -# Sub: draw_legend_marker -# -# Args: $dsn, $x, $y -# $dsn The dataset number to draw the marker for -# $x The x position of the marker -# $y The y position of the marker -# -# Description: Draws the legend marker for the specified -# dataset number at the given coordinates -# ---------------------------------------------------------- -# Date Modification Author -# ---------------------------------------------------------- -# 2000OCT06 Fixed rendering bugs JW -# ---------------------------------------------------------- -sub draw_legend_marker -{ - my $self = shift; - my ($n, $x, $y) = @_; - - my $ci = $self->set_clr($self->pick_data_clr($n)); - my $type = $self->pick_line_type($n); - - $y += int($self->{lg_el_height}/2); - - # Joe Smith <jms@tardis.Tymnet.COM> - local($self->{line_width}) = 2; # Make these show up better - - $self->draw_line( - { coords => [$x, $y] }, - { coords => [$x + $self->{legend_marker_width}, $y] }, - undef, - $type, - $ci - ); - -} # end draw_legend_marker - -1; |
