#!/usr/bin/perl
use warnings;
use strict;
# Grafikbibliothek einbinden
use Tk;
my $mw = MainWindow->new;
my $canvas = $mw->Scrolled("Canvas", -scrollbars => "se");
$canvas->pack;
use constant EPSILON => 10e-8;
my $v0 = 7;
my $h = 2600;
my $vx = 0;
my $vy = -1000 * $v0;
my $dt = 100;
my $mx = 150000;
my $my = 150000;
my $G = 6.67e-11;
my $M = 5.98e+24;
my $C = $G * $M;
my $R = 6370000;
my $x = $R + 1000*$h;
my $y = 0;
my $pset = sub {
my ($x, $y) = @_;
$canvas->createOval($x - .5, $y - .5, $x + .5, $y + .5, -tags => [qw< dot >]);
$canvas->createOval($x - .5, $y - .5, $x + .5, $y + .5,);
};
# Erde und Startpunkt
my $etag;
my $erde = sub {
$canvas->delete($etag) if $etag;
$etag = $canvas->createOval(200-$R/$mx, 100-$R/$my, 200+$R/$mx, 100+$R/$my);
};
$erde->();
my $stag;
my $run = 0;
my ($hh, $hh_human);
my $update = sub {
return unless $run;
$canvas->delete($stag) if $stag;
# Ausgabe
{
my $ho = sqrt($x**2 + $y**2) - $R;
$hh = sprintf "%d", round($ho);
$hh_human = sprintf "%d", $hh / 1000;
if($ho <= 0) {
$run = 0;
$mw->messageBox(-type => "Ok", -title => "Shit", -message => "Absturz auf der Erde");
return;
}
my ($xs, $ys) = (200 + $x/$mx, 100 + $y/$my);
$stag = $pset->($xs, $ys) if $xs > 0 and $ys > 0;
}
{
$x += $vx * $dt;
$y += $vy * $dt;
my $ae = -$C/($x**2 + $y**2)**1.5;
my $ax = $ae * $x;
my $ay = $ae * $y;
$vx += $ax * $dt;
$vy += $ay * $dt;
}
};
# Bindings einiger Variablen an Tk
{
my $frame = $mw->Frame;
my $l_v0 = $mw->Label(-text => "v0/(km/s):");
my $e_v0 = $mw->Entry(-textvariable => \$v0);
my $l_h = $mw->Label(-text => "h0/km:");
my $e_h = $mw->Entry(-textvariable => \$h);
my $l_G = $mw->Label(-text => " G/[m^3/(kg s^2)]:");
my $e_G = $mw->Entry(-textvariable => \$G);
my $l_M = $mw->Label(-text => "M/kg:");
my $e_M = $mw->Entry(-textvariable => \$M);
my $l_hh = $mw->Label(-text => "h/km:");
my $e_hh = $mw->Entry(-textvariable => \$hh_human);
my $l_R = $mw->Label(-text => "R/km:");
my $e_R = $mw->Entry(-text => $R / 1000);
my $updC = $mw->Button(-text => "Ok", -command => sub {
$R = $e_R->cget("-text") * 1000;
$erde->();
$C = $G * $M;
});
my $runB = $mw->Button(-text => "Ok", -command => sub {
$run = 1 - $run;
$vy = -1000 * $v0;
$x = $R + 1000*$h;
$y = 0;
$vx = -$C/($x**2) * $dt/2;
});
my $clear = $mw->Button(-text => "Clear", -command => sub {
$canvas->delete("dot");
});
$l_v0->grid(-row => 0, -column => 0, -sticky => "e", -in => $frame);
$e_v0->grid(-row => 0, -column => 1, -sticky => "w", -in => $frame);
$l_h ->grid(-row => 1, -column => 0, -sticky => "e", -in => $frame);
$e_h ->grid(-row => 1, -column => 1, -sticky => "w", -in => $frame);
$l_hh->grid(-row => 2, -column => 0, -sticky => "e", -in => $frame);
$e_hh->grid(-row => 2, -column => 1, -sticky => "w", -in => $frame);
$runB->grid(-row => 0, -column => 2, -rowspan => 2, -sticky => "ns", -in => $frame);
$l_G ->grid(-row => 0, -column => 3, -sticky => "e", -in => $frame);
$e_G ->grid(-row => 0, -column => 4, -sticky => "w", -in => $frame);
$l_M ->grid(-row => 1, -column => 3, -sticky => "e", -in => $frame);
$e_M ->grid(-row => 1, -column => 4, -sticky => "w", -in => $frame);
$l_R ->grid(-row => 2, -column => 3, -sticky => "e", -in => $frame);
$e_R ->grid(-row => 2, -column => 4, -sticky => "w", -in => $frame);
$updC->grid(-row => 0, -column => 5, -rowspan => 3, -sticky => "ns", -in => $frame);
$clear->grid(-row => 3, -column => 0, -columnspan => 6, -sticky => "we", -in => $frame);
$frame->pack;
}
$canvas->repeat(50, $update);
MainLoop;
sub round {
my $ho = shift;
return $ho;
return 0 if $ho <= EPSILON;
my $hh = $ho / 1000; # Abstand in km
return int($hh/100 + 0.5)*100 if $hh >= 10000;
return int($hh/10 + 0.5)*100 if $hh >= 1000;
return int($hh/1 + 0.5)*100 if $hh >= 100;
return int($hh*10 + 0.5)*100 if $hh >= 10;
return int($hh*100 + 0.5)*100 if $hh >= 1;
return int($hh*1000 + 0.5)*100 if $hh >= 0.1;
return int($hh*10000 + 0.5)*100 if $hh >= 0.01;
return int($hh*100000 + 0.5)*100 if $hh >= 0.001;
return int($hh*1000000 + 0.5)*100 if $hh >= 0;
}
Download