#!/usr/bin/perl -w # A spherical image slicer for patterning spheres # Copyright 2001 Bruno Postle # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use Image::Magick; # image stuff use Math::Trig; # math stuff use Math::Trig ':radial'; # more math stuff if ( $#ARGV ne 2 ) { die "Incorrect number of arguments\nUsage $0 \ne.g. $0 16 1000 input.jpg\n"; } my $n = $ARGV[0]; # number of panels my $out_size = $ARGV[1]; # output circumference my $out_filetype = "png"; # can be changed to tif, gif, jpg or whatever.. my $out_height = int ( $out_size / 2 ); my $out_width = int ( ( $out_size / pi ) * tan( pi / $n ) ); my $rho = $out_height / pi; # output radius $in = Image::Magick->new(); # get input image $in->ReadImage( "$ARGV[2]" ); $in_width = $in->Get( 'width' ); $in_height = $in->Get( 'height' ); print "Input image is $in_width x $in_height.\n"; for ( $panel = 0; $panel < $n; $panel += 1 ) { # do each panel $theta_offset = ( pi / $n ) * ( $panel + .5 ) * 2; $out = Image::Magick->new(); # setup output image $out->Set( size=>"$out_width"."x"."$out_height" ); $out->ReadImage( 'NULL:white' ); # background colour for ( $u = 0; $u < $out_width; $u += 1 ) { # do each column for ( $v = 0; $v < $out_height; $v += 1 ) { # do each row my $y = $u - ( $out_width / 2 ); my $phi = ( ( $v / $out_height ) * pi ); # phi is inclination my ( $x, $junk, $z ) = spherical_to_cartesian( $rho, 0, $phi ); if ( ( $x > 0 ) && ( atan($y/$x) < (pi/$n) ) && ( 0 - atan($y/$x) < (pi/$n) ) ) { $colour = getcolour( $x,$y,$z ); $out->Set( "pixel[$u,$v]"=>$colour ); } } } print "Writing panel$panel.$out_filetype $out_width x $out_height..\n"; $out->Write( "panel$panel.$out_filetype" ); } sub getcolour { my ($rho, $theta, $phi) = cartesian_to_spherical( $_[0], $_[1], $_[2] ); $theta += $theta_offset; my $u = int ( ( $theta / ( 2 * pi ) ) * $in_width ); my $v = int ( $in_height - ( ( $phi / pi ) * $in_height ) ); my $colour = $in->Get( "pixel[$u,$v]" ); return $colour; }