<?xml version="1.0" encoding="windows-1252"?>
<node id="980572" title="J-spline Perl implementation" created="2012-07-08 06:48:12" updated="2012-07-08 06:48:12">
<type id="1042">
CUFP</type>
<author id="980468">
t-k</author>
<data>
<field name="doctext">
J-spline documentation:  http://faculty.cs.tamu.edu/schaefer/research/js.pdf

&lt;code&gt;#!/usr/bin/perl
use warnings;
use strict;
use Glib qw/TRUE FALSE/;
use Gtk2 -init;

my $xsize             = 400;
my $ysize             = 400;
my $subdivision_level = 5;

my @points =
  ( '120', '350', '100', '350', '80', '350', '80', '210', '120', '100', '260', '50', '220', '210', '220', '350', '200', '350', '180', '350' ); 
my $area;

my %allocated_colors;
my ( $x0, $y0, $x1, $y1, $width, ) = ( 0, 0, 0, 0 );

my $window = new Gtk2::Window("toplevel");
$window-&gt;signal_connect( "delete_event", sub { Gtk2-&gt;main_quit; } );
$window-&gt;set_border_width(10);
$window-&gt;set_size_request( 640, 480 );
$window-&gt;set_position('center');

my $vbox = Gtk2::VBox-&gt;new( 0, 0 );
$window-&gt;add($vbox);
$vbox-&gt;set_border_width(2);

my $hbox = Gtk2::HBox-&gt;new( 0, 0 );
$vbox-&gt;pack_start( $hbox, 1, 1, 0 );
$hbox-&gt;set_size_request( 320, 240 );
$hbox-&gt;set_border_width(2);

my $hbox1 = Gtk2::HBox-&gt;new( 0, 0 );
$vbox-&gt;pack_start( $hbox1, 0, 0, 0 );
$hbox1-&gt;set_border_width(2);

my $button1 = Gtk2::Button-&gt;new('Generate');
$hbox1-&gt;pack_start( $button1, FALSE, FALSE, 2 );
$button1-&gt;signal_connect( clicked =&gt; sub { start_drawing($area) } );

my $button2 = Gtk2::Button-&gt;new('Exit');
$hbox1-&gt;pack_start( $button2, FALSE, FALSE, 2 );
$button2-&gt;signal_connect( clicked =&gt; sub { exit; } );

my $scwin = Gtk2::ScrolledWindow-&gt;new();
my $ha1   = $scwin-&gt;get_hadjustment;
$scwin-&gt;set_policy( 'always', 'never' );

my $vp = Gtk2::Viewport-&gt;new( undef, undef );
$scwin-&gt;add($vp);
$hbox-&gt;pack_start( $scwin, 1, 1, 0 );

$area = new Gtk2::DrawingArea;
$area-&gt;size( $xsize, $ysize );
$vp-&gt;add($area);

$area-&gt;set_events(
	[
		qw/exposure-mask
		  leave-notify-mask
		  button-press-mask
		  pointer-motion-mask
		  pointer-motion-hint-mask/
	]
);

$area-&gt;signal_connect( button_press_event =&gt; \&amp;button_press_event );

$window-&gt;show_all;

Gtk2-&gt;main;

sub get_color {
	my ( $colormap, $name ) = @_;
	my $ret;

	if ( $ret = $allocated_colors{$name} ) {
		return $ret;
	}

	my $color = Gtk2::Gdk::Color-&gt;parse($name);
	$colormap-&gt;alloc_color( $color, TRUE, TRUE );

	$allocated_colors{$name} = $color;

	return $color;
}

sub draw_line {
	my ( $widget, $line, $color ) = @_;

	my $colormap = $widget-&gt;window-&gt;get_colormap;

	my $gc = $widget-&gt;{gc} || new Gtk2::Gdk::GC $widget-&gt;window;
	$gc-&gt;set_foreground( get_color( $colormap, $color ) );

	$widget-&gt;window-&gt;draw_lines( $gc, @$line );
	$gc-&gt;set_foreground( get_color( $colormap, 'black' ) );
	$widget-&gt;window-&gt;draw_points( $gc, @$line );
}

sub start_drawing {
	my $area = shift;

	&amp;draw_line( $area, [@points], 'blue' );

	my $a;
	my $b;
	my $k = 0;
	while ( $k++ &lt; $subdivision_level ) {
		my $j = 0;
		my @tmp;
		while ( $j &lt; $#points ) {
			$a = $b = 0.5;
			if ( $j == 0 ) {

				push( @tmp, $points[$j] );
				push( @tmp, $points[ $j + 1 ] );
			}
			elsif ( $j + 3 &lt;= $#points ) {
				my ( $pt1, $pt2 );

				#push( @tmp, $points[$j] );
				#push( @tmp, $points[ $j + 1 ] );

				$pt1 =
				  ( $a * $points[ $j - 2 ] +
					  ( 8 - 2 * $a ) * $points[$j] +
					  $a * $points[ $j + 2 ] ) / 8;
				$pt2 =
				  ( $a * $points[ $j - 1 ] +
					  ( 8 - 2 * $a ) * $points[ $j + 1 ] +
					  $a * $points[ $j + 3 ] ) / 8;
				push( @tmp, int($pt1) );
				push( @tmp, int($pt2) );
			}
			if ( $j + 5 &lt;= $#points &amp;&amp; $j &gt; 0) {
				my ( $pt1, $pt2 );

				#push( @tmp, $points[ $j + 2 ] );
				#push( @tmp, $points[ $j + 3 ] );

				$pt1 =
				  ( ( $b - 1 ) * $points[$j -2] +
					  ( 9 - $b ) * $points[ $j ] +
					  ( 9 - $b ) * $points[ $j + 2 ] +
					  ( $b - 1 ) * $points[ $j + 4 ] ) / 16;
				$pt2 =
				  ( ( $b - 1 ) * $points[ $j -1 ] +
					  ( 9 - $b ) * $points[ $j + 1 ] +
					  ( 9 - $b ) * $points[ $j + 3 ] +
					  ( $b - 1 ) * $points[ $j + 5 ] ) / 16;
				push( @tmp, int($pt1) );
				push( @tmp, int($pt2) );
			}
			$j += 2;
		}
		push( @tmp, $points[ $#points - 1 ] );
		push( @tmp, $points[$#points] );
		@points = ();
		@points = @tmp;
		print "@points\n";
	}

	&amp;draw_line( $area, [@points], 'green' );
	print "@points";
}&lt;/code&gt;</field>
</data>
</node>
