Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Rainbow Rectangle

edited May 2017 in Code Sharing Posts: 121

It's a rectangle filled with a rainbow. What's not to like?

-- Rainbow Rect

-- Use this function to perform your initial setup
function setup()
    a = rainbow_rect(0,0, WIDTH,HEIGHT)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    a:draw()
    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here

end

-- x,y specify bottom left corner
function rainbow_rect(x,y,w,h)
    local rectangle = mesh()
    local h2,h3,h4,h5 = h*.75,h*.5,h*.25,0
    local verts = {vec2(w,h), vec2(0,h), vec2(0,h2),    -- h is red
                    vec2(w,h), vec2(0,h2), vec2(w,h2),   -- h2 is yellow
                     vec2(w,h2), vec2(0,h2), vec2(0,h3),
                      vec2(w,h2), vec2(0,h3), vec2(w,h3), -- h3 is green
                       vec2(w,h3), vec2(0,h3), vec2(0,h4),
                        vec2(w,h3), vec2(0,h4), vec2(w,h4), -- h4 is blue
                         vec2(w,h4), vec2(0,h4), vec2(0,h5),
                          vec2(w,h4), vec2(0,h5), vec2(w,h5)} --h5 is purple
    local colors = {}
    local c
    for i,v in ipairs(verts) do
            if v.y == h then c = color(255,0,0)
        elseif v.y == h2 then c = color(255,255,0)
        elseif v.y == h3 then c = color(0,255,0)
        elseif v.y == h4 then c = color(0,0,255)
        elseif v.y == h5 then c = color(141, 0, 255, 255)
            end
        colors[i] = c
    end
    for i,v in ipairs(verts) do
        v.x = v.x + x
        v.y = v.y + y
    end
    rectangle.vertices = verts
    rectangle.colors = colors
    return rectangle
end

Instead of returning rectangle you could return an image instead

local image = image(w,h)
setContext(image)
rectangle:draw()
return image

Originally I was trying to make a rainbow gradient shader for a sphere/ellipse but i couldn't figure it out.

Comments

  • dave1707dave1707 Mod
    edited May 2017 Posts: 7,554

    @xThomas Here's a simple way of doing a circle. I'll let you do it as a shader. Basically I'm calculating the x,y points around the circumference of a circle. I'm then drawing a line from the top of the circle to the bottom as I move from the right to the left. Like cutting a sphere into thin slices.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        tab={}
        cx=WIDTH/2
        cy=HEIGHT/2
        size=HEIGHT/2-10
        step=.2
        d=256/(180/step)
        for z=0,180,step do
            x=math.cos(math.rad(z))*size
            y=math.sin(math.rad(z))*size
            table.insert(tab,vec2(x,y))        
        end   
    end
    
    function draw()
        background(0)
        strokeWidth(2)
        for a,b in pairs(tab) do
            stroke(255-a*d,math.abs(450-a),a*d)
            line(cx+b.x,cy+b.y,cx+b.x,cy-b.y)
        end
    end
    
  • edited May 2017 Posts: 121

    @dave1707:

    Oh, cool! I never thought of drawing a circle using just lines. But yeah, I still haven't gotten any shader for the rainbow. Might take me a bit of time to learn

    In the meantime, I did get a rainbow circle half working at least as a plain old textured mesh. Colors are really washed out for some reason I don't know, and it's way long



    function rainbowCircle(x,y,size,r) -- USE POWERS OF 2 FOR size IF YOU ENABLE TEXTURE WRAPPING -- size builds the circle -- r is rotation in degrees of the texture local CONST_SIZE = size local CONST_ROTATEPOINT = vec2(size/2, size/2) local r = r local rectangle = mesh() local w,h = size, size local h2,h3,h4,h5 = h*.75,h*.5,h*.25,0 local verts = {vec2(w,h), vec2(0,h), vec2(0,h2), -- h is red vec2(w,h), vec2(0,h2), vec2(w,h2), -- h2 is yellow vec2(w,h2), vec2(0,h2), vec2(0,h3), vec2(w,h2), vec2(0,h3), vec2(w,h3), -- h3 is green vec2(w,h3), vec2(0,h3), vec2(0,h4), vec2(w,h3), vec2(0,h4), vec2(w,h4), -- h4 is blue vec2(w,h4), vec2(0,h4), vec2(0,h5), vec2(w,h4), vec2(0,h5), vec2(w,h5)} --h5 is purple local colors = {} local c for i,v in ipairs(verts) do if v.y == h then c = color(255,0,0) elseif v.y == h2 then c = color(255,255,0) elseif v.y == h3 then c = color(0,255,0) elseif v.y == h4 then c = color(0,0,255) elseif v.y == h5 then c = color(141, 0, 255) end colors[i] = c end -- rotate verts local pt for i,v in ipairs(verts) do pt = math.rotateTo(v, r, CONST_ROTATEPOINT) v.x,v.y = pt.x, pt.y end local rainbow = image(w,h) -- sets up our texture setContext(rainbow) rectangle.vertices = verts rectangle.colors = colors rectangle:draw() -- draws our texture setContext() --[[ ============================================ ]]-- -- now we create the circle mesh local circle = mesh() local r = size/2 -- r means radius now local origx, origy = x,y --store original x,y values local x,y = r,r --new x,y values local verts={} local coords = {} local center = vec2(r,r) for i = 1,1080,3 do local angle = i * math.pi / 100 local angle3 = (i+3) * math.pi / 100 local x1, y1 = x + r * math.cos(angle), y + r * math.sin(angle) local x2, y2 = r,r local x3, y3 = x + r * math.cos(angle3), y + r * math.sin(angle3) verts[i] = vec2(x1,y1) verts[i+1] = vec2(x2,y2) verts[i+2] = vec2(x3,y3) end x,y = origx,origy --restore original x,y values --TEXCOORDS: HELP. ME. local coord,cx,cy for i,v in ipairs(verts) do cx,cy = v.x/CONST_SIZE, v.y/CONST_SIZE coords[i] = vec2(cx,cy) end --MOVE TO X,Y COORDINATE ON SCREEN --(Otherwise you'd need to use translate(x,y)) for i,v in ipairs(verts) do v.x, v.y = v.x + x, v.y + y end circle.vertices = verts circle.texCoords = coords circle.texture = rainbow circle:setColors(255,255,255) return circle, rectangle, rainbow end
    -- rotates point around the centre by degrees
    -- rounds the returned coordinates using math.round() if round == true
    -- returns new coordinates object
    local function rotateAboutPoint( point, degrees, centre )
        local pt = { x=point.x - centre.x, y=point.y - centre.y }
        pt = math.rotateTo( pt, degrees )
        pt.x, pt.y = pt.x + centre.x, pt.y + centre.y
        return pt
    end
    
    -- rotates a point around the (0,0) point by degrees
    -- returns new point object
    -- center: optional
    math.rotateTo = function( point, degrees, center )
        if (center ~= nil) then
            return rotateAboutPoint( point, degrees, center )
        else
            local x, y = point.x, point.y
            local theta = math.rad( degrees )
            local pt = {
                x = x * math.cos(theta) - y * math.sin(theta),
                y = x * math.sin(theta) + y * math.cos(theta)
            }
            return pt
        end
    end
    
    function setup()
        a,b,c= rainbowCircle(320,240,512,100)
    end
    
    function draw()
        background(40, 40, 50)
        a:draw()
        b:draw()
        sprite(c, WIDTH/2,HEIGHT/2)
    end
    
  • Posts: 69
    I am not sure if that is it but a medh must always have its vertices devisable by 3, like 3,6,9,...
  • edited May 2017 Posts: 121

    @GR00G0

    Just checked. print(#coords) and print(#verts) both output 1080. (On the rounded circle)

    were you trying to run my code and having a,problem?

  • dave1707dave1707 Mod
    Posts: 7,554

    @xThomas Add the line of code I show below just before the return in the function rainbowCircle(). I'm not sure why it's needed to brighten the colors, but I found that out long ago when I was messing around with meshes.

        circle:setColors(255,255,255)        -- add this line of code
    
        return circle, rectangle, rainbow     -- existing line of code
    
  • dave1707dave1707 Mod
    edited May 2017 Posts: 7,554

    Here's my above program modified to show a range of colors in the circle. You can also slide your finger right or left to scroll the colors.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        dx=0
        tab1={}
        r,g,b=0,255,255
        y=WIDTH
        while y>=0 do
            table.insert(tab1,vec3(r,g,b))
            y=y-WIDTH/(256*6)
            if r==255 and g==0 and b==0 then
                rv,gv,bv=0,1,0
            elseif r==255 and g==255 and b==0 then
                rv,gv,bv=-1,0,0
            elseif r==0 and g==255 and b==0 then
                rv,gv,bv=0,0,1
            elseif r==0 and g==255 and b==255 then
                rv,gv,bv=0,-1,0
            elseif r==0 and g==0 and b==255 then
                rv,gv,bv=1,0,0
            elseif r==255 and g==0 and b==255 then
                rv,gv,bv=0,0,-1
            end 
            r=r+rv
            g=g+gv
            b=b+bv       
        end
        cx,cy=WIDTH/2,HEIGHT/2
        tab={}
        size=HEIGHT/2-6
        for z=0,180,.3 do
            x=math.cos(math.rad(z))*size
            y=math.sin(math.rad(z))*size
            table.insert(tab,vec2(x,y))        
        end 
        s=#tab1/#tab
        scroll=0
    end
    
    function draw()
        background(0)
        strokeWidth(5)
        if scroll>#tab1 then
            scroll=scroll-#tab1
        elseif scroll<=0 then
            scroll=scroll+#tab1
        end
        for a,b in pairs(tab) do
            f=(a*s)//1+scroll
            if f>#tab1 then
                f=f-#tab1
            elseif f<=0 then
                f=f+#tab1
            end
            stroke(tab1[f].x,tab1[f].y,tab1[f].z)
            line(cx+b.x,cy+b.y,cx+b.x,cy-b.y)
        end
    end
    
    function touched(t)
        if t.state==MOVING then
            scroll=(scroll+t.deltaX)//1
        end
    end
    
Sign In or Register to comment.