Messing around in stutterspace

Having done the Chinese arm, my next effort has been to try and do a new map of the French arm based on Constantine’s updated near star list.  However I found I was running into problems because I was relying on a variety of websites to tell me the distances between stars, and sometimes they contradicted each other, or sometimes they just didn’t have the stars that I was interested in (but that Constantine was showing as being within 7.7 ly).  Now the simple solution would have been to have used Astrosynthesis like he does, but I have a very old Mac Mini at home, and it is a PC piece of software, so that was out.  And anyway, I didn’t want all of the features of Astrosynthesis, just something that would tell me the distance between two coordinates, which is Pythagoras.  So I decided that the simplest thing would be to knock up a quick script (not my first thought though – that was to do it in Excel, which is possible, but produces a matrix that is very sparsely populated, and very difficult to read).  Normally I would script something in php, but a friend had been extolling the virtues of Python, so I decided to use it as an opportunity to learn some basic Python as well.

The input is designed to be a simple csv file of star coordinates, names and characteristics.  The output, in this version, is a text file and html file, listing each star in alphabetical order, with the distances to all the stars that are within 7.7 ly.

The python script is:

import math
from operator import itemgetter

def main(filepath):
 star_data = []
 nav_data = []
 import_position_data(filepath, star_data)
 calculate_distances(star_data, nav_data)
 write_output_file(nav_data)
 write_html_file(nav_data)

def import_position_data(filepath, star_data):
 input_f = open(filepath, 'r')
 for line in input_f:
  line_data = line.split(',')
  star_data.append(line_data)
 input_f.close()

def calculate_distances(star_data, nav_data):
 for star_a in star_data:
  this_nav_data = star_a
  for star_b in star_data:
   if star_a[2] != star_b[2]:
    distance = math.sqrt(
    (float(star_a[3]) - float(star_b[3]))**2
    +(float(star_a[4]) - float(star_b[4]))**2
    +(float(star_a[5]) - float(star_b[5]))**2)
    if distance <= 7.7:
     this_route_data = [star_b[2], distance, star_b[3], star_b[4], star_b[5]] 
     this_nav_data.append(this_route_data)
     del this_route_data
   nav_data.append(this_nav_data)
   del this_nav_data

def write_output_file(nav_data):
 # sort into Star name order
 sorted_nav_data = sorted(nav_data, key=itemgetter(2))
 output_f = open("star_distances.txt", 'w')
 for star in sorted_nav_data:
  output_f.write('=' * 40 + '\n')
  output_f.write(star[2] + '\n')
  output_f.write('-' * 20 + '\n')
  output_f.write(star[9] + '\n')
  output_f.write('X coordinate: ' + star[3] + '\n')
  output_f.write('Y coordinate: ' + star[4] + '\n')
  output_f.write('Z coordinate: ' + star[5] + '\n')
  distance_from_sol = math.sqrt(
  (float(star[3]))**2
  +(float(star[4]))**2
  +(float(star[5]))**2)
  output_f.write('Distance from Sol: ' + str(distance_from_sol)[0:4] + ' ly\n')
  output_f.write('\n') 
  output_f.write('Neighbours\n')
  for neighbour in star[12:]: 
   output_f.write(neighbour[0] + " at " + str(neighbour[1])[0:4] + "ly\n")
  output_f.write('\n')
  del distance_from_sol
 output_f.close()

def write_html_file(nav_data):
 # sort into Star name order
 sorted_nav_data = sorted(nav_data, key=itemgetter(2))
 output_f = open("star_distances.html", 'w')
 output_f.write('<html><head></head><body>\n')
 for star in sorted_nav_data:
  output_f.write('<h2>' + star[2] + '</h2>\n')
  output_f.write('<p>Type: ' + star[9] + '</p>\n')
  output_f.write('<p>X coordinate: ' + star[3] + '</p>\n')
  output_f.write('<p>Y coordinate: ' + star[4] + '</p>\n')
  output_f.write('<p>Z coordinate: ' + star[5] + '</p>\n')
  distance_from_sol = math.sqrt(
  (float(star[3]))**2
  +(float(star[4]))**2
  +(float(star[5]))**2)
  output_f.write('<p>Distance from Sol: ' + str(distance_from_sol)[0:4] + ' ly</p>\n')
  output_f.write('</br>\n')
  output_f.write('<p>Neighbours:</p>\n')
  for neighbour in star[12:]:
   output_f.write('<p>' + neighbour[0] + " at " + str(neighbour[1])[0:4] + "ly</p>\n")
  output_f.write('</br>\n')
  del distance_from_sol
 output_f.write('</body></html>\n')
 output_f.close()

if __name__ == '__main__':
 import sys
 if len(sys.argv) > 1:
  main(sys.argv[1])
 else:
  main('Raw Star Data.csv')

Formatting isn’t great but you get the idea…

The one problem with this… One of the many problems with this, is that the txt file it produces is about 600 pages long if I do it for stars with 100 ly of Sol.  Which is a wonderful academic astronomical resource, but not as useful as a practical 2300AD astrogation resource.  So we need to trim out the stars that we can’t possibly reach using a 7.7 ly stutterwarp.  First step is to remove all the stars which have no other star within 7.7 ly, because they are obviously inaccessible.  Next and more difficult step is to trim out the stars that have no route to Sol, which is more difficult and computationally intensive, but it occurs to me that if I start near Sol, and store the routes as I find them, then all I need to do is find a connection to a star that is already on a route and I know that it must connect to Sol.