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