Rose graphs

I was playing around with rose graphs earlier and thought they might make a cool little loading indicator or something.

Here’s the code:


--# Main
-- Rose Graph

function setup()
    rose = Rose(100, 3)
end

function draw()
    background(255)
    
    stroke(255, 0, 0) strokeWidth(5) --noSmooth()
    
    pushMatrix()
    translate(WIDTH / 2, HEIGHT / 2)
    
    rose:draw()
    
    popMatrix()
end


--# Rose
Rose = class()

function Rose:init(a, b)
    a = a or 100
    b = b or 3
    
    local rose = function(angle) 
        return a * math.cos(b * angle) 
    end
    
    self.points = {}
    
    for theta = 0, math.pi * 2, 0.05 do
        local r = rose(theta)
        local x, y = r * math.cos(theta), r * math.sin(theta)
    
        table.insert(self.points, vec2(x, y))
    end
end

function Rose:draw()
    for i = 70, #self.points - 1 do
        line(self.points[i].x, self.points[i].y, self.points[i + 1].x, self.points[i + 1].y)
    end
    
    local last = self.points[#self.points]
    for i = #self.points, 2, -1 do
        self.points[i] = self.points[i - 1]
    end
    self.points[1] = last
end

function Rose:touched(touch)
    -- Codea does not automatically call this method
end

Love it!
Modified it a bit, because why not:

function setup()
    rose = Rose(100, 2)
end
function draw()
    background(255)
    stroke(255, 0, 0) strokeWidth(5) --noSmooth()
    pushMatrix()
    translate(WIDTH / 2, HEIGHT / 2)
    rose:draw()
    popMatrix()
end
Rose = class()
function Rose:init(a, b)
    a = a or 100
    b = b or 3
    local rose = function(angle) 
        return a * math.cos(b * angle) 
    end
    self.points = {}
    for theta = 0, math.pi * 2, 0.04 do
        local r = rose(theta)
        local x, y = r * math.cos(theta), r * math.sin(theta)
        table.insert(self.points, vec2(x, y))
    end
    self.factor = #self.points-1-80
    self.colors = {color(255, 0, 0, 255),color(255, 118, 0, 255),
    color(255, 230, 0, 255),color(73, 255, 0, 255),
    color(0, 249, 255, 255),color(15, 0, 255, 255),
    color(190, 0, 255, 255),color(255, 0, 172, 255)}
    self.next = 3
end
function Rose:draw()
    self:ccyc(true)
    for i = 80, #self.points - 1 do
        stroke(self:ccyc())
        strokeWidth(7.5-7*(i-80)/self.factor)
        line(self.points[i].x, self.points[i].y, self.points[i + 1].x, self.points[i + 1].y)
    end
    local last = self.points[#self.points]
    for i = #self.points, 2, -1 do
        self.points[i] = self.points[i - 1]
    end
    self.points[1] = last
end
function Rose:ccyc(reset)
    if reset then
        self.num = 0
        self.c2 = self.colors[2]
        self.c1 = self.colors[1]
        self.next = 3
        self.gl = 0
    else
        self.num = self.num + 1/self.factor
        if self.num*7>=1 then
            self.c1 = self.c2
            self.c2 = self.colors[self.next] or self.colors[1]
            self.num = 0
            self.next = self.next + 1 
        end
        return self.c2:mix(self.c1,self.num*7)
    end
end

If we’re going to modify this, here’s my version.

displayMode(FULLSCREEN)
    
function setup()
    tab={}
    size=2
    table.insert(tab,Rose(100+size*5,size))
    c=0
end

function draw()
    background(255)
    stroke(255, 0, 0) strokeWidth(5) --noSmooth()
    pushMatrix()
    translate(WIDTH / 2, HEIGHT / 2)
    for a,b in pairs(tab) do
        b:draw()
    end
    popMatrix()
    c=c+1
    if c>60 then
        size=size+1
        table.insert(tab,Rose(100+size*5,size))
        if size>5 then
            table.remove(tab,1)
        end
        c=0
    end
end

Rose = class()
function Rose:init(a, b)
    a = a or 100
    b = b or 3
    local rose = function(angle) 
        return a * math.cos(b * angle) 
    end
    self.points = {}
    for theta = 0, math.pi * 2, 0.04 do
        local r = rose(theta)
        local x, y = r * math.cos(theta), r * math.sin(theta)
        table.insert(self.points, vec2(x, y))
    end
    self.factor = #self.points-1-80
    self.colors = {color(255, 0, 0, 255),color(255, 118, 0, 255),
    color(255, 230, 0, 255),color(73, 255, 0, 255),
    color(0, 249, 255, 255),color(15, 0, 255, 255),
    color(190, 0, 255, 255),color(255, 0, 172, 255)}
    self.next = 3
end
function Rose:draw()
    self:ccyc(true)
    for i = 80, #self.points - 1 do
        stroke(self:ccyc())
        strokeWidth(7.5-7*(i-80)/self.factor)
        line(self.points[i].x, self.points[i].y, self.points[i + 1].x, self.points[i + 1].y)
    end
    local last = self.points[#self.points]
    for i = #self.points, 2, -1 do
        self.points[i] = self.points[i - 1]
    end
    self.points[1] = last
end
function Rose:ccyc(reset)
    if reset then
        self.num = 0
        self.c2 = self.colors[2]
        self.c1 = self.colors[1]
        self.next = 3
        self.gl = 0
    else
        self.num = self.num + 1/self.factor
        if self.num*7>=1 then
            self.c1 = self.c2
            self.c2 = self.colors[self.next] or self.colors[1]
            self.num = 0
            self.next = self.next + 1 
        end
        return self.c2:mix(self.c1,self.num*7)
    end
end

nice graphs! Thanks