#### 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 Posts: 122

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)

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

``````

``````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.

• edited May 2017 Posts: 9,432

@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
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: 122

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: 122

@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?

• Posts: 9,432

@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
``````
• edited May 2017 Posts: 9,432

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
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
``````