############################################################################
#
# Sample code for use of Polyline.pm
#
# Author:	Dan Harasty
# Email:	harasty@cpan.org
# Version:	0.1
# Date:		7/20/2002
#
#

use GD;
use GD::Polyline;

$PI = 3.14159; $TWO_PI = 2 * $PI;
sub r2d {$_[0] * 180 / $PI};

$splinekey = "<UL><LI>Green: original polygon or polyline<LI>Blue: control points added with addControlPoints()<LI>Black: spline generated by toSpline()</UL>";

if (1) {

	use GD;
	use GD::Polyline;

	# create an image
	$image = new GD::Image (500,300);
	$white  = $image->colorAllocate(255,255,255);
	$black  = $image->colorAllocate(  0,  0,  0);
	$red    = $image->colorAllocate(255,  0,  0);

	# create a new polyline
	$polyline = new GD::Polyline;

	# add some points
	$polyline->addPt(  0,  0);
	$polyline->addPt(  0,100);
	$polyline->addPt( 50,125);
	$polyline->addPt(100,  0);

	# polylines can use polygon methods (and vice versa)
	$polyline->offset(200,100);

	# rotate 60 degrees, about the centroid
	$polyline->rotate(3.14159/3, $polyline->centroid());

	# scale about the centroid
	$polyline->scale(1.5, 2, $polyline->centroid());

	# draw the polyline
	$image->polydraw($polyline,$black);

	# create a spline, which is also a polyine
	$spline = $polyline->addControlPoints->toSpline;
	$image->polydraw($spline,$red);

	# output the png
	#binmode STDOUT;
	#print $image->png;

	SampleImage($image, "polyline-synopsis.png", "Synopsis", "Polyline created by 'SYNOPSIS' section of documentation.");

}

if (1) {
	$image = NewImage();

	$offset = 50;


	for $poly (new GD::Polygon, new GD::Polyline) {

		$table_info = [];

		$poly->addPt(  0,  0);
		$poly->addPt(  0,100);
		$poly->addPt( 50,125);
		$poly->addPt(100,  0);

		#print "this " . ref($poly) . " has " . $poly->length() . " points\n";

		push @$table_info, ["<B>".ref($poly)."</B>"];
		push @$table_info, ['vertex number: ', 0..($poly->length()-1)];

		@coords = $poly->vertices();
		@coords = map {"[".int($_->[0]).",".int($_->[1])."]"} @coords;
		push @$table_info, ['coordinates (pre-offset): ', @coords];

		@lengths = $poly->segLength();
		@lengths = map {int($_+0.5)} @lengths;
		#print "segLengths are   : @lengths\n";
		#print "perimeter is     : " . int($poly->segLength()) . "\n";
		push @$table_info, ['segment lengths: ', @lengths];

		@angles = $poly->segAngle();
		@angles = map {int(r2d($_)+0.5)} @angles;
		#print "seg angles are   : @angles\n";
		push @$table_info, ['segment angles: ', @angles];

		@angles = $poly->vertexAngle();
		@angles = map {defined ($_) ? int(r2d($_)+0.5) : "undef"} @angles;
		#print "vertex angles are: @angles\n";
		push @$table_info, ['vertex angles: ', @angles];

		$poly->offset(50 + $offset,80);
		$offset += 200;

		# draw the original poly
		$image->polydraw($poly,$black);

		#print "\n\n";

		push @$summary_table, genHTMLTable($table_info, 0);
	}

	SampleImage($image, "polyline-simple.png", "Simple", "GD::Polygon and GD::Polyline with same vertexes.</P>" . genHTMLTable([$summary_table], 1));

}

if (1) {
	$image = NewImage();

	$offset = 50;

	for $poly (new GD::Polygon, new GD::Polyline) {

		$poly->addPt(  0,  0);
		$poly->addPt(  0,100);
		$poly->addPt( 50,125);
		$poly->addPt(100,  0);

		$poly->offset(50 + $offset,80);
		$offset += 200;

		# draw the original poly
		$image->polydraw($poly,$green);

		# create and draw the control line for the spline
		$ctrlline = $poly->addControlPoints();
		$image->polydraw($ctrlline,$cyan);

		# create and draw the spline itself
		$spline = $ctrlline->toSpline();
		$image->polydraw($spline,$black);

	}

	SampleImage($image, "polyline-spline.png", "Spline", "Splines fit to vertices of polygon and polyline.  $splinekey");

}


if (1) {
	$image = NewImage();

	$triangle = new GD::Polygon;

	$triangle->addPt(  0,  0);
	$triangle->addPt(-19, 95);
	$triangle->addPt( 19, 95);

	$triangle->offset(250,50);

	foreach (1..9) {
		$image->polydraw($triangle,gdBrushed);
		$triangle->rotate($TWO_PI / 9, 250, 150);
	}

	SampleImage($image, "polyline-star9.png", "Nine Pointed Star", "A triangle, rotated about a point other than the origin.<BR>Demonstration of \$poly->rotate() and \$poly->offset()");

}

if (1) {
	$image = NewImage();

	$cloverControl = new GD::Polyline;
	$cloverControl->addPt(45,45);
	$cloverControl->addPt(10,10);
	$cloverControl->addPt(90,10);
	$cloverControl->addPt(55,45);
	$cloverControl->addPt(90,10);
	$cloverControl->addPt(90,90);
	$cloverControl->addPt(55,55);
	$cloverControl->addPt(90,90);
	$cloverControl->addPt(10,90);
	$cloverControl->addPt(45,55);
	$cloverControl->addPt(10,90);
	$cloverControl->addPt(10,10);
	$cloverControl->addPt(45,45);

	$clover = $cloverControl->toSpline();

	# note that the three following transformations
	# could have been called on $cloverControl, instead,
	# followed by the above call

	$clover->offset($clover->centroid(-1));
	$clover->scale(3, 3);
	$clover->offset(250, 150);

	$image->filledPolygon($clover,$green);

	SampleImage($image, "polyline-clover.png", "Clover", "Sample image generated by GD::Polygon");

}

if (1) {
	$image = NewImage();

	$polyline = new GD::Polyline;

	for (0..15) {
		$polyline->addPt(30 * $_ + 10, rand(90) + 5);
	}

	$image->polyline($polyline,$green);

	$ctrlline = $polyline->addControlPoints();
	$ctrlline->offset(0,100);
	$image->polyline($ctrlline,$cyan);

	$spline = $ctrlline->toSpline();
	$spline->offset(0,100);
	$image->polyline($spline,$black);

	SampleImage($image, "polyline-zigzag.png", "Zigzag", "Spline fit to random function.  $splinekey");

}

if (1) {
	$image = NewImage();

	$ring_network = new GD::Polygon;

	$num_nodes = 10;
	$randfactor = 80;

	for (1..$num_nodes) {
		$x = 250 + 150 * cos($TWO_PI * $_/$num_nodes);
		$y = 150 + 100 * sin($TWO_PI * $_/$num_nodes);
		$x += rand($randfactor)-$randfactor/2;
		$y += rand($randfactor)-$randfactor/2;
		$ring_network->addPt($x, $y);
	}

	$image->setBrush($brush2);
	$image->polyline($ring_network->addControlPoints->toSpline,gdBrushed);

	$ring_node = new GD::Polygon;

	$ring_node->addPt( 0, 0);
	$ring_node->addPt(10, 0);
	$ring_node->addPt(10,10);
	$ring_node->addPt( 0,10);

	for $ring_vertex ($ring_network->vertices()) {
		$ring_node->offset($ring_node->centroid(-1));
		$ring_node->offset(@$ring_vertex);
		$image->filledPolygon($ring_node,$grey);
	}

	SampleImage($image, "polyline-ring-network.png", "Ring Network", "Closed spline fit to nodes at somewhat random positions.");

}

WriteToFile("polyline-example.html", theHTML());

print "\n";
print "open 'polyline-example.html' in your favorite browser that supports PNG.\n";
print "\n";

print "done! " . localtime() . "\n";

##########################
#
# helper functions
#

sub NewImage {
	$image = new GD::Image (500,300);

	$white  = $image->colorAllocate(255,255,255);
	$black  = $image->colorAllocate(  0,  0,  0);
	$grey   = $image->colorAllocate(128,128,128);
	$red    = $image->colorAllocate(255,  0,  0);
	$orange = $image->colorAllocate(255,196,  0);
	$green  = $image->colorAllocate(  0,255,  0);
	$blue   = $image->colorAllocate(  0,  0,255);
	$cyan   = $image->colorAllocate(  0,255,255);
	$purple = $image->colorAllocate(206,  0,165);

	$brush_width = 2;
	$brush_color = [255,128,0];
		$brush = new GD::Image($brush_width,$brush_width);
		$brush->transparent($brush->colorAllocate(255,255,255));
		$brush->filledRectangle(0,0,$brush_width,$brush_width,$brush->colorAllocate(@$brush_color));
	$brush1 = $brush;

	$brush_width = 3;
	$brush_color = [206,0,165];
		$brush = new GD::Image($brush_width,$brush_width);
		$brush->transparent($brush->colorAllocate(255,255,255));
		$brush->filledRectangle(0,0,$brush_width,$brush_width,$brush->colorAllocate(@$brush_color));
	$brush2 = $brush;

	$image->setBrush($brush1);

	$image;
}

my $html;

sub SampleImage {
	my $image = shift;
	my $file  = shift;
	my $title = shift;
	my $text  = shift;

	WriteToBinaryFile($file, $image->png());

	$html .= "<IMG SRC='$file'><BR>\n";
	$html .= "<B>$title</B> - $file<BR>\n";
	$html .= "<P>$text</P><HR>\n";

}

sub theHTML {
	$html;
}

sub WriteToFile {
	my $file = shift || return 0;
	my $contents = shift || "";

	open (NEWFILE, ">" . $file) or die "couldn't write to file $file";
	print NEWFILE $contents;
	close(NEWFILE);

	print "created file $file\n";
}

sub WriteToBinaryFile {
	my $file = shift || return 0;
	my $contents = shift || "";

	open (NEWFILE, ">" . $file) or die "couldn't write to file $file";
	binmode NEWFILE;
	print NEWFILE $contents;
	close(NEWFILE);

	print "created file $file\n";
}

sub genHTMLTable {
	my $array_of_arrays = shift;
	my $border = shift;
	my $html_table;

	$html_table .= "<TABLE BORDER='$border'>";
	for my $array_of_items (@$array_of_arrays) {
		$html_table .= "<TR><TD>";
		$html_table .= join("</TD><TD>", @$array_of_items);
		$html_table .= "</TD></TR>";
	}
	$html_table .= "</TABLE>";
	$html_table;
}

