最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

lua - Is it possible to create the algorithm in the table with code? - Stack Overflow

programmeradmin0浏览0评论

Below is a table of RGB color codes.

When I use this table in a form with lua code, I create a 13*9 color tone panel. Is it possible to create a code that creates the same algorithm (color codes) without using the table (or based on the first row of 13 colors)?

local clrtbl = { 0x000033,0x001933,0x003333,0x003319,0x003300,0x193300,0x333300,0x331900,0x330000,0x330019,0x330033,0x190033,0x000000, 0x000066,0x003366,0x006666,0x006633,0x006600,0x336600,0x666600,0x663300,0x660000,0x660033,0x660066,0x330066,0x202020, 0x000099,0x004C99,0x009999,0x00994C,0x009900,0x4C9900,0x999900,0x994C00,0x990000,0x99004C,0x990099,0x4C0099,0x404040, 0x0000CC,0x0066CC,0x00CCCC,0x00CC66,0x00CC00,0x66CC00,0xCCCC00,0xCC6600,0xCC0000,0xCC0066,0xCC00CC,0x6600CC,0x606060, 0x0000FF,0x0080FF,0x00FFFF,0x00FF80,0x00FF00,0x80FF00,0xFFFF00,0xFF8000,0xFF0000,0xFF007F,0xFF00FF,0x7F00FF,0x808080, 0x3333FF,0x3399FF,0x33FFFF,0x33FF99,0x33FF33,0x99FF33,0xFFFF33,0xFF9933,0xFF3333,0xFF3399,0xFF33FF,0x9933FF,0xA0A0A0, 0x6666FF,0x66B2FF,0x66FFFF,0x66FFB2,0x66FF66,0xB2FF66,0xFFFF66,0xFFB266,0xFF6666,0xFF66B2,0xFF66FF,0xB266FF,0xC0C0C0, 0x9999FF,0x99CCFF,0x99FFFF,0x99FFCC,0x99FF99,0xCCFF99,0xFFFF99,0xFFCC99,0xFF9999,0xFF99CC,0xFF99FF,0xCC99FF,0xE0E0E0, 0xCCCCFF,0xCCE5FF,0xCCFFFF,0xCCFFE5,0xCCFFCC,0xE5FFCC,0xFFFFCC,0xFFE5CC,0xFFCCCC,0xFFCCE5,0xFFCCFF,0xE5CCFF,0xFFFFFF}

The color palette that the table creates.

This algorithm table creates 13 colors from left to right, 9 tones from top to bottom. When considered in this context, it appears to be arranged with a certain symmetry. The final output is clear in the picture. How can we solve this?
I have added a calculation code below. But it doesn't even come close to my table list. My goal is to make a function that generates the same algorithm (RGB hex codes that generate color tones) with lua code, without using the table.

EDIT: I think the closest I could get to the result by taking 2 rows (26 color tones) from the table is as follows:

local base_colors = {0x000033, 0x001933, 0x003333, 0x003319, 0x003300, 0x193300, 0x333300, 0x331900, 0x330000, 0x330019, 0x330033, 0x190033, 0x000000}

local special_colors = {0x0000FF, 0x0080FF, 0x00FFFF, 0x00FF80, 0x00FF00, 0x80FF00, 0xFFFF00, 0xFF8000, 0xFF0000, 0xFF007F, 0xFF00FF, 0x7F00FF, 0xFFFFFF}

local function calculate_shades(base_color)
    local shades = {}
    local step = 0x22

    for i = 0, 7 do
        local red = ((base_color // 0x10000) & 0xFF)
        local green = ((base_color // 0x100) & 0xFF)
        local blue = (base_color & 0xFF)

        red = math.min(255, red + i * step)
        green = math.min(255, green + i * step)
        blue = math.min(255, blue + i * step)

        local shade = (red << 16) + (green << 8) + blue
        shades[#shades + 1] = shade
    end

    table.insert(shades, base_color)
    return shades
end

local function generate_color_table(base_colors, special_colors)
    local color_table = {}
    local special_index = 1
    for base_index, base_color in ipairs(base_colors) do
        local shades = calculate_shades(base_color)
        for shade_index, shade in ipairs(shades) do
            if (base_index - 1) * 9 + shade_index == special_index * 9 then
                table.insert(color_table, special_colors[special_index])
                special_index = special_index + 1
            else
                table.insert(color_table, shade)
            end
        end
    end
    return color_table
end

local result = "newClrTbl = {"

local color_table = generate_color_table(base_colors, special_colors)
for i = 1, #color_table do
    if i == #color_table then
        result = result .. (string.format("0x%06X", color_table[i]))
    else
        result = result .. (string.format("0x%06X,", color_table[i]))
    end
end

print(result.."}")

Panel with the last edited code output

There still seems to be a lot of code waste. Is there a code that can do this algorithm without using a table and based on the color tones in the main table?

Below is a table of RGB color codes.

When I use this table in a form with lua code, I create a 13*9 color tone panel. Is it possible to create a code that creates the same algorithm (color codes) without using the table (or based on the first row of 13 colors)?

local clrtbl = { 0x000033,0x001933,0x003333,0x003319,0x003300,0x193300,0x333300,0x331900,0x330000,0x330019,0x330033,0x190033,0x000000, 0x000066,0x003366,0x006666,0x006633,0x006600,0x336600,0x666600,0x663300,0x660000,0x660033,0x660066,0x330066,0x202020, 0x000099,0x004C99,0x009999,0x00994C,0x009900,0x4C9900,0x999900,0x994C00,0x990000,0x99004C,0x990099,0x4C0099,0x404040, 0x0000CC,0x0066CC,0x00CCCC,0x00CC66,0x00CC00,0x66CC00,0xCCCC00,0xCC6600,0xCC0000,0xCC0066,0xCC00CC,0x6600CC,0x606060, 0x0000FF,0x0080FF,0x00FFFF,0x00FF80,0x00FF00,0x80FF00,0xFFFF00,0xFF8000,0xFF0000,0xFF007F,0xFF00FF,0x7F00FF,0x808080, 0x3333FF,0x3399FF,0x33FFFF,0x33FF99,0x33FF33,0x99FF33,0xFFFF33,0xFF9933,0xFF3333,0xFF3399,0xFF33FF,0x9933FF,0xA0A0A0, 0x6666FF,0x66B2FF,0x66FFFF,0x66FFB2,0x66FF66,0xB2FF66,0xFFFF66,0xFFB266,0xFF6666,0xFF66B2,0xFF66FF,0xB266FF,0xC0C0C0, 0x9999FF,0x99CCFF,0x99FFFF,0x99FFCC,0x99FF99,0xCCFF99,0xFFFF99,0xFFCC99,0xFF9999,0xFF99CC,0xFF99FF,0xCC99FF,0xE0E0E0, 0xCCCCFF,0xCCE5FF,0xCCFFFF,0xCCFFE5,0xCCFFCC,0xE5FFCC,0xFFFFCC,0xFFE5CC,0xFFCCCC,0xFFCCE5,0xFFCCFF,0xE5CCFF,0xFFFFFF}

The color palette that the table creates.

This algorithm table creates 13 colors from left to right, 9 tones from top to bottom. When considered in this context, it appears to be arranged with a certain symmetry. The final output is clear in the picture. How can we solve this?
I have added a calculation code below. But it doesn't even come close to my table list. My goal is to make a function that generates the same algorithm (RGB hex codes that generate color tones) with lua code, without using the table.

EDIT: I think the closest I could get to the result by taking 2 rows (26 color tones) from the table is as follows:

local base_colors = {0x000033, 0x001933, 0x003333, 0x003319, 0x003300, 0x193300, 0x333300, 0x331900, 0x330000, 0x330019, 0x330033, 0x190033, 0x000000}

local special_colors = {0x0000FF, 0x0080FF, 0x00FFFF, 0x00FF80, 0x00FF00, 0x80FF00, 0xFFFF00, 0xFF8000, 0xFF0000, 0xFF007F, 0xFF00FF, 0x7F00FF, 0xFFFFFF}

local function calculate_shades(base_color)
    local shades = {}
    local step = 0x22

    for i = 0, 7 do
        local red = ((base_color // 0x10000) & 0xFF)
        local green = ((base_color // 0x100) & 0xFF)
        local blue = (base_color & 0xFF)

        red = math.min(255, red + i * step)
        green = math.min(255, green + i * step)
        blue = math.min(255, blue + i * step)

        local shade = (red << 16) + (green << 8) + blue
        shades[#shades + 1] = shade
    end

    table.insert(shades, base_color)
    return shades
end

local function generate_color_table(base_colors, special_colors)
    local color_table = {}
    local special_index = 1
    for base_index, base_color in ipairs(base_colors) do
        local shades = calculate_shades(base_color)
        for shade_index, shade in ipairs(shades) do
            if (base_index - 1) * 9 + shade_index == special_index * 9 then
                table.insert(color_table, special_colors[special_index])
                special_index = special_index + 1
            else
                table.insert(color_table, shade)
            end
        end
    end
    return color_table
end

local result = "newClrTbl = {"

local color_table = generate_color_table(base_colors, special_colors)
for i = 1, #color_table do
    if i == #color_table then
        result = result .. (string.format("0x%06X", color_table[i]))
    else
        result = result .. (string.format("0x%06X,", color_table[i]))
    end
end

print(result.."}")

Panel with the last edited code output

There still seems to be a lot of code waste. Is there a code that can do this algorithm without using a table and based on the color tones in the main table?

Share Improve this question edited Mar 6 at 18:54 A_CE asked Mar 6 at 15:16 A_CEA_CE 231 silver badge9 bronze badges 3
  • Your algorithm is wrong. Very roughly for i = 0, 5 shade = base_colour*i and then it adds a shade of grey to each colour for i=6, 8 shade = base_colour + 0x333333 using bytewise saturated arithmetic so that overflows do not propogate into adjacent colours. – Martin Brown Commented Mar 6 at 17:44
  • I updated the question and added the final coding I came up with. I'm confused as to how I can do it with less space and without using tables. – A_CE Commented Mar 6 at 18:56
  • The palette that you linked is not the one that is created by clrtbl. The former starts from redish coliurs, the latter, with blueish. – Alexander Mashin Commented Mar 8 at 11:16
Add a comment  | 

1 Answer 1

Reset to default 2

The following code generates a palette as a two-dimentional Lua table:

local abs, floor = math.abs, math.floor

-- https://www.rapidtables/convert/color/hsv-to-rgb.html
local function hsv2rgb (h, s, v)
    local c = s * v
    local x = c * (1 - abs ((h / 60) % 2 - 1))
    local m = v - c
    local cases = {
        { c, x, 0 }, -- h ∈ [0°; 60°)
        { x, c, 0 }, -- h ∈ [60°; 120°)
        { 0, c, x }, -- h ∈ [120°; 180°)
        { 0, x, c }, -- h ∈ [180°; 240°)
        { x, 0, c }, -- h ∈ [240°; 300°)
        { c, 0, x }  -- h ∈ [300°; 360°)
    }
    local rgb = {}
    for _, colour in ipairs (cases [floor (h / 60) + 1]) do
        rgb [#rgb + 1] = (colour + m) * 255
    end
    return rgb
end

local function palette (v_start, v_end, v_step, h_start, h_step)
    local h_steps = floor (360 / abs (h_step))
    local plt = {}
    for v = v_start, v_end, v_step do
        local gray = (v - v_start) / (v_end - v_start)
        local s = 1
        -- Excessive brightness reduces saturation:
        if v > 1 then
            s = s - (v - 1)
            v = 1
        end
        local row = {}
        for h = h_start, h_start + h_step * (h_steps - 1), h_step do
            row [#row + 1] = hsv2rgb (h % 360, s, v)
        end
        -- Grays:
        row [#row + 1] = hsv2rgb (0, 0, gray)
        plt [#plt + 1] = row
    end
    return plt
end

local as_linked = palette (0.2, 1.8, 0.2, 0, 30)
local as_in_clrtbl = palette (0.2, 1.8, 0.2, 240, -30)

The idea is that all colours in one column have the same hue; and all rows, the same brightness, and when it reaches 100%, saturation will begin to reduce. Then the colour's HSV coordinates are converted to RGB by hsv2rgb(). The gray column is produced by a special rule, with increasing brightness.

palette() gets parametres:

  • v_start — brightness of the top row; in [0; 1],
  • v_end — brightness of the bottom row; in [0; 1],
  • v_step — brightness increment; in (0, 1],
  • h_start — hue of the first column; in [0, 360), 0 meaning red, 180, cyan,
  • h_step — hue increment; in (-360, 360), positive meaning red to violet, negative, violet to red.

palette (0.2, 1.8, 0.2, 0, 30) will produce approximately the table that you linked.

palette (0.2, 1.8, 0.2, 240, -30) will produce the table defined by clrtbl.

This page shows different variants of the generated palette. Cells' background is the generated color; the colour of the circle is the corresponding colour from clrtbl. The upper left or right is approximately what is linked, the bottom left is exactly clrtbl.

发布评论

评论列表(0)

  1. 暂无评论