×
Einen neuen Artikel erstellen
Schreibe den Seitennamen hierhin:
Wir haben derzeit 9.055 Artikel auf Vaultpedia. Gib deinen Artikelnamen oberhalb von oder klicke auf einen der unten stehenden Titel und beginne zu schreiben! ein



    Vaultpedia
    9.055Artikel
    Tritt unserem Discord bei und informiere dich auf unserem Twitter-Kanal über die aktuellsten Themen rund um Fallout!

    Die Dokumentation für dieses Modul kann unter Modul:CurveTable/Doku erstellt werden

    local p = {}
    
    -- Parses a string of the format `x,y` with numerical `x` and `y` into an array with named numbers `x` and `y`.
    function parsePoint(string)
        local stringArray = mw.text.split(string, ",")
    
        local point = {}
        point["x"] = tonumber(stringArray[1])
        point["y"] = tonumber(stringArray[2])
    
        return point
    end
    
    -- Rounds `value` according to the type of rounding indicated by `mode`.
    function round(mode, value)
            if mode == "ceil"    then return math.ceil(value)
        elseif mode == "floor"   then return math.floor(value)
        elseif mode == "trunc"   then return value >= 0 and math.floor(value - 0.5) or math.ceil(value + 0.5)
        elseif mode == "nearest" then return math.floor(value + 0.5)
                                 else return value
        end
    end
    
    -- Interpolates (or extrapolates) the x-coordinate `c` based on points `a` and `b`.
    function interpolatePoint(a, b, c)
        return a["y"] + (c - a["x"]) * (b["y"] - a["y"]) / (b["x"] - a["x"])
    end
    
    -- Interpolates (or extrapolates) the x-coordinate `target` in the curve table `curveTable`.
    function interpolate(curveTable, target)
        if #curveTable == 1 then
            -- One point in curve table; interpret as horizontal line
            return parsePoint(curveTable[1])["y"]
        end
    
        -- Find the first point that is greater than `target`
        for i = 1, #curveTable, 1 do
            local point = parsePoint(curveTable[i])
    
            if target == point["x"] then
                -- `target` is on a point in the curve table; no interpolation/extrapolation required
                return point["y"]
            elseif target < point["x"] then
                if i == 1 then
                    -- `target` comes before the first point; extrapolate from first two points in table
                    return interpolatePoint(parsePoint(curveTable[1]), parsePoint(curveTable[2]), target)
                else
                    -- `target` is in between two points; interpolate between current and previous point
                    return interpolatePoint(parsePoint(curveTable[i - 1]), parsePoint(curveTable[i]), target)
                end
            end
        end
    
        -- `target` is after last point. Extrapolate from last two points in table
        return interpolatePoint(parsePoint(curveTable[#curveTable - 1]), parsePoint(curveTable[#curveTable]), target)
    end
    
    -- See documentation at [[Template:CurveTable]].
    function p.evaluate(frame)
        local curveTable = mw.text.split(frame.args[1], " ")
        if #curveTable == 0 then
            -- Empty curve table
            return "Not enough points in curve table."
        end
        
        local target1 = tonumber(frame.args[2])
        return round(frame.args["round"], interpolate(curveTable, target1))
    end
    
    return p