CNSH - Calculate the Observer's Position Using Saint-Hilaire's Method
Description: The program calculates the latitude and longitude of the observer's position from two sights, either simultaneous (\(DMG = 0\)) or as a running fix (\(DMG > 0\)), using Saint-Hilaire's method.
Inputs:
| DR Lat | The DR latitude of the observer |
| DR Lon | The DR longitude of the observer |
| GHA sight 1 | GHA of the celestial object from sight 1 |
| Dec sight 1 | Declination of the celestial object from sight 1 |
| Ho sight 1 | Height/Altitude of the celestial object from sight 1 |
| DMG | Distance made good between sights 1 and 2 (running fix) |
| CMG | Course made good between sights (\(DMG > 0\)) |
| GHA sight 2 | GHA of the celestial object from sight 2 |
| Dec sight 2 | Declination of the celestial object from sight 2 |
| Ho sight 2 | Height/Altitude of the celestial object from sight 2 |
Outputs:
| Lat | The calculated latitude of the observer |
| Lon | The calculated longitude of the observer |
Sample execution:
DR Lat? 38,30 DR Lon? -30,0 GHA sight 1? 13,22 Dec sight 1? 20,03.3 Ho sight 1? 66,49.2 DMG? 30 CMG? 25 GHA sight 2? 43,22 Dec sight 2? 20,02.3 Ho sight 2? 67,11 Lat = 39° 12.5' Lon = -28° 59.4'
(For explanation of notation, conventions etc, see python-programs).
Copyright (C) 2024 Ian Staniforth
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
https://www.gnu.org/licenses/.
# CNSH - Calculate a fix from 2 Sights using Saint-Hilaire's Method
from math import *
from CN_LIB import *
lat = stod("DR Lat? ")
lon = stod("DR Lon? ")
# First sight
gha1 = stod("GHA sight 1? ")
dec1 = stod("Dec sight 1? ")
ho1 = stod("Ho sight 1? ")
lha1 = (gha1+lon+360)%360
hc1 = aSin(Sin(lat)*Sin(dec1)+Cos(lat)*Cos(dec1)*Cos(lha1))
z1 = aCos((Sin(dec1)-Sin(hc1)*Sin(lat))/(Cos(hc1)*Cos(lat)))
zn1 = 360-z1 if lha1 <= 180 else z1
intercept1 = ho1-hc1
dlat1 = intercept1*Cos(zn1)
dlon1 = intercept1*Sin(zn1)/Cos(lat)
lat1 = lat+dlat1
lon1 = lon+dlon1
# Running fix?
dmg = float(input("DMG? "))
if (dmg > 0):
cmg = stod("CMG? ")
rfdlat = dmg*Cos(cmg)/60
rfdlon = dmg*Sin(cmg)/Cos(lat)/60
lat1 = lat1+rfdlat
lon1 = lon1+rfdlon
# Second sight
gha2 = stod("GHA sight 2? ")
dec2 = stod("Dec sight 2? ")
ho2 = stod("Ho sight 2? ")
lha2 = (gha2+lon1+360)%360
hc2 = aSin(Sin(lat1)*Sin(dec2)+Cos(lat1)*Cos(dec2)*Cos(lha2))
z2 = aCos((Sin(dec2)-Sin(hc2)*Sin(lat1))/(Cos(hc2)*Cos(lat1)))
zn2 = 360-z2 if lha2 <= 180 else z2
intercept2 = ho2-hc2
# Calculate position P
theta = zn1-zn2
ep = intercept2/Sin(theta)
phi = zn1-90
dlat2 = ep*Cos(phi)
dlon2 = ep*Sin(phi)/Cos(lat1)
lat2 = lat1+dlat2
lon2 = lon1+dlon2
print("")
print("Lat = "+dtos(lat2))
print("Lon = "+dtos(lon2))