Perl Cairo tutorial - Scale

This is one page of a Perl Cairo tutorial.

This example draws a sine curve. It demonstrates scale and translate.
#!/usr/bin/perl
use warnings;
use strict;
use POSIX qw/DBL_MAX DBL_MIN/;
use Cairo;
my $size = 400;
my $surface = Cairo::ImageSurface->create ('argb32', ($size) x 2);
my $cr = Cairo::Context->create ($surface);
use constant M_PI => 3.14159265359;
my $start = -3*M_PI;
my $end = 3*M_PI;
$cr->set_line_width (0.2);
$cr->set_source_rgb (0, 0, 0.2);
draw_function ($cr, $start, $end, \& my_sin);
my $png = 'scale.png';
$surface->write_to_png ($png);
exit;

sub my_sin
{
    my ($in) = @_;
    return sin ($in);
}

sub draw_function
{
    my ($cr, $start, $end, $function) = @_;
    # The number of steps of the function to take.
    my $steps = 100;
    my @values;
    # These are from POSIX.
    my $max = DBL_MIN;
    my $min = DBL_MAX;
    # A small margin for top and bottom so that the top and bottom of
    # the graph are not cut off.
    my $ymargin = 0.05;
    # Get the values of the function, and store the x, y pairs in
    # @values.
    for my $i (0..$steps) {
        my $x = ($end - $start) / $steps * $i + $start;
        my $y = &{$function} ($x);
        if ($y > $max) {
            $max = $y;
        }
        if ($y < $min) {
            $min = $y;
        }
        push @values, [$x, $y];
    }
    # This creates a scaled path, but doesn't call "stroke" on it,
    # since that will cause the x and y parts of the line to have
    # different thicknesses.
    $cr->save ();
    $cr->new_path ();
    # Scale the graph appropriately.
    my $gap = $max - $min;
    my $yscale = (1 - 2 * $ymargin) * $size / $gap;
    $cr->scale ($size / ($end - $start), $yscale);
    # Move the origin appropriately.
    $cr->translate (-$start, $gap*$ymargin-$min);
    # Draw the graph.
    $cr->move_to (@{$values[0]});
    for my $i (1..$steps) {
        $cr->line_to (@{$values[$i]});
    }
    $cr->restore ();
    # Now stroke the line.
    $cr->set_line_width (3);
    $cr->stroke ();
}

(download)


Copyright © Ben Bullock 2009-2023. All rights reserved. For comments, questions, and corrections, please email Ben Bullock (benkasminbullock@gmail.com) or use the discussion group at Google Groups. / Privacy / Disclaimer