#!/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