3D Cube - Filled Polygon & Wire frame Polygons

Started by kevin, April 26, 2025, 01:42:07 PM

Previous topic - Next topic

kevin

3D Cube - Filled Polygon & Wire frame Polygons


 This PlayBASIC program draws a spinning 3D cube on the screen. It shows two versions of the cube side-by-side — one filled with solid-colored faces (flat-shaded) and one drawn as a wireframe.

Here's how it works:

    Setup: It creates a random color palette for the cube's faces and sets up arrays to store the cube's 3D points (vertices) and the faces (which points connect to make each side).

    Scaling: The cube's points are scaled to a larger size using the SizeVerts function.

    Rotation: Every frame, the cube's points are rotated around the X, Y, and Z axes using a rotation matrix inside the RotateVerts function. This gives the cube its spinning effect.

    Projection: After rotation, the 3D points are projected onto the 2D screen so they can be drawn.

    Drawing: The DrawCube function draws each face twice:

        On the left side, it draws a filled, solid-colored polygon.

        On the right side, it draws just the wireframe (outline) of the face.

    Backface Culling: The code uses the cross product to check whether each face is pointing towards the viewer and only draws the visible ones.

    Animation: The cube keeps rotating smoothly because the tilt, turn, and roll angles are slightly increased every frame.

    Controls: Pressing the up arrow zooms the camera closer, and down arrow zooms out.



PlayBASIC Code: [Select]
 /*
This PlayBASIC program draws a spinning 3D cube using random colors. It scales the cube, rotates its points in 3D space, projects them onto the 2D screen, and draws each face as a filled shape on the left and a wireframe on the right. The cube rotates automatically and the camera distance can be adjusted with the up/down keys.

*/


// Colour palette for the cube faces
dim Palette(16)
for lp =0 to 16
Palette(lp) = rndrgb()
next

Rem create arrays to hold the points (vertex)
rem and face data for our cube.
Dim Points#(8,5)
Dim Faces(6,5)


Rem read in the vertex data
For p = 1 To 8
points#(p,1) = ReadData()
points#(p,2) = ReadData()
points#(p,3) = ReadData()
Next p

Rem Read in the face Data
For f = 1 To 6
faces(f,1) = ReadData()
faces(f,2) = ReadData()
faces(f,3) = ReadData()
faces(f,4) = ReadData()
Next f



Rem some space To put the rotated points
Dim rotated#(255,3)

Rem variables which control the size of the cube
x_scale# = 200.0
y_scale# = 200.0
z_scale# = 200.0

Rem set the initial rotation angles To 0
tilt#=0.0
turn#=0.0
roll#=0.0


SizeVerts(Points#(),x_scale#,y_scale#,z_scale#)

// distance from the viewer
Zdepth#=1000


Do

// clear the screen to rgb colour
cls $334455

// Rotate vertex
RotateVerts(points#(),Rotated#(),8,Tilt#,turn#,roll#,Zdepth#)

// Draw the cube projected to the screen
DrawCube()

Rem animate the tilt, turn And roll values
tilt# = tilt#+1.31
turn# = turn#+0.42
roll# = roll#+0.53

if upkey() and zdepth#>400 then Zdepth#=Zdepth#-20
if downkey() then Zdepth#=Zdepth#+20

// Flip the buffer to show user the frame and start rendering
// the new frame
Sync
loop





Function RotateVerts(Pts#(),RotatedPts#(),NumbOfVerts,Tilt#,turn#,roll#,ObjectDistance#)

ProjectionX#=400
ProjectionY#=400

cx=getscreenwidth()/2
cy=getscreenheight()/2


Rem prepare the rotation matrix
A#=Cos(tilt#):B#=Sin(tilt#)
C#=Cos(turn#):D#=Sin(turn#)
E#=Cos(roll#):F#=Sin(roll#)
AD#=A#*D#
BD#=B#*D#

; Calc Rotation Matrix
m11#=C#*E#
m21#=-1*C#*F#
m31#=D#
m12#=BD#*E#+A#*F#
m22#=-1*BD#*F#+A#*E#
m32#=-1*B#*C#
m13#=-1*AD#*E#+B#*F#
m23#=AD#*F#+B#*E#
m33#=A#*C#

Rem rotate all the points using the matrix
For p=1 To NumbOfVerts

pointx#=pts#(p,1)
pointy#=pts#(p,2)
pointz#=pts#(p,3)

rotatedPts#(p,1) = (m11# * pointx#) + (m12# * pointy#) + (m13# * pointz#)
rotatedPts#(p,2) = (m21# * pointx#) + (m22# * pointy#) + (m23# * pointz#)
rotatedPts#(p,3) = (m31# * pointx#) + (m32# * pointy#) + (m33# * pointz#)

Rem Now Do the perspective calculation
z# = rotatedPts#(p,3) + ObjectDistance#
rotatedPts#(p,1) = cx+ ((rotatedPts#(p,1)*ProjectionX# ) / z#)
rotatedPts#(p,2) = cy+ ((rotatedpts#(p,2)*ProjectionY# )/ z#)
Next p



Endfunction




Function DrawCube()
lockbuffer
For f=1 To 6
Rem p1 -> p4 are the points On the face
p1 = faces(f,1)
p2 = faces(f,2)
p3 = faces(f,3)
p4 = faces(f,4)

vx1#=rotated#(p1,1)
vy1#=rotated#(p1,2)

vx2#=rotated#(p2,1)
vy2#=rotated#(p2,2)

Login required to view complete source code