This simulation depends on the simple principal of projection of points. When you have some points in a space, joined by lines, their projection forms a 3D wireframe image. Moreover, the projection can simply be considered the X and Y positions of the points, since projecting a point is equivalent to equalizing the Z coordinate. In other words, if a point has coordinates (X,Y,Z) we can project its image as (X,Y) on the screen.
To represent points, we will use three lists, representing X, Y, and Z positions, respectively, so the coordinates of point N are (X[N], Y[N], Z[N]). The order of points describes the path of the "wire". To draw the wireframe, we move sprite through all the projected positions with the pen down, such that the trail will be the projection of the model.
Implementation of Static Models
To implement a static model, we use this script:
when gf clicked forever clear // clear screen pen up // stop drawing set [n v] to (0) // iterator repeat (length of [X v]) // for all coordinates change [n v] by (1) // iterate go to x: (item (n) of [X v]) y: (item (n) of [Y v]) // trace projection pen down // put the pen down end end
Generating models is really hard by hand-editing the lists. A much easier way to generate these lists is via visual editing with programs like Blender. Python scripts can be created to reference Blender models and write them to text files, which can then be imported into Scratch. Alternatively, simple Scratch programs to generate random test models are also easy to build. For example, we can make a simple program to follow mouse trails and constantly add these to the coordinate lists with a constant Z axis.
It may also be possible to create a project that can convert an exported modeler Wavefront file into project-readable format.
Implementing rotation is much harder. We need to update the entire list of coordinates with new, displaced positions in every cycle. This is time-consuming, so the end result may run extremely slowly. A good way to avoid it is by using Turbo Mode, or, even more ambitiously, by making the script Single Frame.
Firstly, we can without loss of generality implement rotation in one axis, and then modify it for the others. This tutorial implements rotation in the up-down (Y) axis, implementation of the rest is left to the reader. Next, we can implement rotation for just one point, and by rotating all points around a fixed axis (Y axis through 0,0,0) we can rotate the entire model. So, the problem can be reduced to rotating a point at X,Y n degrees about 0,0.
|Note:||Here, remember "Y" is actually the Z position, since when we look at the model from the top the axes are inverted. From now on, X refers to the X position, Y to the Z, and Z to the original Y position.|
The rotation is implemented via trigonometry. We note the angle between the X axis and the line from the point to the origin, and add n. Finally, we use that and the knowledge of the distance between the point and origin (remember, this remains constant) to plot the new location. To find the original angle, we use the arctan function. Letting that angle be a,
So, the total angle rotated is
Finally, the new X and Y positions can be found with the formulae
where d is the distance between the point one origin. We find d by the Pythagoras Theorem:
Having found the new X and Y, we can now replace the coordinates of the point with the rotated coordinates.
|Note:||This explanation is extremely rough. In reality, we need to consider negative cases since trig functions of integers vary. These are all handled with special cases.|