Back to Wyrdchao.net
Down to Bottom

Bok/Tk version 0.57 listing


Below is my listing for a Perl5/Tk program that does everything the from  this article. 
If you want to skip straight to the Bok equations below, click here.
or click here to download everything in a zip file.
#!/usr/bin/perl
#
# Canvas bouncing 'buttons' 
# 
# 2/19/08 - Pat Struthers
#

use Tk;
use strict;
use Time::HiRes qw(gettimeofday);

my $tstep = 100;

my $hmax = 200;
my $wmax = 200;

my $ohx = my $owx = 0;

my $lmg = 15;
my $rmg = 15;
my $tmg = 15;
my $bmg = 60;

# Bok drive variables start here


my $pi = 3.1415926535;
my $gth = 1;
my $p2au = 206265;

my $dummy = "";

my $ptw = 10;
my $cargmass = 600;
my $cargm0 = 600;
my $stx = 2.1;

my $nc = 5;

my $mst1 = 1;
my $mst2 = 1;

# start laying stuff out

my $mw = MainWindow->new;

$mw->title('Bok-Tk 0.52');
$mw->repeat($tstep, \&redowin);

my $rcv = $mw->Canvas(-relief=>'sunken')
	->pack(-side=>"top", -fill=>"both", -expand=>'1');

my $xmax = $rcv->canvasx($mw->width - $rmg);
my $ymax = $rcv->canvasx($mw->height - $bmg);
my $xmin = $rcv->canvasx($lmg);
my $ymin = $rcv->canvasx($tmg);
my $ctrx = ($xmax - $xmin) / 2 + $rmg;
my $ctry = ($ymax - $ymin) / 2 + $tmg;


my $frct = $rcv->createRectangle($xmin, $ymin, $xmax, $ymax, -fill=>'white'); 

my $l3 = $rcv->createLine($ctrx, $ymin, $ctrx, $ymax);


my $abut = $mw->Button(-text=>"Do!", -command => \&dobut)
	->pack(-side=>"left"); 
my $xbut = $mw->Button(-text=>"Exit", -command => sub { exit })
	->pack(-side=>"left"); 

my $pwt_sc = $mw -> Scale(-label=>"P/M ratio",
	-orient=>'h', -from=>2,	-to=>25,
	-sliderlength=>10, -resolution=>0.1, -length=>60,
	-width=>8,
	-variable=>\$ptw)
	->pack(-side=>"left"); 

my $nc_sc = $mw -> Scale(-label=>"Crew #",
	-orient=>'h', -from=>1,	-to=>2500,
	-sliderlength=>10, -resolution=>1, -length=>80,
	-width=>8,
	-variable=>\$nc)
	->pack(-side=>"left"); 

my $crg_sc = $mw -> Scale(-label=>"Cargo Max",
	-orient=>'h', -digit=>1, -from=>100, -to=>20000,
	-sliderlength=>10, -resolution=>10, -length=>80,
	-width=>8,
	-variable=>\$cargmass)
	->pack(-side=>"left"); 

my $crg0_sc = $mw -> Scale(-label=>"Cargo",
	-orient=>'h', -digit=>1, -from=>0, -to=>20000,
	-sliderlength=>10, -resolution=>10, -length=>80,
	-width=>8,
	-variable=>\$cargm0)
	->pack(-side=>"left"); 

my $dist_sc = $mw -> Scale(-label=>"Target Dist",
	-orient=>'h', -from=>0.5,	-to=>3.5,
	-resolution=>0.01, -sliderlength=>10, -length=>60,
	-width=>8,
	-variable=>\$stx)
	->pack(-side=>"left"); 

my $mst1_sc = $mw -> Scale(-label=>"Mass 1",
	-orient=>'h', -from=>0.01,	-to=>5.00,
	-resolution=>0.01, -sliderlength=>10, -length=>60,
	-width=>8,
	-variable=>\$mst1)
	->pack(-side=>"left"); 

my $mst2_sc = $mw -> Scale(-label=>"Mass 2",
	-orient=>'h', -from=>0.01,	-to=>5.00,
	-resolution=>0.01, -sliderlength=>10, -length=>60,
	-width=>8,
	-variable=>\$mst2)
	->pack(-side=>"left"); 

my $ddlg;   #declared Toplevel for a dialog box later...

MainLoop;

## subs below...
sub dobut {  # do lots of Bok calculations here...

	my @lc = ();
	my $j;

	my $stx_au = $stx * $p2au;
	my $sty = 0.5 * sqrt($mst2);
	my $stz = 0.5 * sqrt($mst2);
	my $shmass = 1.5 * (500 + 1.5 * $cargmass + 20 * $nc) / (1 - 1.5 * $ptw / 100);
	my $genpower = $ptw * $shmass;
	my $genmass = 400 + $genpower / 100;
	my $lfmass = 100 + $nc * 20;
	my $fmass = ($genmass + $cargmass + $lfmass) / 2;
	my $fldrg = $genpower / 260;
	my $saferg = $genpower / 800;

	$shmass = $shmass - $cargmass + $cargm0;
	my $ptwe = $genpower / $shmass;

	my $bokpb = ($ptw * $pi/80) + $pi/8;

	my $genf = 1.2 * $stx_au / ((1 + $bokpb/(2 * $pi)) * 41253 * $ptwe);

	my $bokwl = $genf * ((2 * $pi + $bokpb)/(2 * $pi)) * 41253 * $ptwe;
	my $bokrg = $genf * $ptwe / 5;

	my $gscal = 0.5;

	my $vx = $genf * ($ptwe**1.1) * 1700;
	my $vxd = 7 * $vx / $p2au;
	my $vxdc = $vxd * 170.07;

	my $boket = $bokrg * 7 / $vxd;
   
	# destroy old plot, if it exists

	for ($j = 0; $j > 50 ; $j++) { 
		if (!Exists($lc[$j])) {$lc[$j]->destroy();}	
	}

	# pop up a display window

	if (!Exists($ddlg)) { 
		$ddlg = $mw->Toplevel(-width=>400);
		$ddlg->title('Bok-Tk Results');
	}
	else { $ddlg->deiconify(); $ddlg->raise(); }

	my $dtxt = $ddlg->Text(-font=>['courier', '8'], 
		-width=>50, -height=>40)->pack;

	$dtxt->insert('end', sprintf(" total ship   - %7.1f tons\n", $shmass ));
	$dtxt->insert('end', sprintf ("         gen. - %7.1f tons\n", $genmass));
	$dtxt->insert('end', sprintf("     life sys - %7.1f tons\n", $lfmass ));
	 $dtxt->insert('end', sprintf("         fuel - %7.1f tons\n", $fmass ));
	 $dtxt->insert('end', sprintf("        cargo - %7.1f tons\n\n", $cargm0 ));
	 $dtxt->insert('end', sprintf(" gen. power - %8.1f kW\n", $genpower ));
	 $dtxt->insert('end', sprintf(" safe range - %7.1f km\n", $saferg ));
	 $dtxt->insert('end', sprintf(" fld range - %7.1f m\n", $fldrg ));
	 $dtxt->insert('end', "power to wt. - $ptw\n");

	 $dtxt->insert('end', sprintf(" Power setting - %5.3f\n\n", 100*$genf));
	 $dtxt->insert('end', "Bok wlength. - $bokwl AU\n");
	 $dtxt->insert('end', "range        - $bokrg pc\n");
	 $dtxt->insert('end', sprintf("ETA          - %8.3f days\n", $boket));
	 $dtxt->insert('end', sprintf( " psuedo vel   - %6.2f c\n", $vxdc));



	my $z = 0;
	my $i = 0.5 * $mst1;
	my $et = 0;
	my $i0 = $i;
	my $giveup = 0;


	my $bokph;
	my $z0 = $z;


		# start of course iteration loop here....


	my $zxsc = ($xmax - $xmin) * 0.8 / $bokwl;
	my $zysc = ($ymax - $ymin) * 0.8 / 3;

	my $szx = my $oldzx = 0.2 * ($xmax - $xmin) + $lmg;
	my $szy = my $oldzy =  0.8 * ($ymax - $ymin) + $tmg;


		#blank the screen

	$rcv->delete($frct); $rcv->delete($l3);
	$frct = $rcv->createRectangle($xmin, $ymin, $xmax, $ymax, -fill=>'white'); 
	$l3 = $rcv->createLine($ctrx, $ymin, $ctrx, $ymax);
	my $lc_base = $rcv->createLine($xmin + 50, $szy - ($zysc * 0.5), 
		$xmax - 50, $szy - ($zysc * 0.5), -fill=>'red');

	while (1){

		$giveup++;
	
		my $gi = $mst1 * $gth /(7 * $i * $i);
		my $gj = $mst2 * $gth / (7 * (($stx_au - $i)**2 + $sty**2 + $stz**2));

		$bokph = -$pi/2 + 2 * $pi * $i / $bokwl + $bokpb;

		$z0 = $z;
		$z = sin($bokph) - $gscal * ($gi + $gj) + 1.01;

		if ($z >0) {
			$et = $et + ($i - $i0)/$vx;
		}


		if (($z < 0 && $et > 0.1) || $giveup > 100) {
			$i = $i0 + ($i - $i0) * $z0 / ($z0 - $z);
			last;
		}
		else {
			$i0 = $i;
			if ($i < $stx_au *0.9) {$i += ($stx_au / 20);}
			else {$i += ($stx_au - $i)/2;} 
			
			#let's try to draw something
			$oldzx = $szx; $oldzy = $szy;

			$szx = 0.2 * ($xmax - $xmin) + $lmg + ($zxsc * $i);
			$szy = (0.8 * ($ymax - $ymin) + $tmg) - ($zysc * (0.5 + $z));

			$lc[$giveup]=$rcv->createLine($szx, $szy, $oldzx, $oldzy);


		}
	}	# end of loop


	my $Dfx = 2 * $ptw ** 2 / 5;

	my $gj = $mst2 * $gth / (7 * (($stx_au - $i)**2 + $sty**2 + $stz**2));

	my $vdd = ($gj * $vxdc / 10000) ** (1/3) + 0.53;
	my $gamma = 1 / (1 - $vdd * $vdd);
	my $KE = 0.5 * ($gamma - 1) * ($shmass * 1000) * (300000000 ** 2);


	$dtxt->insert('end', "\n--------------\nFinal Numbers\n----------------\n" ); 
	$dtxt->insert('end', sprintf "%9.2f AU  -- ET %5.2f days" ,$i , $et ); 
	$dtxt->insert('end', sprintf "\nMax. Dump factor - %6.1f", $Dfx ); 
	$dtxt->insert('end', sprintf "\n0.75 Dump factor - %6.1f", $Dfx * 0.75 ); 
	$dtxt->insert('end', sprintf "\nDrop out vel.    - %5.3f c\n\n", $vdd );


	my $j = 0;
	my $vu = "c";

	while (1) {
		$i = $i + 15 * ($vdd * 300000) / 149600000;
		if ($vdd < 0.01) {$vdd = $vdd * 300000; $vu = 'km/sec';}

		$dtxt->insert('end', 
			sprintf "Dump %d  -- v => %5.4f %s\n", $j++, $vdd, $vu); 

		if ($vu ne "c" && $vdd < 300) {last;}	
	
		$KE = $KE / ($Dfx * 0.75);
		$vdd = sqrt(1 - (1 / ((2 * $KE / 
			($shmass * 1000 * (300000000 ** 2))) + 1))); 
		$gamma = 1 / (1 - $vdd * $vdd);

	}

	my $jj = sqrt(($i - $stx_au)**2 + $sty ** 2 + $stz ** 2);
	my $eti = $jj * 149600000 / (3600 * $vdd) ;

	$dtxt->insert('end', sprintf "\ndistance to station: %8.3f AU\n", $jj ); 
	$dtxt->insert('end', sprintf "ETA from last dump : %6.2f hours\n", $eti ); 

	$ddlg->Button(-text=>"Exit", 
			-command => sub { $ddlg->destroy }) ->pack;

}

sub redowin {


	$ohx = $hmax;
	$owx = $wmax;

	$wmax = $mw->width - $rmg - $lmg;	
	$hmax = $mw->height - $tmg - $bmg;

	if ($ohx != $hmax || $owx != $wmax) {

		$xmax = $rcv->canvasx($mw->width - $rmg);
 		$ymax = $rcv->canvasx($mw->height - $bmg);
 		$xmin = $rcv->canvasx($lmg);
		$ymin = $rcv->canvasx($tmg);

		$ctrx = ($xmax - $xmin) / 2 + $rmg;
		$ctry = ($ymax - $ymin) / 2 + $tmg;



		$rcv->coords($frct, $xmin, $ymin, $xmax, $ymax); 

		$rcv->coords($l3, $ctrx, $ymin, $ctrx, $ymax); 

	}
}

sub fround {
	return ($_[0] < 0 ? -1 : 1) * int(abs($_[0]) * 1000 + 0.5) / 1000;
}

# end of test


Back to top