74 lines
2.0 KiB
Plaintext
74 lines
2.0 KiB
Plaintext
import "mathUtil"
|
|
scale = 250
|
|
radius = sqrt(scale^2)
|
|
|
|
Face = new Sprite
|
|
Face.image = file.loadImage("/sys/pics/shapes/SquareThin.png")
|
|
|
|
clear; gfx.clear color.gray
|
|
sprites = display(4).sprites
|
|
|
|
// build a sprite for each side
|
|
for i in range(0, 3)
|
|
sp = new Face
|
|
sp.x = 480; sp.y = 320
|
|
yBot = -sin(pi/4)
|
|
yTop = sin(pi/4)
|
|
cosAngL = cos(i*pi/2); sinAngL = sin(i*pi/2)
|
|
cosAngR = cos((i+1)*pi/2); sinAngR = sin((i+1)*pi/2)
|
|
sp.corners3d = [
|
|
[cosAngL, yBot, sinAngL], [cosAngR, yBot, sinAngR],
|
|
[cosAngR, yTop, sinAngR], [cosAngL, yTop, sinAngL] ]
|
|
sp.color = [color.yellow, color.aqua, color.pink, color.lime][i]
|
|
sprites.push sp
|
|
end for
|
|
// ...and one for the top
|
|
top = new Face
|
|
top.x = 480; top.y = 320
|
|
top.corners3d = []
|
|
for i in range(0, 3)
|
|
top.corners3d.push [cos(i*pi/2), sin(pi/4), sin(i*pi/2)]
|
|
end for
|
|
sprites.push top
|
|
|
|
// Rotate the given [x,y,z] point by some number of degrees
|
|
// around the Y axis, then project to the screen.
|
|
rotateAndProject = function(point3d, rotDegrees)
|
|
radians = rotDegrees * pi/180
|
|
cosAng = cos(radians); sinAng = sin(radians)
|
|
// First, rotate around the Y axis in 3D space
|
|
x = point3d[0] * cosAng - point3d[2] * sinAng
|
|
y = point3d[1]
|
|
z = point3d[0] * sinAng + point3d[2] * cosAng
|
|
// Then, project this to the screen
|
|
result = [480 + x * scale, 320 + y * scale + z*0]
|
|
p = (8 - z) / 8 // (perspective factor)
|
|
return mathUtil.lerp2d(result, [480,800], 1-p)
|
|
end function
|
|
|
|
// Position all the sprites where they should be on screen for the given rotation.
|
|
positionSprites = function(rotDegrees)
|
|
for sp in sprites
|
|
corners = []
|
|
for i in range(0,3)
|
|
corners.push rotateAndProject(sp.corners3d[i], rotDegrees)
|
|
end for
|
|
sp.setCorners corners
|
|
if sp == top then continue
|
|
if corners[1][0] > corners[0][0] then
|
|
sp.tint = sp.color
|
|
else
|
|
sp.tint = color.clear
|
|
end if
|
|
end for
|
|
end function
|
|
|
|
// Main program
|
|
rot = 0
|
|
while not key.pressed("escape") and not key.pressed("q")
|
|
yield
|
|
positionSprites rot
|
|
rot = rot + 1
|
|
end while
|
|
key.clear
|