#!/usr/bin/python3
# ===================================================================
# Finding out if a particular star is in the area-of-interest
# (AOI) is a problem. The coordinates (lat/lon) are not consistent
# (lon is 0 to 360 and lat is -90 to +90) and must be "fiddled"
# with in code to overcome this inconsistency.
# -------------------------------------------------------------------
# This code test if a star's lat/lon is in the area-of-interest (AOI)
# a. Pretend the point-of-interest (POI) has been rotated
# until it is on the +Z axes. (-poilat,-poilon)
# b. The AIO is now centered on the new POI (lat=0,lon=0).
# c. The other stars are rotated relative to the new POI
# for testing. (Rotated the same amount as the POI.)
# d. To see if a star is in the AOI, pretend rotate it's lat/lon
# relative to the new POI (and AOI) and test. Is it in or out.
# e. Because of the lat/lon coordinate system are not consistent,
# the calculations will give you "funny" numbers. However,
# you can still test.
# -------------------------------------------------------------------
# The lat/lon coordinate system is inconsistent, but it is
# good for astronomy. (lon is 0 to 360 and lat is -90 to +90)
# ===================================================================
import user_interface as ui
import sys, os, platform
from math import radians, sin, cos
win_width = 801 # graphics window width (pixels)
win_height = 801 # graphics window height (pixels)
min_poi_latitude = -90.0 # degrees
max_poi_latitude = +90.0 # degrees
min_poi_longitude = +0.0 # degrees
max_poi_longitude = +360.0 # degrees
min_poi_size = +2.0 # degrees
max_poi_size = +20.0 # degrees
# -------------------------------------------------------------------
# ---- get user's Point of Interest (POI)
# -------------------------------------------------------------------
def get_user_poi():
ui.clear_screen()
# --- galactic longitude
print()
print('Enter POI galactic longitude in degrees (0.0 to 360.0)')
print('Enter nothing to exit program')
while(True):
print()
s = ui.get_user_input('Enter POI longitude: ')
if not s:
sys.exit()
tf,poilon = ui.is_float(s)
if tf != True or \
poilon < min_poi_longitude or \
poilon > max_poi_longitude:
print('illegal longitude - try again')
continue
break
# ---- poi latitude
print()
print('Enter POI galactic latitude in degrees (-90.0 to +90.0)')
print('Enter nothing to exit program')
while(True):
print()
s = ui.get_user_input('Enter POI Latitude: ')
if not s:
sys.exit()
tf,poilat = ui.is_float(s)
if tf != True or \
poilat < min_poi_latitude or \
poilat > max_poi_latitude:
print()
print('illegal latitude - try again')
continue
break
# ---- poi size
print()
print('Enter POI size in degrees (2.0 > size <= 20.0)')
print('Enter nothing to exit program')
while(True):
print()
s = ui.get_user_input('Enter POI size: ')
if not s:
sys.exit()
tf,poisize = ui.is_float(s)
if tf != True or \
poisize < min_poi_size or \
poisize > max_poi_size:
print()
print('illegal latitude - try again')
continue
break
return (poilat,poilon,poisize)
# -------------------------------------------------------------------
# ---- convert galactic lat/lon to x,y,z coordinates
# ---- (unit vector is radius of sphere)
# -------------------------------------------------------------------
def lat_lon_to_xyz(glat,glon,scale=1.0):
rlat = radians(glat) # convert to radians
rlon = radians(glon) # convert to radians
x = sin(rlat) * cos(rlon)
y = sin(rlat)
z = cos(rlat) * cos(rlon)
return (x*scale, y*scale, z*scale)
# -------------------------------------------------------------------
# ---- rotate a star's lat/lon so it is relative to the POI
# ---- as if the POI were on the +Z axis
# -------------------------------------------------------------------
def rotate_lat_lon_to_z_axis(lat,lon,poilat,poilon):
newlat = lat - poilat
newlon = lon - poilon
print()
print(f'new lat = {newlat}')
print(f'new lon = {newlon}')
return (newlat,newlon)
# -------------------------------------------------------------------
# ---- get lat/lon to test POI rotation
# -------------------------------------------------------------------
def get_test_lat_lon():
while(True):
print()
s = ui.get_user_input('Enter test lon (0 to 360): ')
if not s:
sys.exit()
tf,lon = ui.is_float(s)
if not tf:
print('bad input')
continue
break
while(True):
print()
s = ui.get_user_input('Enter test lat (-90 to +90): ')
if not s:
sys.exit()
tf,lat = ui.is_float(s)
if not tf:
print('bad input')
continue
break
return (lat,lon)
# -------------------------------------------------------------------
# ---- is test lat/lon (star) in area-if-interest AIO
# -------------------------------------------------------------------
def in_area_of_interest(tlat,tlon,poilat,poilon,poisiz):
halfsiz = poisiz / 2.0
aio_min_lat = poilat - halfsiz
aio_max_lat = poilat + halfsiz
aio_min_lon = poilon - halfsiz
aio_max_lon = poilon + hanfsiz
newlat = tlat - poilat
newlon = tlon - poilon
print()
print(f'new lat = {newlat}')
print(f'new lon = {newlon}')
return (newlat,newlon)
# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------
if __name__ == '__main__':
# ---- get the user's point of interest (POI)
poilat,poilon,poisiz = get_user_poi()
# ---- calculate the area-of-interest after rotating
# ---- the POI until it is on the +Z axes
aio_min_lat = -poisiz/2.0 # 1/2 poi size
aio_max_lat = +poisiz/2.0 # 1/2 poi size
aio_min_lon = -poisiz/2.0 # 1/2 poi size
aio_max_lon = +poisiz/2.0 # 1/2 poi size
while(True):
ui.clear_screen()
print()
print(f'POI lon = {poilon}')
print(f'POI lat = {poilat}')
print(f'POI siz = {poisiz}')
print(f'AIO lon = {aio_min_lon:<6} (min)')
print(f'AIO lon = {aio_max_lon:<6} (max)')
print(f'AIO lat = {aio_min_lat:<6} (min)')
print(f'AIP lat = {aio_max_lat:<6} (max)')
tlat,tlon = get_test_lat_lon()
print()
print(f'test lon = {tlon}')
print(f'test lat = {tlat}')
nlat = tlat - poilat # rotate test lat
nlon = tlon - poilon # rotate test lon
print()
print(f'new lon = {nlon}')
print(f'new lat = {nlat}')
x,y,z = lat_lon_to_xyz(nlat,nlon)
xx = x * 100.0 # scale X coordinate
yy = y * 100.0 # scale Y coordinate
zz = z * 100.0 # scale Z coordinate
print()
print(f'new x = {round(xx,2)}')
print(f'new y = {round(yy,2)}')
print(f'new z = {round(zz,2)}')
# ---- test if the rotated test lat/lon (newlat,newlon)
# ---- in the area-of-interest?
print()
if nlon < aio_min_lon or nlon > aio_max_lon or \
nlat < aio_min_lat or nlon > aio_max_lat:
print('NOT in area of interest')
else:
print('in area of interest')
ui.pause()