#!/usr/local/bin/perl -w # # tartan disc drawer, this one makes filled intersections # # to make all at once, # tartan2.p c=1 all=3 ; xv figs/tartan1.pbm & # # see also images/tartan.README # # to make them one by one, $fiduc = 0 ; # whether to put a ruddy big x in the middle $filled = 0 ; # whether to fill in the intersections. $circle = 1 ; # whether to exclude points outside circle $circle2 = 1 ; # whether to exclude points inside circle2 $repeat = 3 ; # number of times to periodic $pbmplot = 1 ; $pbmfile = "tartan" ; $pbmx = 286 ; # for width=6, 4 more than mult of 6 $pbmx = 202 ; # for width=8, mult of 8 plus 2 $pbmx = 276 ; # for width=12, $c = 1 ; # colour (1,2,3) or 1 for all $all = 3 ; # set to zero to force only one colour $ascii = 1 ; # whether also to write an ascii summary to stdout. $low = 0 ; $high = 1 - $low; $xoff = 0.35 ; # offset of centre of circle $yoff = 0.42 ; $ex = 0.41 ; $ey = 0.56 ; # fraction of the whole repeated picture $efx = 0.1 ; # ellipticity (stretch by sqrt 1/this) along x dirn $re = 0.05 ; # radius in the y direction $elip = 0.0 ; # ellipticity in 45 degree sense $radius = 0.31 ; # was .3 $shelf = 0.1 ; # how far before the dots die out $eshelf = 0.3 ; $xmax = 580 ; # clip size $ymax = 670 ; # clip size $maxpbm = 3 ; $verbose = 0 ; # eval "\$$1=\$2" while @ARGV && $ARGV[0]=~ /^(\w+)=(.*)/ && shift; # $period = $pbmx ; $pbmx = $repeat * $pbmx ; $pbmy = $pbmx ; $pbmfile .= $c.".pbm" ; $P = $pbmx * $pbmy ; $centrex = $pbmx * $xoff ; $centrey = $pbmy * $yoff ; print "centre is at $centrex, $centrey\n" ; $radius *= $pbmx ; $trueradius = $radius ; $radius *= $radius ; # radius squared $re *= $pbmx ; $re *= $re ; $ex = $pbmx * $ex ; $ey = $pbmy * $ey ; print "ellipse at $ex $ey\n" ; $pbmx = $xmax ; $pbmy = $ymax ; if ( $ascii ) { print "$pbmx $pbmy\n" ; } if ( $pbmplot ) { # note I actually write a pgm file . open (PBM,"> $pbmfile"); if ( $all > 1 ) { print PBM "P2\n# CREATOR: tartan.p DJCM 99 05\n" ; print PBM "$pbmx $pbmy\n" ; print PBM "$maxpbm\n" ; $low = 3 ; $high = 0 ; } else { print PBM "P1\n# CREATOR: tartan.p DJCM 99 05\n" ; print PBM "$pbmx $pbmy\n" ; } } for ( $i = 1 ; $i <= $P ; $i ++ ) { $c[$i] = $low ; } do { $stripe3start = 0 ; $stripe4start = 0 ; $stripe5start = 0 ; $stripe3end = 0 ; $stripe4end = 0 ; $stripe5end = 0 ; if ( $c == 2 ) { $stripe1start = 89 ; $stripe1width = 39 ; # $stripe2start = 139 ; $stripe2width = $stripe1width ; $lwidth = 12 ; $onwidth = 4 ; $o0 = 0 ; $oh = 7 ; } elsif ( $c == 1 ) { $stripe3width = 7 ; $stripe3start = 268 ; $stripe1start = 42 ; $stripe1width = 39 ; $stripe2start = 186 ; $stripe2width = $stripe1width ; # 14 $lwidth = 12 ; # period (was 6 and 2) (or 8 and 3) $onwidth = 4 ; # amount of ink $o0 = 0 ; $oh = 7 ; $stripe3end = $stripe3start + $stripe3width ; } elsif ( $c == 3 ) { $stripe3start = 130 ; $stripe3width = 7 ; $stripe4start = 180 ; $stripe4width = 4 ; $stripe5start = 227 ; $stripe5width = 39 ; $stripe1start = 1 ; $stripe1width = 39 ; $stripe2start = 83 ; $stripe2width = 4 ; $lwidth = 12 ; # period (was 6 and 2) (or 8 and 3) $onwidth = 4 ; # amount of ink $o0 = 0 ; $oh = 7 ; $stripe3end = $stripe3start + $stripe3width ; $stripe4end = $stripe4start + $stripe4width ; $stripe5end = $stripe5start + $stripe5width ; } $stripe1end = $stripe1start + $stripe1width ; $stripe2end = $stripe2start + $stripe2width ; @stripes = () ; @stripes = ($stripe1start..$stripe1end, $stripe5start..$stripe5end, $stripe2start..$stripe2end, $stripe3start..$stripe3end, $stripe4start..$stripe4end) ; print @stripes if ($verbose) ; $off = 0 ; foreach $t ( @stripes ) { if ( $t ) { # ignore zeroes &doit() ; } } if ( $filled ) { # fill in intersections foreach $t ( @stripes ) { if ( $t ) { # ignore zeroes foreach $tt ( @stripes ) { if ( $tt ) { # ignore zeroes $x = $period+1-$t ; $y = $tt ; &checkdraw ; if ( $repeat ) { &dorepeat ; } } } # } # } # } print "pbmx = $pbmx\n" ; &markers ; $c ++ ; $high ++ ; # assumes high was 1... } while ( $c <= $all ) ; sub markers { print "pbmx = $pbmx\n" ; docross ( $pbmx - 30 , $pbmy - 80 , $c * 5 -4 , ($c+1)* 5 - 5 ) ; docross ( 30 , 130 , $c * 5 -4 , ($c+1)* 5 - 5 ) ; print "centre is at $centrex, $centrey\n" ; if ( $fiduc ) { docross ( $centrex , $centrey , 5 , 165 ) ; print ( $centrex + $trueradius , ":" , $centrey + $trueradius , "\n" ) ; dofloor ( ($centrex + $trueradius) , ($centrey + $trueradius) , 1 , 10 ) ; print ( $pbmx , " : " , $pbmy, "\n" ) ; doceil ( $centrex - $trueradius , $centrey - $trueradius , 1 , 10 ) ; } dofloor ( $pbmx , $pbmy, 1 , 10 ) ; } sub docross { local ( $xx , $yy , $start , $end ) = @_ ; dofloor ( $xx , $yy , $start , $end ) ; doceil ( $xx , $yy , $start , $end ) ; } sub dofloor { local ( $xx , $yy , $start , $end ) = @_ ; print "pbmx = $pbmx\n" ; print ( "floor " , $xx , " : " , $yy, "\n" ) ; $y = $yy ; for ( $x = $xx - $end ; $x <= $xx - $start ; $x ++ ) { $i0 = $x + ($y-1) * $pbmx ; $c[$i0] = $high; } $x = $xx ; for ( $y = $yy - $end ; $y <= $yy - $start ; $y ++ ) { $i0 = $x + ($y-1) * $pbmx ; $c[$i0] = $high; } } sub doceil { local ( $xx , $yy , $start , $end ) = @_ ; $y = $yy ; for ( $x = $xx + $start ; $x <= $xx + $end ; $x ++ ) { $i0 = $x + ($y-1) * $pbmx ; $c[$i0] = $high; } $x = $xx ; for ( $y = $yy + $start ; $y <= $yy + $end ; $y ++ ) { $i0 = $x + ($y-1) * $pbmx ; $c[$i0] = $high; } } sub checkdraw { # local ($x,$y) = @_ ; # $x -= $dx ; # $y -= $dy ; return if ( $x > $pbmx || $y > $pbmy ); if ( $circle ) { $rc = ($x-$centrex)**2 + ($y-$centrey)**2 ; if ( $rc > $radius ) { $p = 1.0 - ( $rc/$radius - 1.0 ) / $shelf ; if ( $p <= 0.0 || rand() > $p ) { return ; } } } if ( $circle2 ) { $rc = ($x-$ex)**2*$efx + ($y-$ey)**2 + $elip * ($y-$ey) * ($x-$ex) ; if ( $rc < $re ) { $p = 1.0 - ( 1.0 - $rc/$re ) / $eshelf ; if ( $p <= 0.0 || rand() > $p ) { return ; } } } $i0 = $x + ($y-1) * $pbmx ; $c[$i0] = $high; } # # # if ( $pbmplot ) { $tot = 0 ; $i0 = 0 ; for ( $i = 1 ; $i <= $pbmy ; $i ++ ) { for ( $j = 1 ; $j <= $pbmx ; $j ++ ) { $i0 ++ ; print PBM "$c[$i0] " ; $tot += $c[$i0] ; } print PBM "\n" ; } # bottom line close ( PBM ) ; print STDERR "$tot pixels high out of $P\n" ; } print STDERR "\n# xv $pbmfile\n" ; sub dorepeat { $x += $period ; &checkdraw ; $y += $period ; &checkdraw ; $x -= $period ; &checkdraw ; if ( $repeat > 2 ) { $y += $period ; &checkdraw ; $x += $period ; &checkdraw ; $x += $period ; &checkdraw ; $y -= $period ; &checkdraw ; $y -= $period ; &checkdraw ; } } sub doit { # off is the offset for the very first stripe $off = ($t+$o0) % $lwidth + 1 ; # off2 is the offset in the current stripe, which rotates. $off2 = $off ; $off3 = $off + $oh ; for ( $s = 1 ; $s <= $period ; $s ++ ) { if ( $off2 >= $lwidth ) { $off2 -= $lwidth ; } if ( $off3 >= $lwidth ) { $off3 -= $lwidth ; } if ( $off3 < $onwidth ) { $x = $period+1-$t ; $y = $period+1-$s ; &checkdraw ; if ( $repeat ) { &dorepeat ; } } if ( $off2 < $onwidth ) { $x = $s ; $y = $t ; &checkdraw ; if ( $repeat ) { &dorepeat ; } } # $off2 ++ ; $off3 ++ ; } }