Whats wrong with this??

Ive just created a class and its saying its a global nil value, im trying to drawing quadratic splines for an app, heres the code:


Brushb = class()

function Brushb:init(x,y,width,col)
    self.col = col
    self.alpha = col.a
    self.width = width
    self.points = {vec2(x,y)}
    self.curves = {}
    self.id = 1
end

function Brushb:addPoints(p)
    self.id = self.id + 1
    table.insert(self.points,p)
    local sp = self.points
    local si = self.id
    if (self.id%3) == 1 then
        local tempc = {}
        local t = 0
        for i=1,5 do
            t = t + 0.2
            table.insert(self.curves,((1 – t)^2)*sp[si-2] + 2*(1 – t)*t*sp[si-1] + (t^2)*sp[si])
        end
    end  
end

function Brushb:drawPoints()
    local sc = self.curves
    local sp = self.points
    for i=2,#sc do
        local sci = sc[i]
        local sci2 = sc[i-1]
        Line(sci,sci2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha):draw()
    end
    if #sp > #sc then
        for i=1,#sp-#sc do
            local spi = sp[#sc+i]
            local spi2 = sp[#sc+i-1]
            Line(spi,spi2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha):draw()
        end
    end
end
function Brushb:draw()  
    
end

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

Im not getting it if I just type in,

brush = Brushb(t.x,t.y,color(50,50,50,255),5)

then I get given the error that global ‘Brushb’ is a nil value.

…^2 => math.pow(…, 2)

math.pow(1 - t,2) * sp[si-2] + 2 * (1 - t) * t * sp[si-1] + (mah.pow(t,2)*sp[si])

and

forgot ) at Line declaration

Line(spi,spi2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()

Ahh, well Ive done that and it hasnt changed the error, I put the code in to a seperate project and ran it and it doesnt work either I get the same errors, here is the Line class if that helps, it doesnt have any errors:

Line = class()


function Line:init(pos1,pos2,width,col)
    self.m = mesh()
    self.p = (pos1+pos2)
    self.pl = (pos1-pos2)
    self.dir = self.pl:normalize()
    self.len = self.pl:len()
    self.width = width
    self.pos1 = pos1
    self.pos2 = pos2
    self.col = col
    self.p = self.p/2
    self.m.texture = linetex
    self.r = self.m:addRect(self.p.x,self.p.y,self.len,width,angleOfPoint(self.dir)/57.3)
    self.m:setColors(col.r,col.g,col.b,col.a)
end

function Line:setPos(pos1,pos2)

    self.p = (pos1+pos2)
    self.pl = (pos1-pos2)
    self.pos1 = pos1
    self.pos2 = pos2
    self.dir = self.pl:normalize()
    self.len = self.pl:len()
    self.p = self.p/2
    self.m:setRect(self.r,self.p.x,self.p.y,self.len,self.width,angleOfPoint(self.dir)/57.3)
end

function Line:draw()
    pushStyle()
        fill(self.col.r,self.col.g,self.col.b,self.col.a or 255)
        ellipse(self.pos1.x,self.pos1.y,self.width)
        ellipse(self.pos2.x,self.pos2.y,self.width)
    popStyle()
    self.m:draw()
end

but in your main, you have just

 brush = Brushb(t.x,t.y,color(50,50,50,255),5) 

?

Yes in your class init the order is x y width colour but you are cslling it ad x y colour width

I changed that but still getting the error… Anyway the error I get doesnt relate to the wrong order of parameters but the actual class itself is a nil value

line 122: brush = Spline(td.x,td.y,width,color(col.r,col.g,col.b,alpha))
---------
error: [string "-- Paint..."]:122: attempt to call global 'Spline' (a nil value)

tab order ?

Nope that doesn’t change it

If this helps try see if you can make this work?



--# Line
Line = class()


function Line:init(pos1,pos2,width,col)
    self.m = mesh()
    self.p = (pos1+pos2)
    self.pl = (pos1-pos2)
    self.dir = self.pl:normalize()
    self.len = self.pl:len()
    self.width = width
    self.pos1 = pos1
    self.pos2 = pos2
    self.col = col
    self.p = self.p/2
    self.m.texture = linetex
    self.r = self.m:addRect(self.p.x,self.p.y,self.len,width,angleOfPoint(self.dir)/57.3)
    self.m:setColors(col.r,col.g,col.b,col.a)
end

function Line:setPos(pos1,pos2)

    self.p = (pos1+pos2)
    self.pl = (pos1-pos2)
    self.pos1 = pos1
    self.pos2 = pos2
    self.dir = self.pl:normalize()
    self.len = self.pl:len()
    self.p = self.p/2
    self.m:setRect(self.r,self.p.x,self.p.y,self.len,self.width,angleOfPoint(self.dir)/57.3)
end

function Line:draw()
    pushStyle()
        fill(self.col.r,self.col.g,self.col.b,self.col.a or 255)
        ellipse(self.pos1.x,self.pos1.y,self.width)
        ellipse(self.pos2.x,self.pos2.y,self.width)
    popStyle()
    self.m:draw()
end
--# Spline
Spline = class()

function Spline:init(x,y,width,col)
    self.x = x
    self.y = y
    self.col = col
    self.alpha = col.a
    self.width = width
    self.points = {}
    table.insert(self.points,vec2(x,y))
    self.curves = {}
    self.id = 1
end

function Spline:addPoints(p)
    self.id = self.id + 1
    table.insert(self.points,p)
    local sp = self.points
    local si = self.id
    if (si%3) == 1 then
        local tempc = {}
        local t = 0
        for i=1,5 do
            t = t + 0.2
table.insert(self.curves,math.pow(1 – t,2)*sp[si-2] + 2*(1 – t)*t*sp[si-1] + math.pow(t,2)*sp[si])
        end
    end  
end

function Spline:drawPoints()
    local sc = self.curves
    local sp = self.points
    for i=2,#sc do
        local sci = sc[i]
        local sci2 = sc[i-1]
        Line(sci,sci2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
    end
    if #sp > #sc then
        for i=1,#sp-#sc do
            local spi = sp[#sc+i]
            local spi2 = sp[#sc+i-1]
            Line(spi,spi2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
        end
    end
end
function Spline:draw()  
    --
end

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

--# Main


function setup()
    spline = Spline(1,3,4,color(255,255,255))
    for i=1,10 do
        spline:addPoints(vec2(30+math.random(300),50+math.random(400)))
    end  
    print("run") 
end

function draw()
    background(255)
    spline:drawPoints()
end

@luatee The minus signs in

table.insert(self.curves,math.pow(1 – t,2)*sp[si-2] + 2*(1 – t)*t*sp[si-1] + math.pow(t,2)*sp[si])

aren’t minus signs. They’re en-dashes (or something like that). It worked when I replaced them with minuses (modulo missing other functions).

I did that and its worked but i found out you can’t draw using this function anyway so waste of time for me and you thanks to all that helped anyway

Okay I’ve spent most the night trying to get this to work, here’s a working version:


Spline = class()

function Spline:init(x,y,width,col)
    self.x = x
    self.y = y
    self.col = col
    self.alpha = col.a
    self.width = width
    self.points = {}
    table.insert(self.points,vec2(x,y))
    self.curves = {}
    table.insert(self.curves,vec2(x,y))
    self.id = 1
    self.it = 1
end

function Spline:addPoints(p)
    self.id = self.id + 1
    table.insert(self.points,p)
    local sp = self.points
    local sc = self.curves
    local si = self.id
    if ((si)%3) == 0 then
        local tempc = {}
        local t = 0
        for i=1,10 do
            t = t + 0.05
            self.it = self.it + 1
            local vec = (2*(1-t)*t*sp[si-1] + math.pow(t,2)*sp[si] + math.pow(1-t,2)*sp[si-2])
            table.insert(self.curves,vec)
            local sci2 = self.curves[self.it-1]
            Line(vec,sci2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
        end
    end  
end

function Spline:drawPoints()
    local sc = self.curves
    local sp = self.points
    for i=2,#sc do
        local sci = sc[i]
        local sci2 = sc[i-1]
        Line(sci,sci2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
    end
    if #sp > #sc then
        for i=1,#sp-#sc do
            local spi = sp[#sc+i]
            local spi2 = sp[#sc+i-1]
            Line(spi,spi2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
        end
        print("true")
    end
end
function Spline:draw()  
    line(0,0,0,0)
end

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

To draw the lines use spline:addPoints(p) do not use drawPoints as this doesn’t work as well.
I’m hoping someone here can maybe improve on this? It seems that the splines are only occurring in certain places, I still end up with sharp edges on the lines (visible line segments)

@Luatee What’s the angleOfPoint function?

Sorry about that, here it is


function angleOfPoint( pt )
   local x, y = pt.x, pt.y
   local radian = math.atan2(y,x)
   local angle = radian*180/math.pi
   if angle < 0 then angle = 360 + angle elseif angle > 360 then angle = 0 + (angle-360) end
   return angle
end

Here’s an updated version which works better, actually smooths out the lines a bit this time!


Spline = class()

function Spline:init(x,y,width,col)
    self.x = x
    self.y = y
    self.col = col
    self.alpha = col.a
    self.width = width
    self.points = {}
    table.insert(self.points,vec2(x,y))
    self.curves = {}
    table.insert(self.curves,vec2(x,y))
    self.id = 1
    self.it = 1
end

function Spline:addPoints(p,dir)
    self.id = self.id + 1
    table.insert(self.points,p)
    local sp = self.points
    local sc = self.curves
    local si = self.id
    if ((si-1)%3) == 0 then
        local tempc = {}
        local t = 0
        for i=1,5 do
            t = t + 0.2
            self.it = self.it + 1
local vec = (1-t)^3 * sp[si-3] + 3*(1-t)^2 *t * sp[si-2] + 3*(1-t)* t^2 *sp[si-1] + t^3*sp[si]
            table.insert(self.curves,vec)
            local sci2 = self.curves[self.it-1]
            Line(vec,sci2,self.width,color(self.col.r,self.col.g,self.col.b,self.alpha)):draw()
        end
    else
    self.points[self.id] = self.points[self.id] + dir/10
    end  
end

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

You know that instead of

    local angle = radian*180/math.pi

You can just use

    local angle = math.deg(radian)

Right?

Yeah I suppose but its sorted now I went to using catmull rom algorithm