Zuletzt geändert: Mi, 20.07.2005

«11C» sat.pl «PDF», «POD»



Download
#!/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;
}