Quick Links: Download Gideros Studio | Gideros Documentation | Ultimate Guide | Gideros Development Center
Snippet: Rotating 3D cube - Gideros Forum

Snippet: Rotating 3D cube

ndossndoss Guru
edited January 2012 in Code snippets
Adapted from: http://www.kirupa.com/developer/actionscript/rotation_center.htm

The following code draws a rotating 3d cube. It doesn't handle depth well and is primarily a learning exercise for me, but thought I'd share.
 
--focal length to determine perspective scaling
local focalLength = 250
 
-- initial decays of 3D cube
local userX = -0.01
local userY = 0.01
local line = {}
 
-- x, y and z properties to represent a 3D point.
local make3DPoint = function(x,y,z)
local point = {}
point.x = x
point.y = y
point.z = z
return point
end
 
-- similarly set up a function to make an object with
-- x and y properties to represent a 2D point.
local make2DPoint = function(x, y)
local point = {}
point.x = x+200
point.y = y+200
return point
end
 
-- conversion function for changing an array of 3D points to an
-- array of 2D points which is to be returned.
local Transform3DPointsTo2DPoints = function(points, axisRotations)
-- the array to hold transformed 2D points - the 3D points
-- from the point array which are here rotated and scaled
--to generate a point as it would appear on the screen
local TransformedPointsArray = {}
-- Math calcs for angles - sin and cos for each (trig)
-- this will be the only time sin or cos is used for the
-- entire portion of calculating all rotations
local sx = math.sin(axisRotations.x)
local cx = math.cos(axisRotations.x)
local sy = math.sin(axisRotations.y)
local cy = math.cos(axisRotations.y)
local sz = math.sin(axisRotations.z)
local cz = math.cos(axisRotations.z)
 
-- a couple of variables to be used in the looping
-- of all the points in the transform process
local x,y,z, xy,xz, yx,yz, zx,zy, scaleRatio
 
-- loop through all the points in your object/scene/space
-- whatever - those points passed - so each is transformed
local i = table.getn(points)
while (i >0) do
--apply Math to making transformations
-- based on rotations
-- assign variables for the current x, y and z
x = points[i].x
y = points[i].y
z = points[i].z
 
-- perform the rotations around each axis
-- rotation around x
xy = cx*y - sx*z
xz = sx*y + cx*z
-- rotation around y
yz = cy*xz - sy*x
yx = sy*xz + cy*x
-- rotation around z
zx = cz*yx - sz*xy
zy = sz*yx + cz*xy
 
-- now determine perspective scaling factor
-- yz was the last calculated z value so its the
-- final value for z depth
scaleRatio = focalLength/(focalLength + yz)
-- assign the new x and y
x = zx*scaleRatio
y = zy*scaleRatio
-- create transformed 2D point with the calculated values
-- adding it to the array holding all 2D points
TransformedPointsArray[i] = make2DPoint(x, y)
i = i -1
end
-- after looping return the array of points as they
-- exist after the rotation and scaling
return TransformedPointsArray
end
 
-- the points array contains all the points in the 3D
-- scene. These 8 make a square on the screen.
local pointsArray = {
make3DPoint(-50,-50,-50),
make3DPoint(50,-50,-50),
make3DPoint(50,-50,50),
make3DPoint(-50,-50,50),
make3DPoint(-50,50,-50),
make3DPoint(50,50,-50),
make3DPoint(50,50,50),
make3DPoint(-50,50,50),
}
 
-- an object to represent the 3 angles of rotation
local cubeAxisRotations = make3DPoint(0,0,0)
 
function newpoly(parent, color, p, v)
local shape = Shape.new()
shape:beginPath()
shape:setLineStyle(4, 0x00000000, 1)
shape:setFillStyle(Shape.SOLID, color, 0.5)
shape:moveTo(p[v[1]].y,p[v[1]].x)
shape:lineTo(p[v[2]].y,p[v[2]].x)
shape:lineTo(p[v[3]].y,p[v[3]].x)
shape:lineTo(p[v[4]].y,p[v[4]].x)
shape:lineTo(p[v[1]].y,p[v[1]].x)
shape:endPath()
parent:addChild(shape)
end
 
local lines = Sprite.new()
stage:addChild(lines)
 
local rotateCube = function()
stage:removeChild(lines)
lines = Sprite.new()
stage:addChild(lines)
 
cubeAxisRotations.y = cubeAxisRotations.y + userY
cubeAxisRotations.x = cubeAxisRotations.x + userX
 
-- create a new array to contain the 2D x and y positions of the
-- points in the pointsArray as they would exist on the screen
local screenPoints = Transform3DPointsTo2DPoints(pointsArray, cubeAxisRotations)
 
-- draw the polys
newpoly(lines, 0xff0000, screenPoints, { 1, 2, 3, 4 } )
newpoly(lines, 0x00ff00, screenPoints, { 5, 6, 7, 8 } )
newpoly(lines, 0x0000ff, screenPoints, { 1, 2, 6, 5 } )
newpoly(lines, 0xff00ff, screenPoints, { 2, 3, 7, 6 } )
newpoly(lines, 0x00ffff, screenPoints, { 3, 4, 8, 7 } )
newpoly(lines, 0xffff00, screenPoints, { 1, 4, 8, 5 } )
 
end
 
stage:addEventListener(Event.ENTER_FRAME , rotateCube )

Aye: MikeHart, atilim

Nay: jdbc

+1 -1 (+2 / -1 ) Share on Facebook

Comments

Sign In or Register to comment.