I wanted to create a program to demonstrate the wide applicability of the QB64 _MAPTRIANGLE procedure for creating impressive graphics applications. _MAPTRIANGLE, most especially _MAPTRIANGLE(3D), is another amazing and supremely useful QB64 coding technique, and can be easily implemented by the novice coder. I include myself very much within this group (not so much a QB64 novice as a low-skill member - most of the techniques of QB64 and virtually all of the discussions at this website are way above my understanding).
Whilst QB64 allows the creation of 'real' 3D graphics applications with the use of _GL methods (wonderfully demonstrated here by Ashish in particular), I do not have the faintest understanding of the technique - a survey of the _GL commands in wiki is just incomprehensible. But I have used _MAPTRIANGLE(3D) in the past, and so could any of our members.
The idea of creating a Coin-tossing simulation seemed a good basis to demonstrate _MAPTRIANGLE(3D) abilities. A search of the website suggests that this has not been attempted in the past, so this looked to be a good project with the goal of simulating a 50-50 Heads-Tails toss of a spinning coin.
To simulate a coin-tossing, the basic starting points were:
- A thin cylindrical 'solid' body with two different faces.
The body describes a 3D path where it moves under a constant downward gravitational acceleration.
In travelling such a path, the body spins upon an axis through a fixed diagonal.
Upon hitting a solid flat surface the coin settles to lay flat - which way it falls determined by the angle at which it hit that surface.
A degree of randomness in the flight so that there is a 50-50 chance of falling on each face.
To give a good representation of a coin shape in 3D, the graphics image was constructed in the following manner. Websites scanned for attractive images of the two faces of a coin in flat right-angle view. The milled edge was created in code to give cyclic lighter-darker regions (which looks pretty realistic).
The flat faces are mapped into the _MAPTRIANGLE(3D) space by cutting the faces into radial triangular segments. The coding to do this was reasonably simply and was achieved in pretty short time. This is the beauty of _MAPTRIANGLE(3D).
The motion of the coin in the 3D space was easy to code. The starting assumptions were:
- The coin travels in a straight line (the x- axis of the _MAPTRIANGLE(3D) space) with constant speed.
After being launched from the starting position, the coin spins at a constant rotation.
The initial upward (_MAPTRIANGLE(3D) space y-axis) varies at each toss. This sets the (random) time of flight.
The _MAPTRIANGLE(3D) view is rotated in the y-axis (vertical) to give a perspective view of the coin travel.
Getting the equations correct for the coin rotation and the horizontal and vertical motions was a doddle, of course. The complicated part was in working out the appropriate equations for the landing of the coin and its subsequent fall to the landing surface. The coin is going to land on one of four edge corners (front and rear faces meeting the edge 'up' and 'down'). In fact this is the simplest of trigonometry, working out triangle geometry, but it took me ten times longer doing this to get it correct for all conditions than it did to code the graphics - again this demonstrates the user-friendliness of _MAPTRIANGLE(3D).
The first video shows the running program with consecutive tails and heads. The graphics are pretty convincing, with realistic coin rotation, movement, landing and settling. When the coin has landed it falls to the nearest horizontal angle. The coin has no inertial mass even though it has gravitational mass. The coin rotation rate (and overall speed) is a compromise between showing the full movement and the time taken for a tossing event. With a faster display speed the spinning would hardly be noticeable, but even so a single event takes much longer than a real coin would. Even so, the rotation is rather difficult to appreciate and even appears unnatural at times (somewhat distorted by the perspective of the 3D space). The second video shows the process happening at a slowed-down rate and it is clear that the coin truly spins as in reality.
To run the program, download and extract the zip file. Place the folder "Flippin' Coin" in your QB64 folder and load the Coin Toss bas file.
https://www.dropbox.com/s/4navhbwrta780e4/Flippin%27%20Coin.zip?dl=1Press the Spacebar to initiate a toss. The coin will land either heads up or tails up (this you would expect!). Depending upon which of the four edge corners the coin lands on, it will either settle backwards as in the video (this is by far the usual case) or forwards. You may have as many goes as you wish. Esc to Quit.
Data gathering was performed using a calculation-only program (no graphics) over 2000 cycles and it was found that the heads-tails ratio was 50-50 to within 1% - pretty good! Because of the simple assumptions and idealised mathematical model there may be a slight bias for one particular face (if there was, it was tails).
The display could be enhanced with more appealing additional graphics, and I had intended to add an animated launch spigot, but as-is the program does its job of showing _MAPTRIANGLE(3D)'s capabilities.