Skip to content

Instantly share code, notes, and snippets.

@Bri-G
Created June 7, 2012 19:12
Show Gist options
  • Save Bri-G/2890949 to your computer and use it in GitHub Desktop.
Save Bri-G/2890949 to your computer and use it in GitHub Desktop.
Old School rotating sphere
-- Lua routing for drawing reflective spheres
-- by Bri_G
Polar = class()
function Polar:init(w)
-- you can accept and set parameters here
self.bigrad = w or 20
self.smallrad = self.bigrad * 0.4 or 8
self.colour = color(0, 255, 55, 255)
self.shine = color(247, 247, 247, 228)
self.shaded = color(69, 100, 66, 255)
end
function Polar:draw(x,y,z)
-- Codea does not automatically call this method
local offset = self.bigrad/6
pushMatrix()
pushStyle()
noStroke()
if z < 0 then
fill(self.shaded)
ellipse(x, y, self.smallrad, self.smallrad)
else
fill(self.colour)
ellipse(x, y, self.bigrad, self.bigrad)
fill(self.shine)
ellipse(x - offset , y + offset, self.smallrad, self.smallrad)
end
popStyle()
popMatrix()
end
function Polar:touched(touch)
-- Codea does not automatically call this method
end
-- A translation of the javascript from Guido D'Albore by Bri_G
-- reference http://www.bitstorm.it/blog/en/2011/05/3d-sphere-html5-canvas/
-- with help from Inviso and Andrew Stacey on the mechanics
-- set up for Love2D too - remove the comment marks
--[[ if require ~= nil then
require("loveCodea")
require("Polar")
end --]]
function setup()
-- tested in the portrait screen mode
displayMode(FULLSCREEN)
watch("drwTime")
pts = { x = {}, y = {}, z = {}}
rotation = 0
distance = 0
Speed = 1
z = 0
t = 0
fps = 0
StepsV = 36
degs = 360/StepsV
midX = WIDTH/2
midY = HEIGHT/2
font("Georgia")
fontSize(20)
-- call to routine to draw the spheres
Polar:init(16)
-- index the array - initialise
index = 1
-- outer circle then front and back loops in 10 deg increments
for i = 0, 360, degs do
for direction = 1, -1, -2 do
for a = 10, 180, degs do
pts.x[index] = math.cos(math.rad(a)) * math.cos(math.rad(i))
pts.y[index] = math.sin(math.rad(a)) * math.cos(math.rad(i))
pts.z[index] = math.sin(math.rad(i)) * direction
index = index + 1
end
end
end
end
-- This function gets called once every frame
function draw()
translate(midX, midY)
-- This sets a dark background color
background(0, 0, 0, 250)
for display = 1,2 do
-- loop twice to get front and nack hemispheres
for i = 1, index - 1 do
rotateX(i, rotation)
rotateY(i, rotation)
rotateZ(i, rotation)
-- modified call to adjust rotational movements
x = projection(pts.x[i], pts.z[i], 100, distance)
y = projection(pts.y[i], pts.z[i], 100, distance)
-- first pass on loop draws the back hemisphere, second the front
if pts.z[i] <= 0 and display == 1 then
Polar:draw(x, y, pts.z[i])
elseif pts.z[i] > 0 and display == 2 then
Polar:draw(x, y, pts.z[i])
end
end
end
-- dictates the intial forward movement and all rotational movements
rotation = rotation + math.pi/360
if distance < 24000 then distance = distance + 400 end
fill(81, 232, 27, 255)
text("Thanks to Guido D'Albore for the precedent",100,-350)
text("plus Inviso and Andrew Stacey for their help", 100, -400)
end
function rotateX(pt, rads)
y = pts.y[pt]
pts.y[pt] = (y*math.cos(rads))-(pts.z[pt]*math.sin(rads))
pts.z[pt] = (y*math.sin(rads))+(pts.z[pt]*math.cos(rads))
end
function rotateY(pt, rads)
x = pts.x[pt]
pts.x[pt] = (x*math.cos(rads))-(pts.z[pt]*math.sin(rads))
pts.z[pt] = (x*math.sin(rads))+(pts.z[pt]*math.cos(rads))
end
function rotateZ(pt, rads)
x = pts.x[pt]
pts.x[pt] = (x*math.cos(rads))-(pts.y[pt]*math.sin(rads))
pts.y[pt] = (x*math.sin(rads))+(pts.y[pt]*math.cos(rads))
end
function projection(xy, z, zOffset, distance)
return((distance*xy)/(z-zOffset))
end
@Bri-G
Copy link
Author

Bri-G commented Jun 7, 2012

I saw Guido D'Aldore's HTML5 demo and was determined to learn from it by reproducing it in Lua for Codea. A good learning example for me. Hope you like it and thanks Guido !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment