Module:HostStars: Difference between revisions

From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs)
No edit summary
NewZimiaGov (talk | contribs)
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
---------------------------------------------------------
---------------------------------------------------------
-- Module: HostStars_AccurateMap
-- Module: HostStarsBySeason
-- Tries a more "chart-based" star logic for top image,
-- Purpose: Provide a function "starsForTonight" that:
-- focusing on whether each star is visible at midnight
--   • uses dayOfYear in [1..183]
-- from Vaeringheim (~44°N) on a given day-of-year.
--   • identifies Atosiel (1..61), Thalassiel (62..122), Opsitheiel (123..183)
--
--   • checks circumpolar status vs. observer lat (49°N)
-- * Some stars become circumpolar if star-lat >= 46°.
--   • uses a star-lat-based "peak day" approach for seasonal visibility
-- * Others have a sine-based season: visible ~ half the year.
--   • displays star name, star class, star latitude, season, circumpolar, visible, note
---------------------------------------------------------
---------------------------------------------------------


Line 12: Line 12:


---------------------------------------------------------
---------------------------------------------------------
-- 1. dayOfYear (Micras-based):
-- 1. dayOfYear (Micras-based, 183-day year)
--    183-day orbit, epoch = 6 Aug 1999 => day=0
---------------------------------------------------------
---------------------------------------------------------
local function getDayOfYearForPSSC()
local function getDayOfYearForPSSC()
Line 23: Line 22:
     local totalDays  = math.floor((currentTime - startDate) / secPerDay)
     local totalDays  = math.floor((currentTime - startDate) / secPerDay)


     local fracYear = totalDays / daysPerYear
     local fractionYear= totalDays / daysPerYear
     local psscYear= math.floor(fracYear)
     local psscYear   = math.floor(fractionYear)
     local dayOfYear= math.floor((fracYear-psscYear)*daysPerYear) + 1
     local dayOfYear   = math.floor((fractionYear - psscYear) * daysPerYear) + 1
     return dayOfYear
     return dayOfYear
end
end


---------------------------------------------------------
---------------------------------------------------------
-- 2. Our star data (N. hemisphere top image).
-- 2. Identify which season we are in
--    We'll keep a "latitude" (really 'declination'-like).
--    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 = {
local starDataNorth = {
Line 64: Line 79:


---------------------------------------------------------
---------------------------------------------------------
-- 3. Our location: Vaeringheim ~44°N
-- 4. Our location: Vaeringheim ~49°N
---------------------------------------------------------
---------------------------------------------------------
local observerLat = 44
local observerLat = 49


---------------------------------------------------------
---------------------------------------------------------
-- 4. Check "circumpolar?"
-- 5. Check circumpolar:
--    For star-lat >= (90 - observerLat)=46 => circumpolar
--    if starLat >= (90 - observerLat) => circumpolar
---------------------------------------------------------
---------------------------------------------------------
local function isCircumpolar(starLat)
local function isCircumpolar(starLat)
     local limit = 90 - observerLat
     local limit = 90 - observerLat -- e.g. 41
     return (starLat >= limit)
     return (starLat >= limit)
end
end


---------------------------------------------------------
---------------------------------------------------------
-- 5. For non-circumpolar stars, we do a "season window" logic:
-- 6. Star "peak day" approach for seasonal window
--    We'll define star "peak visibility" day = some function of lat.
--    Then we define it visible for ~ half the year around that peak.
---------------------------------------------------------
---------------------------------------------------------
local function isStarUpAtMidnight(starLat, dayOfYear)
local function isStarUpAtMidnight(starLat, dayOfYear, halfWindow)
     -- let "peak" day = 10 * starLat mod 183 (some made-up formula)
     -- define star's peak day
    -- or let's do simpler: starLat*2 => wrap mod 183
     local peakDay = (starLat * 2) % 183
     local peakDay = (starLat*2) % 183


    -- we define "visible range" ~ +/- 45 days from peak => 90 days total
    -- that means about half the year. Tweak as desired
    local halfWindow = 45
    -- difference in dayOfYear
     local diff = dayOfYear - peakDay
     local diff = dayOfYear - peakDay
    -- wrap around 183 => we want minimal cyc mod 183
     diff = (diff + 183) % 183  -- wrap around
     diff = (diff + 183) % 183  -- ensures in [0..182]
     if diff > 91.5 then
     if diff>91.5 then  
         diff = 183 - diff
         diff = 183 - diff   -- symmetrical
     end
     end
     return (diff <= halfWindow)
     return (diff <= halfWindow)
end
end


---------------------------------------------------------
---------------------------------------------------------
-- 6. Build the table
-- 7. MAIN: starsForTonight
--    Output a table with star name, class, lat, season, circumpolar, etc.
---------------------------------------------------------
---------------------------------------------------------
function p.starsForMidnight(frame)
function p.starsForTonight(frame)
     local dayOfYear = getDayOfYearForPSSC()
     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 = {}
     local out = {}
     table.insert(out, "=== Stars Visible at Midnight in Vaeringheim (44°N) ===\n")
     table.insert(out, "=== Stars Visible at Midnight in Vaeringheim (49°N) ===\n")
     table.insert(out, string.format("''Day %d of Micras Year (183 days)''\n\n", dayOfYear))
     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 !! Star Class !! Circumpolar? !! Visible at 00:00? !! Note\n")
     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 circ = isCircumpolar(star.lat)
         local isUp
         local visible
         local note=""
         local note


         if circ then
         if circ then
             isUp = true
             visible = "Yes"
             note="Circumpolar => always above horizon"
             note   = "Circumpolar"
         else
         else
             local val = isStarUpAtMidnight(star.lat, dayOfYear)
             local isUp = isStarUpAtMidnight(star.lat, dayOfYear, halfWin)
             isUp = val
             visible = isUp and "Yes" or "No"
             note="Season-based ~ half-year window"
             note   = string.format("Seasonal window (±%d days from peak)", halfWin)
         end
         end


         local circStr = circ and "Yes" or "No"
         local circStr = circ and "Yes" or "No"
        local upStr  = isUp and "Yes" or "No"


         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, circStr, upStr, note
            "| %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