Here’s an example that shows a tube created with Craft. It’s a tube that runs along a Bézier curve. Each run creates a different curve. Press the restart icon for a different curve. You can zoom in from an end or just pass thru the skin to see the inside. You can change the diameter or the number of sides. 2 sides creates a ribbon, and 3 sides just looks interesting.
EDIT: Made a change so the red dots line up with the skin. There was 1 dot that stuck out on one end and on the other end it was one dot in.
displayMode(FULLSCREEN)
function setup()
diameter=25
sides=20
assert(craft, "Please include Craft as a dependency")
assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
scene = craft.scene()
v=scene.camera:add(OrbitViewer,vec3(0,0,0), 600, 0, 2000)
v.camera.farPlane=3000
pos,ind,col={},{},{}
x1,y1,z1=math.random(-300,300),math.random(-300,300),math.random(-300,300)
x2,y2,z2=math.random(-300,300),math.random(-300,300),math.random(-300,300)
bezier()
createSkin()
createTube()
end
function draw()
update(DeltaTime)
scene:draw()
text("Slide your finger around the screen to rotate the image.",WIDTH/2,HEIGHT-25)
text("Use two fingers to zoom in, zoom out or to move the image.",WIDTH/2,HEIGHT-50)
end
function update(dt)
scene:update(dt)
end
function bezier()
local tab1={}
local x,y,z={0,0},{0,0},{-200,200}
for t=0,1,.02 do
local xt=(1-t)^3*x[1]+3*t*(1-t)^2*x1+3*t^2*(1-t)*x2+t^3*x[2]
local yt=(1-t)^3*y[1]+3*t*(1-t)^2*y1+3*t^2*(1-t)*y2+t^3*y[2]
local zt=(1-t)^3*z[1]+3*t*(1-t)^2*z1+3*t^2*(1-t)*z2+t^3*z[2]
table.insert(tab1,vec3(xt,yt,zt))
end
for z=1,#tab1-1 do
local p1=vec3(tab1[z].x,tab1[z].y,tab1[z].z)
local p2=vec3(tab1[z+1].x,tab1[z+1].y,tab1[z+1].z)
createLoop(p1,p2)
createSphere(vec3(tab1[z].x,tab1[z].y,tab1[z].z))
end
end
function createLoop(p1,p2)
local rp=vec3(80,80,80)
local v1=rp-p1
local r1=v1:cross(p2-p1)
local s1=r1:cross(p2-p1)
r1,s1=r1:normalize(),s1:normalize()
local n=vec3(0,0,0)
for a=0,359,360/sides do
n.x = r1.x * math.cos(math.rad(a)) + s1.x * math.sin(math.rad(a))
n.y = r1.y * math.cos(math.rad(a)) + s1.y * math.sin(math.rad(a))
n.z = r1.z * math.cos(math.rad(a)) + s1.z * math.sin(math.rad(a))
n=n:normalize()*diameter
table.insert(pos,vec3(n.x+p1.x,n.y+p1.y,n.z+p1.z))
end
end
function createSkin()
o,p={1,2,3,4,5,6,3,2,1,6,5,4},{}
for z=1,#pos-sides do
p[1],p[2],p[3],p[4],p[5],p[6]=z,z+1,z+sides+1,z,z+sides+1,z+sides
if z%sides==0 then
p[2]=z-sides+1
p[3]=z+1
p[5]=z+1
end
for t=1,12 do
table.insert(ind,p[o[t]])
end
end
for z=1,#pos do
table.insert(col,color(math.random(255),math.random(255),math.random(255)))
end
end
function createSphere(p)
local pt=scene:entity()
pt.position=p
pt.model = craft.model.icosphere(2,2)
pt.material = craft.material("Materials:Specular")
pt.material.diffuse=color(255,0,0)
end
function createTube()
local pt=scene:entity()
pt.model = craft.model.cube()
pt.model.positions=pos
pt.model.indices=ind
pt.model.colors=col
pt.material = craft.material("Materials:Basic")
end