#!/usr/bin/perl -l use lib qw{packages}; use Astro::SpaceElevator 0.05; use Class::Date qw{date}; use Getopt::Lucid qw{:all}; use SVG::TT::Graph; use SVG::TT::Graph::TimeSeries; $Class::Date::DEFAULT_TIMEZONE = 'UTC'; my $opt; eval { $opt = Getopt::Lucid->getopt([Param("start|s")->required, Param("end|e")->default("1D"), Param("interval|i")->default("1h"), Param("graph|g"), Switch("lunar|l")]); }; if ($@) { if (ref $@ eq 'Getopt::Lucid::Exception::ARGV') { print qq{Error: $@ Usage: ./shadows.pl --start "2006-01-01 04:00:00" --end "12h" --interval 5m --graph one-day.svg Options: --start -s required Starting time as a string. --end -e 1 day Duration of the simulation. --interval -i 1 hour Size of the time step. --graph -g Name of a file to write an svg graph to. --lunar -l When specified, the output will include information on the lunar shadow. Note that there are a number of parameters passed to the SVG Graphing module that you may want to change, but that currently have no command line equivalent. I consider it a bug, but for my purposes a fairly minor one. Until I add the necessary options (and some smart defaults), you'll want to review the contents of this script and make changes as necessary. }; exit 1; } ref $@ ? $@->rethrow : die $@; } my $graphname = $opt->get_graph; my @shadowdata; my $start = date $opt->get_start; my $end = $start + $opt->get_end; my $interval = new Class::Date::Rel $opt->get_interval; my $include_lunar = $opt->get_lunar; my $elevator = new Astro::SpaceElevator(0, 120, 100_000, $time); for (my $current = $start; $current <= $end; $current += $interval) { $elevator->time($current->epoch); my $data = $elevator->shadows($include_lunar); $data->{time} = $current; if ($graphname) { push @shadowdata, $data; } else { local $, = '|'; local $" = ','; print ($current, "@{$data->{Earth}{umbra}}", "@{$data->{Earth}{penumbra}}", "@{$data->{Moon}{umbra}}", "@{$data->{Moon}{penumbra}}"); } } if ($graphname) { # You'll probably want to change a number of these values, as # they're really only suitable for a particular graph my $graph = new SVG::TT::Graph::TimeSeries({height => 1000, width => 1200, show_data_values => 0, key => 1, key_position => 'bottom', show_graph_title => 1, graph_title => 'Shadow height on the Space Elevator', show_x_title => 1, x_title => 'Date', rotate_x_labels => 1, #x_label_format => '%Y-%m-%d', x_label_format => '%H:%M:%S', #x_label_format => '%Y-%m-%d %H:%M', timescale_divisions => '1 hours', max_scale_value => 10200, show_y_title => 1, y_title => 'Height (km)', style_sheet => 'graph.css'}); $graph->max_time_span('30 minutes'); for $body ('Earth', $include_lunar ? 'Moon' : ()) { for $shadow ('umbra', 'penumbra') { for $slice (0, 1) { $graph->add_data({data => [grep { defined $_->[1] } map { [$_->{time}, $_->{$body}{$shadow}->[$slice]] } @shadowdata], title => "${body}'s $shadow"}); } } } open GRAPH, '>', $graphname; print GRAPH $graph->burn; }