Module:HostStars: Difference between revisions
From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs) Created page with "--------------------------------------------------------- -- Module: HostStars_Midnight -- Purpose: Provide a "starsForTonight" function that: -- 1) Uses Micras' 183-day orbit, 24-hour day, 22.5° tilt, -- 2) Approximates day length (~9..15 hours) with a sine wave, -- 3) Assigns random star rise/set times within the night, -- 4) Checks if each star is visible at EXACTLY midnight (00:00). -- -- Usage: -- {{#invoke:HostStars_Midnight|starsForTonight}} -----------..." |
NewZimiaGov (talk | contribs) No edit summary |
||
| (3 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- Module: | -- Module: HostStarsBySeason | ||
-- Purpose: Provide a "starsForTonight" | -- Purpose: Provide a function "starsForTonight" that: | ||
-- 1 | -- • uses dayOfYear in [1..183] | ||
-- | -- • identifies Atosiel (1..61), Thalassiel (62..122), Opsitheiel (123..183) | ||
-- | -- • checks circumpolar status vs. observer lat (49°N) | ||
-- | -- • uses a star-lat-based "peak day" approach for seasonal visibility | ||
-- | -- • displays star name, star class, star latitude, season, circumpolar, visible, note | ||
-- | |||
--------------------------------------------------------- | --------------------------------------------------------- | ||
| Line 14: | Line 12: | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- 1. dayOfYear (Micras-based | -- 1. dayOfYear (Micras-based, 183-day year) | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
local function getDayOfYearForPSSC() | local function getDayOfYearForPSSC() | ||
local startDate = os.time({year = 1999, month = 8, day = 6}) | local startDate = os.time({year=1999, month=8, day=6}) | ||
local secPerDay = 86400 | local secPerDay = 86400 | ||
local daysPerYear = 183 | local daysPerYear = 183 | ||
| Line 25: | Line 22: | ||
local totalDays = math.floor((currentTime - startDate) / secPerDay) | local totalDays = math.floor((currentTime - startDate) / secPerDay) | ||
local fractionYear= totalDays / daysPerYear | |||
local | local psscYear = math.floor(fractionYear) | ||
local psscYear = math.floor( | local dayOfYear = math.floor((fractionYear - psscYear) * daysPerYear) + 1 | ||
local dayOfYear = math.floor(( | |||
return dayOfYear | return dayOfYear | ||
end | end | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- 2. | -- 2. Identify which season we are in | ||
-- | -- Atosiel = days 1..61 | ||
-- Thalassiel= days 62..122 | |||
-- | -- Opsitheiel= days 123..183 | ||
-- | |||
--------------------------------------------------------- | --------------------------------------------------------- | ||
local function | local function getSeasonName(dayOfYear) | ||
if dayOfYear <= 61 then | |||
return "Atosiel" | |||
elseif dayOfYear <= 122 then | |||
return "Thalassiel" | |||
else | |||
return "Opsitheiel" | |||
end | |||
end | end | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- 3. Star | -- 3. Star data (northern hemisphere top chart), | ||
-- lat = approximate "declination" from star map | |||
--------------------------------------------------------- | --------------------------------------------------------- | ||
local starDataNorth = { | local starDataNorth = { | ||
{ name="Agave", starClass="M", | { name="Agave", starClass="M", lat=29.5 }, | ||
{ name="Amaäz", starClass="K", | { name="Amaäz", starClass="K", lat=31 }, | ||
{ name="Amáenu", starClass="G", | { name="Amáenu", starClass="G", lat=45 }, | ||
{ name="Amap", starClass="A", | { name="Amap", starClass="A", lat=55 }, | ||
{ name="Amazä", starClass="F", | { name="Amazä", starClass="F", lat=39 }, | ||
{ name="Atämios", starClass="F", | { name="Atämios", starClass="F", lat=56 }, | ||
{ name="Aprobelle", starClass="A", | { name="Aprobelle", starClass="A", lat=59 }, | ||
{ name="Azos", starClass="Galaxy", | { name="Azos", starClass="Galaxy", lat=60 }, | ||
{ name="Bebeakaus", starClass="K", | { name="Bebeakaus", starClass="K", lat=30.5 }, | ||
{ name="Bulhanu", starClass="A", | { name="Bulhanu", starClass="A", lat=40 }, | ||
{ name="Crösacío", starClass="K", | { name="Crösacío", starClass="K", lat=17 }, | ||
{ name="Danaß", starClass="A", | { name="Danaß", starClass="A", lat=67 }, | ||
{ name="Dilëtaz", starClass="G", | { name="Dilëtaz", starClass="G", lat=36 }, | ||
{ name="Dranamos", starClass="A", | { name="Dranamos", starClass="A", lat=58 }, | ||
{ name="Gaht", starClass="G", | { name="Gaht", starClass="G", lat=29 }, | ||
{ name="Häpi", starClass="F", | { name="Häpi", starClass="F", lat=78 }, | ||
{ name="Hazaméos", starClass="A", | { name="Hazaméos", starClass="A", lat=72 }, | ||
{ name="Liléigos", starClass="F", | { name="Liléigos", starClass="F", lat=18 }, | ||
{ name="Nyama", starClass="F", | { name="Nyama", starClass="F", lat=64 }, | ||
{ name="Ocananus", starClass="F", | { name="Ocananus", starClass="F", lat=60.5 }, | ||
{ name="Orebele", starClass="F", | { name="Orebele", starClass="F", lat=22 }, | ||
{ name="Osiríos", starClass="G", | { name="Osiríos", starClass="G", lat=53 }, | ||
{ name="Pythe", starClass="A", | { name="Pythe", starClass="A", lat=45 }, | ||
{ name="Sanashalo", starClass="G", | { name="Sanashalo", starClass="G", lat=27 }, | ||
{ name="Tä", starClass="F", | { name="Tä", starClass="F", lat=39.5 }, | ||
{ name="Vï", starClass="A", | { name="Vï", starClass="A", lat=46 }, | ||
{ name="Wedíos", starClass="A", | { name="Wedíos", starClass="A", lat=54 }, | ||
} | } | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- 4. | -- 4. Our location: Vaeringheim ~49°N | ||
--------------------------------------------------------- | |||
local observerLat = 49 | |||
--------------------------------------------------------- | |||
-- 5. Check circumpolar: | |||
-- if starLat >= (90 - observerLat) => circumpolar | |||
--------------------------------------------------------- | --------------------------------------------------------- | ||
local function | local function isCircumpolar(starLat) | ||
local | local limit = 90 - observerLat -- e.g. 41 | ||
return (starLat >= limit) | |||
return | |||
end | end | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
-- | -- 6. Star "peak day" approach for seasonal window | ||
--------------------------------------------------------- | --------------------------------------------------------- | ||
function | local function isStarUpAtMidnight(starLat, dayOfYear, halfWindow) | ||
-- define star's peak day | |||
local | local peakDay = (starLat * 2) % 183 | ||
local | local diff = dayOfYear - peakDay | ||
diff = (diff + 183) % 183 -- wrap around | |||
if diff > 91.5 then | |||
diff = 183 - diff | |||
end | |||
return (diff <= halfWindow) | |||
end | |||
--------------------------------------------------------- | |||
-- 7. MAIN: starsForTonight | |||
local | -- Output a table with star name, class, lat, season, circumpolar, etc. | ||
local | --------------------------------------------------------- | ||
function p.starsForTonight(frame) | |||
local dayOfYear = getDayOfYearForPSSC() | |||
local seasonName = getSeasonName(dayOfYear) | |||
-- | --------------------------------------------------------- | ||
local | -- halfWindow: different widths in different seasons | ||
-- tweak as you like | |||
--------------------------------------------------------- | |||
local halfWin | |||
if seasonName == "Atosiel" then | |||
halfWin = 45 | |||
elseif seasonName == "Thalassiel" then | |||
halfWin = 40 | |||
else | |||
halfWin = 50 | |||
end | |||
local out = {} | local out = {} | ||
table.insert(out, "=== | table.insert(out, "=== Stars Visible at Midnight in Vaeringheim (49°N) ===\n") | ||
table.insert(out, string.format( | table.insert(out, string.format("Day %d of Micras year (Season: %s)\n\n", dayOfYear, seasonName)) | ||
table.insert(out, '{| class="wikitable" style="width:100%; text-align:left;"\n') | table.insert(out, '{| class="wikitable" style="width:100%; text-align:left;"\n') | ||
table.insert(out, "! Star Name | table.insert(out, | ||
"! Star Name !! Star Class !! Star Latitude !! Season !! Circumpolar !! Visibility at Midnight !! Note\n" | |||
) | |||
for _, star in ipairs(starDataNorth) do | for _, star in ipairs(starDataNorth) do | ||
local circ = isCircumpolar(star.lat) | |||
local visible | |||
local note | |||
local | |||
if circ then | |||
local | visible = "Yes" | ||
note = "Circumpolar" | |||
else | |||
local isUp = isStarUpAtMidnight(star.lat, dayOfYear, halfWin) | |||
visible = isUp and "Yes" or "No" | |||
note = string.format("Seasonal window (±%d days from peak)", halfWin) | |||
end | end | ||
local circStr = circ and "Yes" or "No" | |||
local | |||
table.insert(out, "|-\n") | table.insert(out, "|-\n") | ||
table.insert(out, string.format("| %s || %s || %s || %s || %s\n", | table.insert(out, string.format( | ||
star.name, star.starClass, | "| %s || %s || %.1f°N || %s || %s || %s || %s\n", | ||
star.name, | |||
star.starClass, | |||
star.lat, | |||
seasonName, | |||
circStr, | |||
visible, | |||
note | |||
)) | |||
end | end | ||
table.insert(out, "|}\n") | table.insert(out, "|}\n") | ||
return table.concat(out) | return table.concat(out) | ||
end | end | ||
return p | return p | ||
Latest revision as of 17:01, 27 December 2024
Documentation for this module may be created at Module:HostStars/doc
---------------------------------------------------------
-- Module: HostStarsBySeason
-- Purpose: Provide a function "starsForTonight" that:
-- • uses dayOfYear in [1..183]
-- • identifies Atosiel (1..61), Thalassiel (62..122), Opsitheiel (123..183)
-- • checks circumpolar status vs. observer lat (49°N)
-- • uses a star-lat-based "peak day" approach for seasonal visibility
-- • displays star name, star class, star latitude, season, circumpolar, visible, note
---------------------------------------------------------
local p = {}
---------------------------------------------------------
-- 1. dayOfYear (Micras-based, 183-day year)
---------------------------------------------------------
local function getDayOfYearForPSSC()
local startDate = os.time({year=1999, month=8, day=6})
local secPerDay = 86400
local daysPerYear = 183
local currentTime = os.time()
local totalDays = math.floor((currentTime - startDate) / secPerDay)
local fractionYear= totalDays / daysPerYear
local psscYear = math.floor(fractionYear)
local dayOfYear = math.floor((fractionYear - psscYear) * daysPerYear) + 1
return dayOfYear
end
---------------------------------------------------------
-- 2. Identify which season we are in
-- Atosiel = days 1..61
-- Thalassiel= days 62..122
-- Opsitheiel= days 123..183
---------------------------------------------------------
local function getSeasonName(dayOfYear)
if dayOfYear <= 61 then
return "Atosiel"
elseif dayOfYear <= 122 then
return "Thalassiel"
else
return "Opsitheiel"
end
end
---------------------------------------------------------
-- 3. Star data (northern hemisphere top chart),
-- lat = approximate "declination" from star map
---------------------------------------------------------
local starDataNorth = {
{ name="Agave", starClass="M", lat=29.5 },
{ name="Amaäz", starClass="K", lat=31 },
{ name="Amáenu", starClass="G", lat=45 },
{ name="Amap", starClass="A", lat=55 },
{ name="Amazä", starClass="F", lat=39 },
{ name="Atämios", starClass="F", lat=56 },
{ name="Aprobelle", starClass="A", lat=59 },
{ name="Azos", starClass="Galaxy", lat=60 },
{ name="Bebeakaus", starClass="K", lat=30.5 },
{ name="Bulhanu", starClass="A", lat=40 },
{ name="Crösacío", starClass="K", lat=17 },
{ name="Danaß", starClass="A", lat=67 },
{ name="Dilëtaz", starClass="G", lat=36 },
{ name="Dranamos", starClass="A", lat=58 },
{ name="Gaht", starClass="G", lat=29 },
{ name="Häpi", starClass="F", lat=78 },
{ name="Hazaméos", starClass="A", lat=72 },
{ name="Liléigos", starClass="F", lat=18 },
{ name="Nyama", starClass="F", lat=64 },
{ name="Ocananus", starClass="F", lat=60.5 },
{ name="Orebele", starClass="F", lat=22 },
{ name="Osiríos", starClass="G", lat=53 },
{ name="Pythe", starClass="A", lat=45 },
{ name="Sanashalo", starClass="G", lat=27 },
{ name="Tä", starClass="F", lat=39.5 },
{ name="Vï", starClass="A", lat=46 },
{ name="Wedíos", starClass="A", lat=54 },
}
---------------------------------------------------------
-- 4. Our location: Vaeringheim ~49°N
---------------------------------------------------------
local observerLat = 49
---------------------------------------------------------
-- 5. Check circumpolar:
-- if starLat >= (90 - observerLat) => circumpolar
---------------------------------------------------------
local function isCircumpolar(starLat)
local limit = 90 - observerLat -- e.g. 41
return (starLat >= limit)
end
---------------------------------------------------------
-- 6. Star "peak day" approach for seasonal window
---------------------------------------------------------
local function isStarUpAtMidnight(starLat, dayOfYear, halfWindow)
-- define star's peak day
local peakDay = (starLat * 2) % 183
local diff = dayOfYear - peakDay
diff = (diff + 183) % 183 -- wrap around
if diff > 91.5 then
diff = 183 - diff
end
return (diff <= halfWindow)
end
---------------------------------------------------------
-- 7. MAIN: starsForTonight
-- Output a table with star name, class, lat, season, circumpolar, etc.
---------------------------------------------------------
function p.starsForTonight(frame)
local dayOfYear = getDayOfYearForPSSC()
local seasonName = getSeasonName(dayOfYear)
---------------------------------------------------------
-- halfWindow: different widths in different seasons
-- tweak as you like
---------------------------------------------------------
local halfWin
if seasonName == "Atosiel" then
halfWin = 45
elseif seasonName == "Thalassiel" then
halfWin = 40
else
halfWin = 50
end
local out = {}
table.insert(out, "=== Stars Visible at Midnight in Vaeringheim (49°N) ===\n")
table.insert(out, string.format("Day %d of Micras year (Season: %s)\n\n", dayOfYear, seasonName))
table.insert(out, '{| class="wikitable" style="width:100%; text-align:left;"\n')
table.insert(out,
"! Star Name !! Star Class !! Star Latitude !! Season !! Circumpolar !! Visibility at Midnight !! Note\n"
)
for _, star in ipairs(starDataNorth) do
local circ = isCircumpolar(star.lat)
local visible
local note
if circ then
visible = "Yes"
note = "Circumpolar"
else
local isUp = isStarUpAtMidnight(star.lat, dayOfYear, halfWin)
visible = isUp and "Yes" or "No"
note = string.format("Seasonal window (±%d days from peak)", halfWin)
end
local circStr = circ and "Yes" or "No"
table.insert(out, "|-\n")
table.insert(out, string.format(
"| %s || %s || %.1f°N || %s || %s || %s || %s\n",
star.name,
star.starClass,
star.lat,
seasonName,
circStr,
visible,
note
))
end
table.insert(out, "|}\n")
return table.concat(out)
end
return p