#!/usr/bin/perl -w
use strict;

use constant TRUE=>1;
use constant FALSE=>!TRUE;

use constant pi=>4*atan2(1,1);

my ($appname,$version)=qw[Meander 0.0.H];

my @packages;
my @incs;
my @libs;

BEGIN {
    @packages=qw[glib-2.0 gtk+-2.0];
    @incs=map qx[pkg-config $_ --cflags], @packages;
    @libs=map qx[pkg-config $_ --libs], @packages;
    chomp (@incs, @libs);
    push @incs, "-I/usr/lib/perl5/Glib/Install"; # ewww
}

use Inline C => <<'EOF', INC => "@incs", LIBS => "@libs";

#include <gperl.h>
#include <gtk/gtk.h>

#define THRESH 1

GtkWidget *da;
double *motif;
int mlen;

int count;
int lines;

#define BUFSIZE 1024
GdkPoint buf[BUFSIZE+1], *bufptr;

static void draw_points (void) {
    (lines?gdk_draw_lines:gdk_draw_points)
	(da->window,
	 da->style->fg_gc[GTK_WIDGET_STATE (da)],
	 buf, bufptr-buf);

    if (lines)
	*buf=*--bufptr;

    count+=bufptr-buf;
    bufptr=buf;
    if (lines)
	bufptr++;
}

static void meander (double x, double y, double dx, double dy, int iter) {
    int i;
    double *ptr = motif;
    
    for (i=0; i<mlen; i++) {
	double xx=*ptr++;
	double yy=*ptr++;
	
	double xn = dx*xx+dy*yy;
	double yn = dy*xx-dx*yy;
	
	if (!iter || xn*xn+yn*yn<THRESH) {
	    bufptr->x = x; bufptr->y = y;
	    if (++bufptr == buf+BUFSIZE)
		draw_points();
	} else
	    meander (x, y, xn, yn, iter-1);

	x += xn;
	y += yn;
    }
}

int draw_meander (SV *points_ref, SV *area, int xstart, int ystart, int dx, int dy, int maxiter, int l) {
    AV *points;
    int len;
    double *ptr;
    int i;

    if (!SvROK(points_ref))
	croak ("oops");

    points = (AV*)SvRV (points_ref);

    len = av_len (points)+1;
    ptr = motif = malloc (len * sizeof (double));

    if (!motif)
	croak ("out of memory");

    if (len & 1)
	croak ("oops");

    mlen = len/2;

    for (i=0; i<len; i++) {
	SV **val = av_fetch (points, i, 0);
#if 0
	if (!SvNOK (*val))
	    croak ("oops");
#endif
	*ptr++=(double)SvNV(*val);
    }

    da = gperl_get_object_check (area, GTK_TYPE_WIDGET);

    bufptr = buf;
    count = 0;
    lines = l;
    
    if (maxiter--)
	meander (xstart, ystart, dx, dy, maxiter);
    else {
	bufptr->x = xstart;
	bufptr->y = ystart;
	bufptr++;
    }
	
    free (motif);

    bufptr->x = xstart+dx;
    bufptr->y = ystart+dy;
    bufptr++;
    
    draw_points();

    return count;
}

EOF

use Gnome2;
use Gnome2::Canvas;
use Gtk2 '-init';
use Gtk2::GladeXML;

Gnome2::Program->init ($appname, $version);

#my $glade=Gtk2::GladeXML->new("meander.glade");
my $glade=Gtk2::GladeXML->new_from_buffer(<<'EOF');
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>
<requires lib="gnome"/>
<requires lib="canvas"/>

<widget class="GtkWindow" id="dispwin">
  <property name="visible">True</property>
  <property name="title" translatable="yes">Display</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="default_width">600</property>
  <property name="default_height">500</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>

  <child>
    <widget class="GtkDrawingArea" id="drawingarea">
      <property name="visible">True</property>
      <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
      <property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property>
      <signal name="expose_event" handler="on_expose_event" last_modification_time="Thu, 26 Feb 2004 22:23:14 GMT"/>
      <signal name="button_press_event" handler="on_drawingarea_click" last_modification_time="Sun, 29 Feb 2004 17:23:18 GMT"/>
    </widget>
  </child>
</widget>

<widget class="GtkWindow" id="editwin">
  <property name="visible">True</property>
  <property name="title" translatable="yes">Meander</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="default_height">300</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <signal name="destroy" handler="gtk_main_quit" last_modification_time="Thu, 26 Feb 2004 01:22:51 GMT"/>

  <child>
    <widget class="GtkVBox" id="vbox1">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child>
	<widget class="GtkMenuBar" id="menubar1">
	  <property name="visible">True</property>

	  <child>
	    <widget class="GtkMenuItem" id="file1">
	      <property name="visible">True</property>
	      <property name="stock_item">GNOMEUIINFO_MENU_FILE_TREE</property>

	      <child>
		<widget class="GtkMenu" id="file1_menu">

		  <child>
		    <widget class="GtkImageMenuItem" id="new1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_NEW_ITEM</property>
		      <property name="label" translatable="yes">_New</property>
		      <property name="use_underline">True</property>
		      <signal name="activate" handler="on_new1_activate" last_modification_time="Thu, 26 Feb 2004 00:45:09 GMT"/>
		    </widget>
		  </child>

		  <child>
		    <widget class="GtkImageMenuItem" id="open1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_OPEN_ITEM</property>
		      <signal name="activate" handler="on_open1_activate" last_modification_time="Thu, 26 Feb 2004 00:45:09 GMT"/>
		    </widget>
		  </child>

		  <child>
		    <widget class="GtkImageMenuItem" id="save1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_SAVE_ITEM</property>
		      <signal name="activate" handler="on_save1_activate" last_modification_time="Thu, 26 Feb 2004 00:45:09 GMT"/>
		    </widget>
		  </child>

		  <child>
		    <widget class="GtkImageMenuItem" id="save_as1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_SAVE_AS_ITEM</property>
		      <signal name="activate" handler="on_save_as1_activate" last_modification_time="Thu, 26 Feb 2004 00:45:09 GMT"/>
		    </widget>
		  </child>

		  <child>
		    <widget class="GtkMenuItem" id="separator3">
		      <property name="visible">True</property>
		    </widget>
		  </child>

		  <child>
		    <widget class="GtkImageMenuItem" id="quit1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_EXIT_ITEM</property>
		      <signal name="activate" handler="gtk_main_quit" last_modification_time="Mon, 01 Mar 2004 03:02:14 GMT"/>
		    </widget>
		  </child>
		</widget>
	      </child>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkMenuItem" id="view1">
	      <property name="visible">True</property>
	      <property name="stock_item">GNOMEUIINFO_MENU_VIEW_TREE</property>

	      <child>
		<widget class="GtkMenu" id="view1_menu">

		  <child>
		    <widget class="GtkMenuItem" id="show_display_window">
		      <property name="visible">True</property>
		      <property name="label" translatable="yes">Show display window</property>
		      <property name="use_underline">True</property>
		      <signal name="activate" handler="on_show_display_window_activate" last_modification_time="Thu, 26 Feb 2004 02:49:31 GMT"/>
		    </widget>
		  </child>
		</widget>
	      </child>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkMenuItem" id="presets">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">_Presets</property>
	      <property name="use_underline">True</property>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkMenuItem" id="help1">
	      <property name="visible">True</property>
	      <property name="stock_item">GNOMEUIINFO_MENU_HELP_TREE</property>

	      <child>
		<widget class="GtkMenu" id="help1_menu">

		  <child>
		    <widget class="GtkImageMenuItem" id="about1">
		      <property name="visible">True</property>
		      <property name="stock_item">GNOMEUIINFO_MENU_ABOUT_ITEM</property>
		      <signal name="activate" handler="on_about1_activate" last_modification_time="Thu, 26 Feb 2004 00:45:09 GMT"/>
		    </widget>
		  </child>
		</widget>
	      </child>
	    </widget>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">False</property>
	</packing>
      </child>

      <child>
	<widget class="GtkFrame" id="frame2">
	  <property name="visible">True</property>
	  <property name="label_xalign">0</property>
	  <property name="label_yalign">0.5</property>
	  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>

	  <child>
	    <widget class="GtkHBox" id="hbox1">
	      <property name="visible">True</property>
	      <property name="homogeneous">False</property>
	      <property name="spacing">0</property>

	      <child>
		<widget class="GtkLabel" id="">
		  <property name="visible">True</property>
		  <property name="label" translatable="yes">Number of sides</property>
		  <property name="use_underline">False</property>
		  <property name="use_markup">False</property>
		  <property name="justify">GTK_JUSTIFY_LEFT</property>
		  <property name="wrap">False</property>
		  <property name="selectable">False</property>
		  <property name="xalign">0.5</property>
		  <property name="yalign">0.5</property>
		  <property name="xpad">0</property>
		  <property name="ypad">0</property>
		</widget>
		<packing>
		  <property name="padding">0</property>
		  <property name="expand">False</property>
		  <property name="fill">False</property>
		</packing>
	      </child>

	      <child>
		<widget class="GtkCombo" id="combo1">
		  <property name="visible">True</property>
		  <property name="value_in_list">False</property>
		  <property name="allow_empty">True</property>
		  <property name="case_sensitive">False</property>
		  <property name="enable_arrow_keys">True</property>
		  <property name="enable_arrows_always">False</property>

		  <child internal-child="entry">
		    <widget class="GtkEntry" id="sides">
		      <property name="visible">True</property>
		      <property name="can_focus">True</property>
		      <property name="editable">True</property>
		      <property name="visibility">True</property>
		      <property name="max_length">0</property>
		      <property name="text" translatable="yes"></property>
		      <property name="has_frame">True</property>
		      <property name="invisible_char" translatable="yes">*</property>
		      <property name="activates_default">False</property>
		      <signal name="changed" handler="on_sides_changed" last_modification_time="Fri, 27 Feb 2004 00:56:18 GMT"/>
		    </widget>
		  </child>

		  <child internal-child="list">
		    <widget class="GtkList" id="combo-list1">
		      <property name="visible">True</property>
		      <property name="selection_mode">GTK_SELECTION_BROWSE</property>

		      <child>
			<widget class="GtkListItem" id="listitem79">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">1 (line)</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkListItem" id="listitem80">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">2 (double-sided line)</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkListItem" id="listitem81">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">3 (triangle)</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkListItem" id="listitem82">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">4 (square)</property>
			</widget>
		      </child>
		    </widget>
		  </child>
		</widget>
		<packing>
		  <property name="padding">0</property>
		  <property name="expand">False</property>
		  <property name="fill">False</property>
		</packing>
	      </child>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkLabel" id="baseline-label">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">Baseline</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">False</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="type">label_item</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">2</property>
	  <property name="expand">False</property>
	  <property name="fill">True</property>
	</packing>
      </child>

      <child>
	<widget class="GtkFrame" id="frame3">
	  <property name="visible">True</property>
	  <property name="label_xalign">0</property>
	  <property name="label_yalign">0.5</property>
	  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>

	  <child>
	    <widget class="GtkVBox" id="vbox2">
	      <property name="visible">True</property>
	      <property name="homogeneous">False</property>
	      <property name="spacing">0</property>

	      <child>
		<widget class="GtkScrolledWindow" id="scrolledwindow2">
		  <property name="visible">True</property>
		  <property name="can_focus">True</property>
		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
		  <property name="shadow_type">GTK_SHADOW_NONE</property>
		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>

		  <child>
		    <widget class="GnomeCanvas" id="editcanvas">
		      <property name="visible">True</property>
		      <property name="can_focus">True</property>
		      <property name="anti_aliased">False</property>
		      <property name="scroll_x1">0</property>
		      <property name="scroll_y1">0.6</property>
		      <property name="scroll_x2">1</property>
		      <property name="scroll_y2">-0.6</property>
		      <property name="pixels_per_unit">150</property>
		    </widget>
		  </child>
		</widget>
		<packing>
		  <property name="padding">0</property>
		  <property name="expand">True</property>
		  <property name="fill">True</property>
		</packing>
	      </child>

	      <child>
		<widget class="GtkHBox" id="hbox2">
		  <property name="visible">True</property>
		  <property name="homogeneous">False</property>
		  <property name="spacing">0</property>

		  <child>
		    <widget class="GtkFrame" id="frame4">
		      <property name="visible">True</property>
		      <property name="label_xalign">0</property>
		      <property name="label_yalign">0.5</property>
		      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>

		      <child>
			<widget class="GtkVBox" id="vbox4">
			  <property name="visible">True</property>
			  <property name="homogeneous">False</property>
			  <property name="spacing">0</property>

			  <child>
			    <widget class="GtkTable" id="table1">
			      <property name="visible">True</property>
			      <property name="n_rows">2</property>
			      <property name="n_columns">4</property>
			      <property name="homogeneous">False</property>
			      <property name="row_spacing">0</property>
			      <property name="column_spacing">0</property>

			      <child>
				<widget class="GtkLabel" id="label5">
				  <property name="visible">True</property>
				  <property name="label" translatable="yes">X</property>
				  <property name="use_underline">False</property>
				  <property name="use_markup">False</property>
				  <property name="justify">GTK_JUSTIFY_LEFT</property>
				  <property name="wrap">False</property>
				  <property name="selectable">False</property>
				  <property name="xalign">0</property>
				  <property name="yalign">0.5</property>
				  <property name="xpad">0</property>
				  <property name="ypad">0</property>
				</widget>
				<packing>
				  <property name="left_attach">0</property>
				  <property name="right_attach">1</property>
				  <property name="top_attach">0</property>
				  <property name="bottom_attach">1</property>
				  <property name="x_options">fill</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkEntry" id="x">
				  <property name="visible">True</property>
				  <property name="can_focus">True</property>
				  <property name="editable">True</property>
				  <property name="visibility">True</property>
				  <property name="max_length">0</property>
				  <property name="text" translatable="yes"></property>
				  <property name="has_frame">True</property>
				  <property name="invisible_char" translatable="yes">*</property>
				  <property name="activates_default">False</property>
				  <property name="width_chars">5</property>
				  <signal name="changed" handler="on_xy_changed" last_modification_time="Thu, 26 Feb 2004 03:50:57 GMT"/>
				</widget>
				<packing>
				  <property name="left_attach">1</property>
				  <property name="right_attach">2</property>
				  <property name="top_attach">0</property>
				  <property name="bottom_attach">1</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkLabel" id="label6">
				  <property name="visible">True</property>
				  <property name="label" translatable="yes">Y</property>
				  <property name="use_underline">False</property>
				  <property name="use_markup">False</property>
				  <property name="justify">GTK_JUSTIFY_LEFT</property>
				  <property name="wrap">False</property>
				  <property name="selectable">False</property>
				  <property name="xalign">0</property>
				  <property name="yalign">0.5</property>
				  <property name="xpad">0</property>
				  <property name="ypad">0</property>
				</widget>
				<packing>
				  <property name="left_attach">0</property>
				  <property name="right_attach">1</property>
				  <property name="top_attach">1</property>
				  <property name="bottom_attach">2</property>
				  <property name="x_options">fill</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkEntry" id="y">
				  <property name="visible">True</property>
				  <property name="can_focus">True</property>
				  <property name="editable">True</property>
				  <property name="visibility">True</property>
				  <property name="max_length">0</property>
				  <property name="text" translatable="yes"></property>
				  <property name="has_frame">True</property>
				  <property name="invisible_char" translatable="yes">*</property>
				  <property name="activates_default">False</property>
				  <property name="width_chars">5</property>
				  <signal name="changed" handler="on_xy_changed" last_modification_time="Thu, 26 Feb 2004 03:50:42 GMT"/>
				</widget>
				<packing>
				  <property name="left_attach">1</property>
				  <property name="right_attach">2</property>
				  <property name="top_attach">1</property>
				  <property name="bottom_attach">2</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkLabel" id="label7">
				  <property name="visible">True</property>
				  <property name="label" translatable="yes">Angle</property>
				  <property name="use_underline">False</property>
				  <property name="use_markup">False</property>
				  <property name="justify">GTK_JUSTIFY_LEFT</property>
				  <property name="wrap">False</property>
				  <property name="selectable">False</property>
				  <property name="xalign">0</property>
				  <property name="yalign">0.5</property>
				  <property name="xpad">0</property>
				  <property name="ypad">0</property>
				</widget>
				<packing>
				  <property name="left_attach">2</property>
				  <property name="right_attach">3</property>
				  <property name="top_attach">0</property>
				  <property name="bottom_attach">1</property>
				  <property name="x_options">fill</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkLabel" id="label8">
				  <property name="visible">True</property>
				  <property name="label" translatable="yes">Length</property>
				  <property name="use_underline">False</property>
				  <property name="use_markup">False</property>
				  <property name="justify">GTK_JUSTIFY_LEFT</property>
				  <property name="wrap">False</property>
				  <property name="selectable">False</property>
				  <property name="xalign">0</property>
				  <property name="yalign">0.5</property>
				  <property name="xpad">0</property>
				  <property name="ypad">0</property>
				</widget>
				<packing>
				  <property name="left_attach">2</property>
				  <property name="right_attach">3</property>
				  <property name="top_attach">1</property>
				  <property name="bottom_attach">2</property>
				  <property name="x_options">fill</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkEntry" id="angle">
				  <property name="visible">True</property>
				  <property name="can_focus">True</property>
				  <property name="editable">True</property>
				  <property name="visibility">True</property>
				  <property name="max_length">0</property>
				  <property name="text" translatable="yes"></property>
				  <property name="has_frame">True</property>
				  <property name="invisible_char" translatable="yes">*</property>
				  <property name="activates_default">False</property>
				  <property name="width_chars">4</property>
				</widget>
				<packing>
				  <property name="left_attach">3</property>
				  <property name="right_attach">4</property>
				  <property name="top_attach">0</property>
				  <property name="bottom_attach">1</property>
				  <property name="y_options"></property>
				</packing>
			      </child>

			      <child>
				<widget class="GtkEntry" id="length">
				  <property name="visible">True</property>
				  <property name="can_focus">True</property>
				  <property name="editable">True</property>
				  <property name="visibility">True</property>
				  <property name="max_length">0</property>
				  <property name="text" translatable="yes"></property>
				  <property name="has_frame">True</property>
				  <property name="invisible_char" translatable="yes">*</property>
				  <property name="activates_default">False</property>
				  <property name="width_chars">4</property>
				</widget>
				<packing>
				  <property name="left_attach">3</property>
				  <property name="right_attach">4</property>
				  <property name="top_attach">1</property>
				  <property name="bottom_attach">2</property>
				  <property name="y_options"></property>
				</packing>
			      </child>
			    </widget>
			    <packing>
			      <property name="padding">0</property>
			      <property name="expand">True</property>
			      <property name="fill">True</property>
			    </packing>
			  </child>

			  <child>
			    <widget class="GtkHButtonBox" id="hbuttonbox1">
			      <property name="visible">True</property>
			      <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
			      <property name="spacing">0</property>

			      <child>
				<widget class="GtkButton" id="insert">
				  <property name="visible">True</property>
				  <property name="can_default">True</property>
				  <property name="can_focus">True</property>
				  <property name="label" translatable="yes">Insert</property>
				  <property name="use_underline">True</property>
				  <property name="relief">GTK_RELIEF_NORMAL</property>
				  <signal name="clicked" handler="on_insert_clicked" last_modification_time="Thu, 26 Feb 2004 03:55:38 GMT"/>
				</widget>
			      </child>

			      <child>
				<widget class="GtkButton" id="delete">
				  <property name="visible">True</property>
				  <property name="can_default">True</property>
				  <property name="can_focus">True</property>
				  <property name="label" translatable="yes">Delete</property>
				  <property name="use_underline">True</property>
				  <property name="relief">GTK_RELIEF_NORMAL</property>
				  <signal name="clicked" handler="on_delete_clicked" last_modification_time="Thu, 26 Feb 2004 03:55:44 GMT"/>
				</widget>
			      </child>
			    </widget>
			    <packing>
			      <property name="padding">0</property>
			      <property name="expand">False</property>
			      <property name="fill">False</property>
			      <property name="pack_type">GTK_PACK_END</property>
			    </packing>
			  </child>
			</widget>
		      </child>

		      <child>
			<widget class="GtkLabel" id="label10">
			  <property name="visible">True</property>
			  <property name="label" translatable="yes">Current point</property>
			  <property name="use_underline">False</property>
			  <property name="use_markup">False</property>
			  <property name="justify">GTK_JUSTIFY_LEFT</property>
			  <property name="wrap">False</property>
			  <property name="selectable">False</property>
			  <property name="xalign">0.5</property>
			  <property name="yalign">0.5</property>
			  <property name="xpad">0</property>
			  <property name="ypad">0</property>
			</widget>
			<packing>
			  <property name="type">label_item</property>
			</packing>
		      </child>
		    </widget>
		    <packing>
		      <property name="padding">2</property>
		      <property name="expand">True</property>
		      <property name="fill">True</property>
		    </packing>
		  </child>

		  <child>
		    <widget class="GtkVBox" id="vbox3">
		      <property name="visible">True</property>
		      <property name="homogeneous">False</property>
		      <property name="spacing">0</property>

		      <child>
			<widget class="GtkCheckButton" id="invert">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">Flip motif</property>
			  <property name="use_underline">True</property>
			  <property name="relief">GTK_RELIEF_NORMAL</property>
			  <property name="active">False</property>
			  <property name="inconsistent">False</property>
			  <property name="draw_indicator">True</property>
			</widget>
			<packing>
			  <property name="padding">0</property>
			  <property name="expand">False</property>
			  <property name="fill">False</property>
			</packing>
		      </child>

		      <child>
			<widget class="GtkCheckButton" id="auto">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">Auto preview</property>
			  <property name="use_underline">True</property>
			  <property name="relief">GTK_RELIEF_NORMAL</property>
			  <property name="active">False</property>
			  <property name="inconsistent">False</property>
			  <property name="draw_indicator">True</property>
			</widget>
			<packing>
			  <property name="padding">0</property>
			  <property name="expand">False</property>
			  <property name="fill">False</property>
			</packing>
		      </child>

		      <child>
			<widget class="GtkCheckButton" id="autoiter">
			  <property name="visible">True</property>
			  <property name="can_focus">True</property>
			  <property name="label" translatable="yes">Auto iterations</property>
			  <property name="use_underline">True</property>
			  <property name="relief">GTK_RELIEF_NORMAL</property>
			  <property name="active">False</property>
			  <property name="inconsistent">False</property>
			  <property name="draw_indicator">True</property>
			  <signal name="toggled" handler="on_autoiter_toggled" last_modification_time="Sun, 29 Feb 2004 02:36:08 GMT"/>
			</widget>
			<packing>
			  <property name="padding">0</property>
			  <property name="expand">False</property>
			  <property name="fill">False</property>
			</packing>
		      </child>

		      <child>
			<widget class="GtkHBox" id="hbox3">
			  <property name="visible">True</property>
			  <property name="homogeneous">False</property>
			  <property name="spacing">0</property>

			  <child>
			    <widget class="GtkLabel" id="label9">
			      <property name="visible">True</property>
			      <property name="label" translatable="yes">Iterations</property>
			      <property name="use_underline">False</property>
			      <property name="use_markup">False</property>
			      <property name="justify">GTK_JUSTIFY_LEFT</property>
			      <property name="wrap">False</property>
			      <property name="selectable">False</property>
			      <property name="xalign">0.5</property>
			      <property name="yalign">0.5</property>
			      <property name="xpad">0</property>
			      <property name="ypad">0</property>
			    </widget>
			    <packing>
			      <property name="padding">0</property>
			      <property name="expand">False</property>
			      <property name="fill">False</property>
			    </packing>
			  </child>

			  <child>
			    <widget class="GtkSpinButton" id="iterations">
			      <property name="visible">True</property>
			      <property name="can_focus">True</property>
			      <property name="climb_rate">1</property>
			      <property name="digits">0</property>
			      <property name="numeric">False</property>
			      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
			      <property name="snap_to_ticks">False</property>
			      <property name="wrap">False</property>
			      <property name="adjustment">6 0 1000 1 10 10</property>
			      <signal name="changed" handler="on_iterations_changed" last_modification_time="Thu, 26 Feb 2004 01:38:01 GMT"/>
			    </widget>
			    <packing>
			      <property name="padding">0</property>
			      <property name="expand">False</property>
			      <property name="fill">False</property>
			    </packing>
			  </child>
			</widget>
			<packing>
			  <property name="padding">0</property>
			  <property name="expand">True</property>
			  <property name="fill">True</property>
			</packing>
		      </child>
		    </widget>
		    <packing>
		      <property name="padding">0</property>
		      <property name="expand">True</property>
		      <property name="fill">True</property>
		    </packing>
		  </child>
		</widget>
		<packing>
		  <property name="padding">0</property>
		  <property name="expand">False</property>
		  <property name="fill">False</property>
		</packing>
	      </child>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkLabel" id="motif-label">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">Motif</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">False</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="type">label_item</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">2</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>

      <child>
	<widget class="GtkStatusbar" id="statusbar">
	  <property name="visible">True</property>
	  <property name="has_resize_grip">True</property>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">False</property>
	</packing>
      </child>
    </widget>
  </child>
</widget>

<widget class="GtkFileSelection" id="fileselection">
  <property name="border_width">10</property>
  <property name="title" translatable="yes">Select File</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="show_fileops">False</property>
  <signal name="response" handler="on_fileselection_response" last_modification_time="Mon, 01 Mar 2004 02:50:30 GMT"/>

  <child internal-child="cancel_button">
    <widget class="GtkButton" id="cancel_button2">
      <property name="visible">True</property>
      <property name="can_default">True</property>
      <property name="can_focus">True</property>
      <property name="relief">GTK_RELIEF_NORMAL</property>
    </widget>
  </child>

  <child internal-child="ok_button">
    <widget class="GtkButton" id="ok_button2">
      <property name="visible">True</property>
      <property name="can_default">True</property>
      <property name="can_focus">True</property>
      <property name="relief">GTK_RELIEF_NORMAL</property>
    </widget>
  </child>
</widget>

<widget class="GtkDialog" id="about">
  <property name="title" translatable="yes">About</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="has_separator">True</property>
  <signal name="response" handler="on_about_response" last_modification_time="Mon, 01 Mar 2004 18:48:45 GMT"/>

  <child internal-child="vbox">
    <widget class="GtkVBox" id="dialog-vbox1">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child internal-child="action_area">
	<widget class="GtkHButtonBox" id="dialog-action_area1">
	  <property name="visible">True</property>
	  <property name="layout_style">GTK_BUTTONBOX_END</property>

	  <child>
	    <widget class="GtkButton" id="closebutton1">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="has_focus">True</property>
	      <property name="label">gtk-close</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-7</property>
	    </widget>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">True</property>
	  <property name="pack_type">GTK_PACK_END</property>
	</packing>
      </child>

      <child>
	<widget class="GtkVBox" id="vbox5">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">0</property>

	  <child>
	    <widget class="GtkDrawingArea" id="drawingarea2">
	      <property name="visible">True</property>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkHBox" id="hbox4">
	      <property name="visible">True</property>
	      <property name="homogeneous">False</property>
	      <property name="spacing">0</property>

	      <child>
		<widget class="GtkDrawingArea" id="aboutlogo">
		  <property name="width_request">200</property>
		  <property name="height_request">80</property>
		  <property name="visible">True</property>
		  <signal name="expose_event" handler="on_aboutlogo_expose_event" last_modification_time="Mon, 01 Mar 2004 18:02:37 GMT"/>
		</widget>
		<packing>
		  <property name="padding">0</property>
		  <property name="expand">True</property>
		  <property name="fill">False</property>
		</packing>
	      </child>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkLabel" id="">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">&lt;span size=&quot;xx-large&quot;&gt;&lt;b&gt;Meander&lt;/b&gt;&lt;/span&gt;</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">True</property>
	      <property name="justify">GTK_JUSTIFY_CENTER</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="padding">5</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkLabel" id="label12">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">An interactive fractal plotter.

By Tom Hargreaves &lt;i&gt;&amp;lt;hex@freezone.co.uk&amp;gt;&lt;/i&gt;.</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">True</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GnomeHRef" id="href1">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="url">http://sphere.chronosempire.org.uk/~HEx/meander/</property>
	      <property name="label" translatable="yes">http://sphere.chronosempire.org.uk/~HEx/meander/</property>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>

EOF

$glade->signal_autoconnect_from_package("main");


my @points;
my @angles;

my ($dispwin,$iterations,$editwin, $dispcanvas, $editcanvas,
    $drawingarea, $xtext, $ytext, $angtext, $lentext, $sidesmenu,
    $statusbar, $presets, $filesel, $about)=

    map $glade->get_widget($_), qw[dispwin iterations editwin
				   dispcanvas editcanvas
				   drawingarea x y angle length
				   sides statusbar presets
				   fileselection about
				   ];

my @presets;
my $presetmenu=Gtk2::Menu->new();

$presets->set_submenu($presetmenu);

{
    local $/="\n\n";
    while (<DATA>) {
	push @presets, $_;
	/^# (.*)/ or die $_;
	my $n=$_;
	my $item=Gtk2::MenuItem->new_with_label($1);
	$item->show;
	$presetmenu->add($item);
	$item->signal_connect('activate', sub { load ($n) });
    }
}
				 

my $displine;
my $editline;
my $dragging=0;
my $panning=0;
my @panoffset;
my $ignoreentry=0;

my $iter;
my $base;
my $autoiter;

my @editpoints;
my $selected_point;

my $xorigin=300;
my $yorigin=250;
my $xscale=100;
my $yscale=100;

my $statuscontext=$statusbar->get_context_id('foo');

$drawingarea->add_events(qw[button-press-mask]);

init_points();

update_display();
draw_motif_editor();

Gtk2->main;

sub points_to_angles {
    my @points=@_;
    my @angles;
    my ($x,$y)=@{shift @points};
    my $ang=0;
    for my $point (@points) {
	my ($xx,$yy)=@{$point};
#	if ($xx eq '' || $yy eq '') {
#	    print STDERR Dumper [@_] ;
#	    exit;
#	}
				    
	my ($dx,$dy)=($yy-$y, $xx-$x);
	$ang=atan2($dx,$dy)-$ang;
	push @angles, [$ang, sqrt($dx*$dx+$dy*$dy)];
	($x,$y)=($xx,$yy);
    }
    return @angles;
}

sub normalize {
    my @angles=@_;
    my ($x,$y)=(0,0);
    my $ang=0;

    for my $a (@angles) {
	my ($angle,$dist)=@{$a};
	$ang+=$angle;
	$x+=$dist*cos($ang);
	$y+=$dist*sin($ang);
    }

    return (sqrt($x*$x+$y*$y),atan2($y,$x));
}

sub angles_to_points {
    my ($scale,$theta,@angles)=@_;
    my @points=([0,0]);

    my ($x,$y)=(0,0);
    my $ang=-$theta;
    
    for my $a (@angles) {
	my ($angle,$dist)=@{$a};
	$ang+=$angle;
	$x+=$dist/$scale*cos($ang);
	$y+=$dist/$scale*sin($ang);
	push @points,[$x,$y];
    }
    return @points;
}

sub gtk_main_quit
{
    Gtk2->main_quit;
}

sub on_iterations_changed {
    my $i=$iterations->get_text;
    if ($i=~/^\d+$/) {
	$iter=$i;
	update_display();
    }
}

sub update_display {
	$drawingarea->window->invalidate_rect($drawingarea->allocation,1);
}
    

sub draw_motif_editor {
    $editline=Gnome2::Canvas::Item->new($editcanvas->root, "Gnome2::Canvas::Line")
	unless $editline;
    $editline->set(
		   points => [map {$_->[0],-$_->[1]} @points],
		   );

    my $size=0.03;
    for my $i (0..$#points) {
	unless ($editpoints[$i]) {
	    $editpoints[$i]=Gnome2::Canvas::Item->new($editcanvas->root,
						      "Gnome2::Canvas::Rect");
	    $editpoints[$i]->signal_connect (event => \&on_select_point, $i)

	}
	    
	$editpoints[$i]->set(
			     x1 => $_->[0]-$size,
			     y1 => -$_->[1]-$size,
			     x2 => $_->[0]+$size,
			     y2 => -$_->[1]+$size,
			     fill_color => 'black',
			     ) for $points[$i];
    }
    for my $i (@points..$#editpoints) {
	next unless $editpoints[$i];
	$editpoints[$i]->destroy;
	undef $editpoints[$i];
    }

    do_select($selected_point);
}

sub on_select_point {
    my ($item, $event, $num)=@_;
#    return 0 unless ref($event) eq 'Gtk2::Gdk::Event::Button';
    if ($event->type eq 'button-press') {
	do_select($num);
	if ($selected_point && $selected_point<$#points) {
	    $item->grab ([qw[pointer-motion-mask button-release-mask]],
		       Gtk2::Gdk::Cursor->new('fleur'), 0);
	    $dragging=1;
	}
    } elsif ($event->type eq 'button-release') {
	$dragging=0;
	$item->ungrab();
    } elsif ($event->type eq 'motion-notify') {
	if ($dragging) {
	    die unless defined $selected_point;
	    $points[$selected_point]=[$event->x,-$event->y];
	    update_angles();
	    points_changed();
	}
    } else {
#	print Dumper @_;
    }
#if ($event->type eq '') {
}

sub do_select {
    $ignoreentry=1;
#    print Dumper $selected_point,@_;
    if (defined $selected_point) {
	$editpoints[$selected_point]->set(
					  fill_color => 'black',
					  );
    }
    my $i=$selected_point=shift;
    if (defined $i) {
	$editpoints[$i]->set(
					  fill_color => 'red',
					  );

	$_->[0]->set_text($_->[1])
	    for ([$xtext=>$points[$i][0]],
		 [$ytext=>$points[$i][1]],
		  );

	if ($i<$#points) {
	    $angtext->set_text($angles[$i][0]*180/pi);
	    $lentext->set_text($angles[$i][1]);
	}
    }

    {
	my $e=$i && $i<$#points;
	for ($xtext,$ytext) {
	    $_->set_editable($e);
	}
    }

    {
	my $e=defined $i && $i<$#points;
	for ($angtext,$lentext) {
	    $_->set_editable($e);
	    $_->set_text('') unless $e;
	}
    }
    $ignoreentry=0;
}

sub on_show_display_window_activate {
    $dispwin->show;
}

sub points_changed {
    draw_motif_editor();
    update_display();
}    

sub update_angles {
    @angles=points_to_angles(@points);
}

sub update_points {
    @points=angles_to_points(@angles);
}

sub on_xy_changed {
    return FALSE unless defined $selected_point;
    return FALSE if $ignoreentry;
    my ($obj)=@_;
    die unless $obj eq $xtext || $obj eq $ytext;
    my $coord=$obj->get_text;
    if ($coord=~/^[-+]?\d*.?\d+$/) {
	$points[$selected_point][($obj eq $xtext)?0:1]=$obj->get_text;
	update_angles();
	points_changed();
    }
    return FALSE;
}

sub on_insert_clicked {
    if (defined $selected_point) {
	my $i=$selected_point;
	$i-- if ($i==$#points);
	my ($x,$y);
	$x=($points[$i][0]+$points[$i+1][0])/2;
	$y=($points[$i][1]+$points[$i+1][1])/2;
	splice @points, $i+1, 0, [$x,$y];
	update_angles();
	do_select($i+1);
	points_changed();
    }
    return FALSE;
}

sub on_delete_clicked {
    if (defined $selected_point) {
	my $i=$selected_point;
	if ($i && $i<$#points) {
	    splice @points, $i, 1;
	    update_angles();
	    do_select(undef);
	    points_changed();
	}
	$selected_point=undef;
    }
    return FALSE;
}

sub init_points {
    @points=([0,0],[1,0]);
    $base=1;
    $iter=4;
    update_angles();
    update_params();
    do_select(undef);
    points_changed();
}

sub load {
    my $f=shift;
    init_points();
    for (split /\n/, $f) {
	next if /^#/;
	chomp;
	$iter=$1, next if /^iterations\s+(\d+)/;
	$base=$1, next if /^baseline\s+(\d+)/;
	if (s/^points\s+//) {
	    @points=([0,0]);
	    while (s/^\s*\(([-+]?\d*.?\d+)\s+([-+]?\d*.?\d+\s*)\)//) {
		push @points,[$1,$2];
	    }
	    push @points,[1,0];
	    next if /^\s*$/;
	}
	die "Syntax error: $_";
    }
    update_angles();
    update_params();
    do_select(undef);
    points_changed();
}

sub save {
    print <<"EOF";
# Generated by $appname $version
points @{[map { sprintf "(%f %f)", @$_ } @points[1..$#points-1]]}
baseline $base
iterations $iter
EOF
}
sub on_open1_activate {
    $filesel->show;
}

sub on_fileselection_response {
    my ($obj,$event)=@_;
}

sub update_params {
    $iterations->set_text($iter);
    $sidesmenu->set_text($base);
}

sub on_new1_activate {
    init_points();
}

sub on_save1_activate {
    save();
}

sub on_sides_changed {
    my $s=$sidesmenu->get_text;
    if ($s=~/^(\d+)/) {
	$base=$1;
	update_display();
    }
}    

sub on_autoiter_toggled {
    my ($obj)=@_;
    $autoiter=$obj->get_active;
    $iterations->set_sensitive(!$autoiter);
    update_display();
}

sub on_drawingarea_click {
    my ($obj,$event)=@_;

    my $size=$drawingarea->allocation;
    if ($event->button==1) {
	$xscale*=4/3;
	$yscale*=4/3;
	$xorigin=($xorigin*3-$event->x)/4;
	$yorigin=($yorigin*3-$event->y)/4;
	update_display();
    } elsif ($event->button==3) {
	$xscale*=3/4;
	$yscale*=3/4;
	$xorigin=($xorigin*3+$event->x)/4;
	$yorigin=($yorigin*3+$event->y)/4;
	update_display();
    } elsif ($event->button==2) {
	$xorigin-=($event->x-$size->width/2);
	$yorigin-=($event->y-$size->height/2);
	update_display();
    }
}

sub on_about1_activate {
    $about->show;
}

sub on_about_response {
    shift->hide;
}

sub on_aboutlogo_expose_event {
    my ($obj, $event)=@_;
    draw_meander ([.4, .2, .2, -.4, .4, .2],
			      $obj,
			      25, 40,
			      150, 0,
			      20, 0);
}

sub on_expose_event {
    my ($obj, $event)=@_;
    
    my $maxiter=$iter;
    if ($autoiter) {
	$maxiter=log(1e8)/log($#points) if @points>2;
    }

# check convergence
#    for (@angles) {
#	return FALSE if ($_->[1]>=0.95);
#    }

    my ($x,$y)=(1,0);
    ($x,$y)=(-1,0) if $base==1; #ewwww

    my $count=0;

    for my $i (1..$base) {
	my $xx=cos(2*pi*$i/$base);
	my $yy=sin(2*pi*$i/$base);
	my $dx=$xx-$x;
	my $dy=$yy-$y;

	my @a=(0,0);
	$count+=draw_meander ([map {
	    my @b=($_->[0]-$a[0], $_->[1]-$a[1]); @a=@$_; @b;
	    } @points[1..$#points]],
			      $obj,
			      $xorigin+$x*$xscale, $yorigin+$y*$yscale,
			      $dx*$xscale, $dy*$yscale,
			      $maxiter, !$autoiter);
	($x,$y)=($xx,$yy);
    }

    $statusbar->pop($statuscontext);
    $statusbar->push($statuscontext, "$count points");

    return FALSE;
}

__DATA__
# Lévy curve
points (0.5 0.5)
baseline 1
iterations 15

# Lévy square
points (0.5 0.5)
baseline 2
iterations 15

# Lévy square with warts
points (0 0.5) (0.5 0.5) (0.5 0.3333333) (0.5 0.5) (1 0.5)
baseline 2
iterations 6

# Koch snowflake
points (0.333333333 0) (0.5 0.28867513) (0.66666667 0)
baseline 3
iterations 6

# Koch anti-snowflake
points (0.333333333 0) (0.5 -0.28867513) (0.66666667 0)
baseline 3
iterations 6

# Minkowski sausage
points (0.25 0) (0.25 0.25) (0.5 0.25) (0.5 0) (0.5 -0.25) (0.75 -0.25) (0.75 0)
baseline 4
iterations 4

# Island
points (0.4 0.2) (0.6 -0.2)
baseline 4
iterations 5

# Logarithmic spiral
points (0.04 0.15333333)
baseline 1
iterations 200

# Clouds
points (0.19333333 -0.19333333) (0.5 -0.06) (1.18 0.16666667)
baseline 2
iterations 8

# Exotic
points (0.28 -0.11333333) (0.5 0.4) (0.72 -0.11333333)
baseline 3
iterations 7

# Square pattern
points (0 0.5) (0.5 0.5) (0.5 0.0)
baseline 4
iterations 6

# Square pattern 2
points (0 0.5) (0.5 0.5) (0.5 0.0) (0.57333333 -0.26)
#(0.5 -0.24)
baseline 4
iterations 6

# Bushy square (dendrite)
points (0.25 0.25) (0.65849365 0.09150635) (0.75 -0.25)
baseline 4
iterations 5

# Triangular dragon
points (0.5 -0.28867513) (0.5 0.28867513)
baseline 1
iterations 8

# Spiky sea-horse
points (0.30666667 0.2) (0.5 -0) (1.29333333 -0.16666667)
baseline 2
iterations 12

# Blotchy
points (0.50666667 0.38) (0.55333333 -0.27333333)
baseline 1
iterations 10

# Curved square
points (0.5 0.05) (0.5 -0.42) (0.5 0.05)
baseline 4
iterations 8

# Torn square 
points (0.47 0) (0.5 -0.47) (0.53 0)
baseline 4
iterations 8

# Ice square
points (0.5 0) (0.5 -0.33333333) (0.5 0)
baseline 4
iterations 8

# Ice triangle
points (0.5 0) (0.375 -0.21650635) (0.5 0) (0.625 -0.21650635) (0.5 0)
baseline 3
iterations 6

# Alien brains
points (0.47333333 0.32) (1.01333333 0.00666667) (0.55333333 -0.14)
baseline 1
iterations 9

# Loopy
points (0.52 -0.23333333) (0.5 -0.45) (0.48 -0.23333333)
baseline 5
iterations 8

# Whirl
points (0.3 0.2) (0.5 0) (0.22 0.22)
baseline 3
iterations 12

# Starry
points (0.393333 0.36) (0.58 -0.353333)
baseline 1
iterations 10

# Swirly
points (0.25 0) (0.25 0.25) (0.75 -0.25) (0.75 0)
baseline 5
iterations 8

# Sphinx
points (0.25 0.433013) (0.5 0.866025) (0.75 0.433013)
baseline 3
iterations 8

