Just junk to pass the time

@Bri_G I’ve made a note on the colour picker issue for my bug list, thanks for finding it

@Simeon - thanks for the update.

Here’s another useless program of mine. It uses 5,000 digits of Pi to plot the position of cubes. A digit of 1=+x, 2=-x, 3=+y, 4=-y, 5=+z, 6=-z. Digits 7,8,9 plots that many cubes using the last value of 1 thru 6. A digit of 0 resets x,y,z to 0,0,0. You can comment out the line in the draw function where x,y,z gets reset to 0 so it just plots continuously. Try both runs. You can zoom in or out or move the plot around.

PS. I added another line of code. In the if statement >6 and <10 I added hv=math.random(6). This gives a random direction for values 7,8,9. This can be uncommented if you want a different plot.

displayMode(FULLSCREEN)

-- Pi 3d

function setup()
    str=""
    digits=5000
    calcPi()
    dir={vec3(1,0,0),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0),vec3(0,0,1),vec3(0,0,-1)}
    img = readImage(asset.builtin.Blocks.Error)
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 400, 0, 10000)
    v.camera.farPlane=10000
    tab={}
    zz=0
    fill(255)
    x,y,z=0,0,0
    pos=0
    createWall(x,y,z)
end

function createWall(x,y,z)
    zz=zz+1
    tab[zz]=scene:entity()
    tab[zz].position=vec3(x,y,z)
    tab[zz].model = craft.model.cube(vec3(1,1,1))
    tab[zz].material = craft.material(asset.builtin.Materials.Standard)
    tab[zz].material.map = img
end

function draw()
    update(DeltaTime)
    scene:draw()
    if pos<#str then
        pos=pos+1
        v=tonumber(string.sub(str,pos,pos))
        if v==0 then
            -- if v==0 then set x,y,z to 0,0,0
            --x,y,z=0,0,0       -- uncomment this line and run again
        elseif v>0 and v<7 then
            x=x+dir[v].x
            y=y+dir[v].y
            z=z+dir[v].z
            createWall(x,y,z)
            hv=v
        elseif v>6 and v<10 then 
            -- set hv to a random direction
            --hv=math.random(6) -- uncomment this line and run again           
            for a=1,v do
                x=x+dir[hv].x
                y=y+dir[hv].y
                z=z+dir[hv].z
                createWall(x,y,z)
            end
        end
    end
    text(pos.."  of  "..digits,WIDTH/2,HEIGHT-50)
end

function update(dt)
    scene:update(dt)
end

function calcPi() 
    local pi,tab={},{}
    local size=math.ceil(digits/7)+1
    local size1=math.ceil(size*7)
    local sum,carry,b,z2
    local d1,d2=10000000,9999999 
    local sf=string.format
    local mm=math.modf    
    for z=0,size1 do
        tab[z]=5*z+3
    end       
    for t=1,size do
        carry=0
        for z=size1,0,-1 do
            z2=z*z
            sum=tab[z]*d1+carry
            b=27*(z2+z)+6
            tab[z]=sum%b
            carry=(sum//b)*(2*z2-z)
        end       
        tab[0]=sum%d1
        pi[t]=sum//d1
    end        
    carry=0
    for z=size,1,-1 do
        b=pi[z]+carry
        if b>d2 then
            b=b-d1
            carry=1
        else
            carry=0
        end
        pi[z]=sf("%07d",b)
    end      
    str=table.concat(pi)
end

@dave1707 - I like this code, but didn’t realise initially that you can scroll the view with the 3D camera. I put a parameter.integer() variable size to increase the size of the cubes. Once you scroll it you can see the depth. Also, if you just watch it and don’t touch the screen the wall disappears offscreen bottom.

I introduced mon and max values for the x,y,z call to createWall() in an attempt to locate the scale then introduced that into the code as an offset, then later as camera viewpoint. But the walls seemed to be behind the camera. Next I’ll try to put the camera z location in front of the 3D wall. Thanks for this - made me think about the concept/code.

@Bri_G It starts spreading out quite fast. You can zoom in or out, rotate or move around. The one I like the best is when x,y,z=0,0,0 is uncommented. Then the display is kept close to the center. I like to zoom in so you can see the 3d effect a lot better as it keeps creating more cubes. I should have renamed the function createWall to createCube. I copied this code from one of my other projects and made some changes and forgot to change that function name.

@dave1707 - actually I didn’t uncomment that line - I’ll try it out.Thanks.

Here’s a Sierpenski cube using my dice routine. This might take a few seconds to load up on slower devices (15 seconds or less). If it crashes Codea, then change the statement cube3(0,0,0) at the end of setup() to cube2(0,0,0) to show a less complex cube. You can also try cube1(0,0,0) for a smaller cube. I couldn’t find a program I liked that calculated the cube, so this is just some brute force code.

displayMode(FULLSCREEN)

function setup()
    noSmooth()
    rectMode(CORNER)    
    img=image(600,100)    
    setContext(img)
    background(0, 0, 0, 255)    
    fill(238, 241, 44) 
    rect(0,0,600,100)    
    fill(0, 0, 0, 255) 
    ellipse(50,50,20)    
    ellipse(125,75,20) ellipse(175,25,20)    
    ellipse(525,75,20) ellipse(550,50,20) ellipse(575,25,20)
    ellipse(425,75,20) ellipse(425,25,20) ellipse(475,75,20) ellipse(475,25,20)    
    ellipse(350,50,20) ellipse(325,75,20) ellipse(325,25,20)
    ellipse(375,75,20) ellipse(375,25,20)    
    ellipse(225,75,20) ellipse(250,75,20) ellipse(275,75,20)    
    ellipse(225,25,20) ellipse(250,25,20) ellipse(275,25,20)
    stroke(0)
    noFill()
    strokeWidth(8)
    rect(0,0,100,100) rect(100,0,100,100) rect(200,0,100,100)
    rect(300,0,100,100) rect(400,0,100,100) rect(500,0,100,100)
    setContext()            
    zz=0
    tab={}
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 70, 0, 10000)
    v.rx=-45
    v.ry=-30
    cube3(0,0,0)
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function cube3()
    for x1=-13,13,9 do
        for y1=-13,13,9 do
            for z1=-13,13,9 do
                if x1==-4 and y1==-4 and z1==-13 then
                elseif x1==-4 and y1==-4 and z1==5 then
                elseif x1==-13 and y1==-4 and z1==-4 then
                elseif x1==-4 and y1==-4 and z1==-4 then
                elseif x1==5 and y1==-4 and z1==-4 then
                elseif x1==-4 and y1==-13 and z1==-4 then
                elseif x1==-4 and y1==5 and z1==-4 then
                else
                    cube2(x1,y1,z1)
                end                
            end
        end
    end
end

function cube2(x,y,z)
    for x1=-4,4,3 do
        for y1=-4,4,3 do
            for z1=-4,4,3 do
                if x1==-1 and y1==-1 and z1==-4 then
                elseif x1==-1 and y1==-1 and z1==2 then
                elseif x1==-4 and y1==-1 and z1==-1 then
                elseif x1==-1 and y1==-1 and z1==-1 then
                elseif x1==2 and y1==-1 and z1==-1 then
                elseif x1==-1 and y1==-4 and z1==-1 then
                elseif x1==-1 and y1==2 and z1==-1 then
                else                    
                    cube1(x1+x,y1+y,z1+z)
                end                
            end
        end
    end
end
        
function cube1(x,y,z)
    for x1=-1,1 do
        for y1=-1,1 do
            for z1=-1,1 do
                if x1==0 and y1==0 and z1==-1 then
                elseif x1==0 and y1==0 and z1==1 then
                elseif x1==-1 and y1==0 and z1==0 then
                elseif x1==0 and y1==0 and z1==0 then
                elseif x1==1 and y1==0 and z1==0 then
                elseif x1==0 and y1==-1 and z1==0 then
                elseif x1==0 and y1==1 and z1==0 then
                else
                    cube0(x1+x,y1+y,z1+z)
                end                
            end
        end
    end
end

function cube0(x,y,z)
    zz=zz+1
    tab[zz]=scene:entity()
    tab[zz].position=vec3(x,y,z)
    tab[zz].model = craft.model.cube(vec3(.9,.9,.9))
    tab[zz].material = craft.material(asset.builtin.Materials.Standard)
    tab[zz].material.map = img
    temp=tab[zz].model.indices
    for z=#tab[zz].model.indices,1,-1 do
        table.insert(temp,tab[zz].model.indices[z])
    end
    tab[zz].model.indices=temp      
    local uvs1={}
    c=0
    for x=1,6 do
        table.insert(uvs1,vec2(c/6,0))
        table.insert(uvs1,vec2((c+1)/6,0))
        table.insert(uvs1,vec2((c+1)/6,1))
        table.insert(uvs1,vec2(c/6,1))
        c=c+1
    end
    tab[zz].model.uvs=uvs1
end

@dave1707 - very impressive, worth the wait. That’s an enormous amount of computing Power to build and place all those cubes on an iPad.

@Bri_G Thanks for the comment. There are 8,000 cubes being drawn at that level. If I could go up one more level, it would take 160,000 cubes. I don’t think Codea could handle that many. Maybe I’ll try and see how many cubes can be drawn before Codea crashes. I’m sure it probably depends on the amount of available memory. I don’t know if apps are limited to a fixed amount of memory or they can use whatever is available while they’re running. How long did it take to load the image. On my iPad it took about 3 second.

PS. I tried other code and I can do a solid 29x29x29 cube, but Codea crashes if I try a 30x30x30 cube.

Here’s a 9x9x9 Sierpinski cube on the left and what was removed from it on the right.

displayMode(FULLSCREEN)

function setup()
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 30, 0, 10000)
    v.camera.farPlane=10000
    img=readImage(asset.builtin.Blocks.Table)

    for x=1,9 do
        for y=1,9 do
            for z=1,9 do
                check(x,y,z)
            end
        end
    end
end

function check(x,y,z)
    for x1=2,8,3 do
        for y1=2,8,3 do
            for z1=2,8,3 do
                if x==x1 and y==y1 then
                    cube(x,y,z)
                    return
                elseif x==x1 and z==z1 then
                    cube(x,y,z)
                    return
                elseif y==y1 and z==z1 then
                    cube(x,y,z)
                    return
                end
            end
        end
    end
    
    for x1=4,6 do
        for y1=4,6 do
            for z1=4,6 do
                if x==x1 and y==y1 then
                    cube(x,y,z)
                    return
                elseif x==x1 and z==z1 then
                    cube(x,y,z)
                    return
                elseif y==y1 and z==z1 then
                    cube(x,y,z)
                    return
                end
            end
        end
    end
    cube(x+15,y,z)
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function cube(x,y,z)
    s=scene:entity()
    s.position=vec3(x-13,y-5,z)
    s.model = craft.model.cube(vec3(1,1,1))
    s.material = craft.material(asset.builtin.Materials.Standard)
    s.material.map = img
end

This is so cool, I’m going to test this with the new image-based-lighting environment stuff @John has added to Craft

Turned on the bloom and image based lighting

I knew there had to be a better way to draw the Sierpinski cube. I took one of my programs and kept compressing the code and this is what I ended up with. Quite a reduction in code using a recursive call. This does a 27 x 27 x 27 cube. I tried the next higher cube, an 81 x 81 x 81, but Codea crashed. I probably need to create the cubes a different way.

displayMode(FULLSCREEN)

-- Sierpinski cube

function setup()
    img=readImage(asset.builtin.Blocks.Table)
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()
    v=scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 10000)
    v.rx=-40
    v.ry=-35
    cube(0,0,0,27)
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function cube(x,y,z,size)
    local s=size/3
    for x1=-s,s,s do
        for y1=-s,s,s do
            for z1=-s,s,s do
                if (y1~=0 or z1~=0) and (x1~=0 or z1~=0) and (x1~=0 or y1~=0) then
                    if size~=3 then
                        cube(x1+x,y1+y,z1+z,s)
                    else
                        local c=scene:entity()
                        c.position=vec3(x1+x,y1+y,z1+z)
                        c.model = craft.model.cube(vec3(1,1,1))
                        c.material = craft.material(asset.builtin.Materials.Standard)
                        c.material.map = img
                    end
                end
            end
        end
    end
end

@dave1707 - waaahooo, that’s a lot of compression - are you a mathematician by trade? This is great, changed the image and took a while to generate - see below.

@Bri_G Not a mathematician, but I like doing math stuff. I was a programmer by profession, currently retired. I usually code thing with brute force, then after I get them working I’ll see how condensed I can get them. I normally don’t do recursive coding, but the Sierpinski cube is naturally recursive.

@dave1707 - I program for a hobby, just added a new image in post above, more relevant I think. Do you think you could build the cube faster/more cubes if you used a textured obj model?

@Bri_G Building each of the cubes is what’s slowing things down. I need to create them a different way. If I comment out the code that creates the cube, it run instantaneously, so that’s the bottleneck.

@Bri_G I tried my above code using the old 3d code that we had before Craft and it drew the cube immediately, but the FPS was 6 on my iPad Air 3. Probably would be near 1 on slower devices. Need to try something else.

Sure seems like there should be a better way to handle that if-or-and nest but I haven’t been able to think of one.

@RonJeffries Look at the code a few programs above and see what my original if statements looked like for the different sized cubes.