astronomical perl (just a tiny bit of it)

rjbs on 2006-10-13T11:08:46

The new house is three stories, and gets lots of natural light. Sadly, none of its third story windows is well-placed for stargazing. If one was, I'd have more time to look through my telescope and more inspiration to write silly astronomy code. Maybe when we overhaul the third floor, we'll put in a window on the slant of the roof. Probably not.

Since I don't do much stargazing, my last need for astronomical Perl code came while working on the RPG that I run. It's space-based, and I wanted to get an idea of distance between various star systems. There were a number of Astro modules on the CPAN, but most of them either lacked the few features I needed or required third party libraries that didn't just work out of the box.

Since I didn't need much at all, I just broke out my copy of Practical Astronomy For Your Personal Computer (a fantastic book that I've never regretted buying), and wrote this silly little program. It would be a lot more fun if there was a giant and easy to access database of stars. I think I'll need to dig more for that.

package Astro;
use Math::Trig ();

use strict;
use warnings;

# Stars are located by their RA (right ascension), declination, and distance
# from earth.

# RA  is usually expressed in hms: hours,   minutes,    seconds
# dec is usually expressed in dms: degrees, arcminutes, arcseconds
# distance is usually expressed in light years

# Spherical coordinates are usually expressed as [ rho, phi, theta ]
#   rho   - distance from center
#   phi   - one angle, in degrees
#   theta - one angle, in degrees

# A star's position can be expressed as [ dist, dec, ra ]

sub hms_to_dms {
  my ($hours, $minutes, $seconds) = @_;

  return map { $_ * 15 } @_;
}

sub dms_to_d {
  my ($deg, $arcmin, $arcsec) = @_;
  return $deg + $arcmin/60 + $arcsec/3600;
}

# given RA in hms, dec in dms, distance in ly
sub star_to_xyz {
  my ($dist, $dec, $ra) = @_;

  my $dec_deg = dms_to_d(@$dec);
  my $ra_deg  = dms_to_d(hms_to_dms(@$ra));

  for my $deg ($dec_deg, $ra_deg) {
    $deg = 360 - $deg if $deg < 0;
  }

  my $dec_rad = Math::Trig::deg2rad($dec_deg);
  my $ra_rad  = Math::Trig::deg2rad($dec_deg);

  return my ($x, $y, $z)
    = Math::Trig::spherical_to_cartesian($dist, $dec_rad, $ra_rad);
}

sub dist {
  my ($p1, $p2) = @_;

  my $mhd
    = ($p2->[0] - $p1->[0]) ** 2
    + ($p2->[1] - $p1->[1]) ** 2
    + ($p2->[2] - $p1->[2]) ** 2;

  return $mhd ** 0.5;
}

sub star_dist {
  my ($star1, $star2) = @_;

  my @s1_xyz = star_to_xyz(@$star1);
  my @s2_xyz = star_to_xyz(@$star2);

  print "star1: @s1_xyz\n";
  print "star2: @s2_xyz\n";

  dist(\@s1_xyz, \@s2_xyz);
}

my @aca  = star_to_xyz( 4.36, [ -60, 50,  2 ], [  14, 39, 37 ]);
my @acb  = star_to_xyz( 4.36, [ -60, 50, 14 ], [  14, 39, 35 ]);
my @wolf = star_to_xyz( 7.78, [   7, 00, 42 ], [  10, 56, 37 ]);

my %star = (   #  dist,   dec,               ra
  capella   => [ 42.20, [  45,  59,  53 ], [  5, 16, 41 ] ], # Alpha Aurigae
  castor    => [ 49.77, [  31,  53,  18 ], [  7, 34, 36 ] ], # Castor
  centauri  => [  4.36, [ -60, -50,  -2 ], [ 14, 39, 37 ] ], # a; Rigil Kent
                                                             # toliman, bungula
  draconis  => [ 18.78, [  69,  39,  40 ], [ 19, 32, 21 ] ], # Sigma Draconis
  eridani   => [ 10.52, [ - 9, -27, -30 ], [  3, 32, 56 ] ], # Epsilon Eridani
  errai     => [ 45.00, [  77,  37,  56 ], [ 23, 39, 21 ] ], # Gamma Cephei
  geminorum => [ 33.72, [  28,   1,  35 ], [  7, 45, 19 ] ], # Pollux
  gliese    => [ 51.81, [  29,  53,  48 ], [ 20,  3, 37 ] ], # Gliese 777; bin
  luyten    => [  8.72, [  17,  57,   0 ], [  1, 39,  1 ] ], # 726-8
  mensae    => [ 33.10, [ -74, -45, -11 ], [  6, 10, 14 ] ], # Alpha Mensae
  pavonis   => [ 30.10, [ - 5, -21, -58 ], [ 21, 26, 26 ] ], # gamma
  pegasi    => [ 53.00, [  12,  11,  00 ], [ 22, 46, 42 ] ], # Xi Pegasi
  persei    => [ 34.40, [  49,  36,  48 ], [  3,  9,  4 ] ], # Iota Persei
  reticuli  => [ 39.51, [ -62, -34, -31 ], [  3, 17, 42 ] ], # Zeta (binary)
  scorpii   => [ 45.70, [ - 8, -22, - 6 ], [ 16, 15, 37 ] ], # 18 Scorpii
  sol       => [  0.00, [   0,   0,   0 ], [  0,  0,  0 ] ], # YOU ARE HERE
  tau_ceti  => [ 11.89, [ -15, -56, -14 ], [  1, 44,  4 ] ], # Tau Ceti
  tucanae   => [ 28.00, [ -64, -52, -29 ], [  0, 20,  4 ] ], # Zeta
  wolf      => [  7.78, [   7,  00,  42 ], [ 10, 56, 37 ] ], # Wolf 359
  zavijava  => [ 35.60, [   1,  45,  53 ], [ 11, 50, 42 ] ], # Beta Virginis
);

if (@ARGV == 2) {
  print star_dist($star{$ARGV[0]}, $star{$ARGV[1]}), "\n";
} else {
  my @max = (0, undef, undef);
  for my $star1 (keys %star) {
    next unless $star{$star1};
    for my $star2 (grep { $_ ne $star1 } keys %star) {
      next unless $star{$star2};
      my $dist = star_dist($star{$star1}, $star{$star2});
      @max = ($dist, $star1, $star2) if $dist > $max[0];
    }
  }

  print "@max\n";
}

1;


Database of stars

Aristotle on 2006-10-13T12:19:42

Are you thinking about something like the New General Catalogue (NGC)? Or one of the specialised star catalogues?

PS.: <ecode> tags automatically escape their content, so if you escape it as well it comes out with gibberish.

Re:Database of stars

rjbs on 2006-10-13T13:01:52

The NGC or any full-sky catalog would be swell.

As for ecode, I really thought I'd fixed my posting script... hmph!

Re:Database of stars

Aristotle on 2006-10-13T14:03:43

Something like The Interactive NGC Catalog Online?

Re:Database of stars

rjbs on 2006-10-20T13:24:04

Beyond the fact that the form doesn't seem to work properly in Firefox, this lacks information like "distance," and doesn't seem to have any system for better machine queries.

The HYG database looks potentially like just what I wanted. Now, to make an interface...

First Perl program!

ChrisDolan on 2006-10-13T15:55:10

It's interesting you bring this up. Here's a link to my very FIRST Perl program ever:
    http://www.astro.wisc.edu/user/dolan/gurps/galdist.cgi

It computes actual and perceived travel times for relativistic journeys between nearby star systems. I wrote it for a (short-lived) sci-fi RPG campaign back in 1999. All of the players in the game were astronomy PhD students, like me, so I had to get the math right. :-)

check the HYG database

dwhite21787 on 2006-10-14T21:16:55

http://astronexus.com/node/34

HYG to 7.5: Database containing all stars brighter than magnitude +7.5, or closer than 50 parsecs. This is the same as the "Version 1.0" database that has been on this site before. (31858 stars)