Simple screen graphics with MSX Basic; part 2.David H. Ahl.

Simple Screen Graphics With MSX Basic

While the turtle graphics feature of the Logo language is certainly useful to generate geometric figures, the old fashioned method using Basic with polar equations can produce similar results.

We start with a Basic program loosely modeled on one by Alan Foxx that appeared in the November issue of inCider. It will produce a polygon with any desired number of sides. Since trig functions on the computer require the arguments to be expressed in radians, we will work with multiples of pi. In this program, pi is divided by the number of sides (line 50) and the result, SP, is used as the step size for computing angles in the loop (lines 70-140).

10 CLS:PRINT TAB(15); "Polysons':PRINT

20 PI=3. 14159

30 INPUT "Number of sides'; SD

40 INPUT "Size (5 to 150)'; SIZE

50 SP=PI/SD

60 SCREEN 1

70 FOR A=0 TO PI+SP/2 STEP SP

80 SZ"SIZE*SIN(A)+.5

90 X=SZ*SIN(A)+60

100 Y=SZ OS(A)+96

110 IF A=0 THEN 130

120 LINE (X0, Y0)-(X, Y)

130 X0=X:Y0=Y

140 NEXT

150 GOTO 150

Theoretically, the loop should go from 0 to pi, and if the number of sides divide pi into exactly even multiples, this will work. However, this rarely happens, so the last leg of the polygon is not completed; hence, we add one-half of the step size to pi and make that the upper limit of the loop (line 70).

The size of the polygon input in line 40 is roughly the diameter of the circle enclosing the polygon. This is scaled to the length of a side (SZ) in line 80.

After the x and y coordinates of both ends of the line segment are calculated, the line is drawn with the LINE statement in line 120. In line 130, the end points of the line just drawn are redefined as the starting points of the next segment.

Figure 1 shows a six-sided polygon (hexagon) of size 120, and Figure 2 shows a figure with 90 sides of size 150. As the number of sides in a multi-sided polygon approaches infinity, the figure approaches a circle. However, because of the finite resolution of the screen, we do not have to get anywhere near infinity to get a figure that looks like a circle. Use the circle command to draw a circle and compare it with the one produced by this program; with roughly how many sides do they look the same?

This program can be simplified slightly by dividing two pi (360 degrees or a full circle) by the number of sides. This allows line 80 to be eliminated, although now the size input in line 40 is the length of a side and not the diameter of the polygon.

10 CLS: PRINT TAB(15); "Polysons': PRINT

20 PI=3. 14159: TP=PI*2

30 INPUT "Number of Sides';SD

40 INPUT "Size (5 to 80)';SZ

50 SP=TP/SD

60 SCREEN 1

70 FOR A=0 TO TP+SP/2 STEP SP

90 X=SZ*SIN(A)+100

100 Y=SZ OS(A)+96

110 IF A=0 THEN 130

120 LINE (X0, Y0)-(X, Y)

130 X0=X:Y0=Y

140 NEXT

150 GOTO 150

You will notice that the orientation of polygons is slightly different with this program. For example, compare the hexagon in Figure 3 (made with this program) to the one in Figure 1.

Concentric Polygons

We next would like to draw concentric or nested polygons. To do so requires a modification of line 40 to put the size in a new variable, SI. Then lines

40 INPUT "Size (5 to 80)'; SI

65 FOR SZ=XI TO SI/5 STEP -10

145 NEXT

65 and 145 create a loop outside the entire polygon plotting procedure to decrease the size of successive polygons by ten (from SI down to SI/5). Figures 4 and 5 show the output from this modification.

Let's say that instead of exactly concentric polygons, we would like less distance on one side than the other. This is easily accomplished by adding an additional amount to the x distance in line 90. For example, we could add one third of SZ which would produce the hexagon in Figure 6.

90 X=SZ*SIN(A)+100+SZ/3

Or, if we wanted a greater offset, we could add a larger quantity, say SZ. The output from this change is shown in Figure 7.

90 X=SZ*SIN(A)+100+SZ

Of course, it is possible to add an offset in both the x and y direction. Lines 90 and 100 offset both x and y by SZ/2.

90 X=SZ*SIN(A)+100+SZ/2

100 Y=SZ OS(A)+50+SZ/2

The result is shown in Figure 8.

Multiple Polygons

Next, let's take the basic polygon generating program (you can make it into a subroutine if you wish) and use it to make several polygons at different points on the screen. To draw two polygons, one offset from the other by 80 units, we could add the following four lines.

45 I=80

90 X=SZ*SIN(A)+I

150 IF I=80 THEN I=160:GOTO 65

160 GOTO 160

The distance I, initially 80, is added to all x distances and, when the first plot is finished, a second one is made with an I distance of 160 (see Figure 9).

However, if we want to add more polygons, we can use a routine similar to that used to produce the polygons in the first place. For example, to produce four sets of polygons, we could add the following four lines.

61 FOR B=0 TO TP STEP TP/4

62 X2=100*SIN(B)

63 Y2=100 OS(B)

150 NEXT

The result of doing this is shown in Figure 10--not exactly what we had in mind. The problem is that there is too much distance between the polygons. Let's decrease the distance to 30 units with new lines 62 and 63.

62 X2=30*SIN(B)

63 Y2=30 OS(B)

The result of this change is shown in Figure 11. Ah, that's more like it. At the moment, the orientation of both the inside and outside polygon (square) is the same. If we change the starting point from 0 to TP/8 (one-eighth of two pi, or one-half of each angle, or 45 degrees), and increase the ending point a similar amount, the square flops on its side (see Figure 12).

61 FOR B=TP/B TO TP+TP/8 STEP TP/4

However, there is no reason to restrict our outside polygon to a square. Actually, why not let it be the same polygon as the concentric ones? This is easily accomplished with the following two lines.

50 SP=TP/SD:LM=TP/(SD*2)

61 FOR B=LM TO TP M STEP SP

If you run this, you will find that the first polygon that was drawn is traced over a second time--and not always in exactly the same place as the first one. We can eliminate this overtrace by lowering the upper limit of the loop by one-half of the angle (LM). The result is shown in Figures 13 and 14.

61 FOR B=LM TO TP STEP SP

Now let's say that we would like to spread out the image in the horizontal direction to fit the dimensions of the screen better. This can be done by adding a larger offset in the x direction than the y direction. Compare the image in Figure 15 made with a 50-unit x multiplier and 30-unit y multiplier to Figure 13 made with equal 30-unit x and y multipliers.

62 X2=50*SIN(B)

Some of the effects, particularly the moir[e patterns can be made more interesting by changing the distance between the concentric polygons. For example, adding the following line 65 results in a pattern with closer spacing (see Figure 16).

65 FOR SZ=SI TO SI/5 STEP -6

After some experimentation, we determined that the outside group of polygons should be spaced closer together if they have a small number of sides and spread apart if they have more sides. This change can be made by letting the distance between outside polygons be a function of the number of sides. This has been made in the new lines 62 and 63 below. We have also increased the spacing between concentric polygons in line 65. The results are shown in Figure 17.

62 X2=(SI*SD/10)*SIN(B)

63 Y2=(SI*SD/12) OS(B)

65 FOR SZ=SI TO SI/5 STEP -8

We have made so many changes to the basic program that it is time to see where we are. Let us use the RENUM function and print the program as it currently stands. Figure 18 was made with this program.

10 CLS:PRINT TAB(15); "Polysons':PRINT

20 PI"3. 1415926536#:TP=PI*2

30 INPUT "Number of Sides'; SD

40 INPUT "Size (5 to 70)'; SI

50 SP=TP/SD:LM=TP/(SD*2)

60 SCREEN 1

70 FOR B=LM TO TP STEP SP

80 X2=(SI*SD/10)*SIN(B)

90 Y2=(SI*SD/12) OS(B)

100 FOR SZ=SI TO SI/5 STEP -8

110 FOR A=0 TO TP+SP/2 STEP SP

120 X=SZ*SIN(A)+128+X2

130 Y=SZ OS(A)+96+Y2

140 IF A=0 THEN 160

150 LINE (X0, Y0)-(X, Y)

160 X0=X:Y0=Y

170 NEXT

180 NEXT

190 NEXT

200 GOTO 200

There are some other things that can be varied to achieve different effects. For example, because of the screen layout, the distance between horizontal (x) pixels is slightly longer than between vertical (y) pixels. Thus, a square drawn on the screen with the true mathematical coordinates is not truly square, but has angles of about 82 and 98 degrees. We can correct this by multiplying y distances by 1.1 (this is not precisely correct, but it is very close). Figure 19 was made using this correction in line 130.

130 Y=1.1* (SZ OS(A))+96+Y2

Instead of rotating the outside polygon exactly one-half of the angle of each corner, we can add a small factor and achieve somewhat different effects. Figure 20 shows the effect of this; compare it to Figure 18.

50 SP=TP/SD:LM=TP/(SD*2)+.07

Concentric polygons can be spaced together even more closely--say at a distance of five or fewer units--to produce very dense patterns. Figure 21 was produced with five-unit spacing using this line 100.

100 FOR SZ=SI TO SI/5 STEP -5

Combined Effects

Some really dramatic effects can be achieved by combining several different approaches. Specifically, combining the x or y offset (Figures 6 to 8) with the outer group of polygons (Figures 12 to 19) produces some very interesting effects. They are particularly interesting if the tight spacing between rings is toward either the center or the outside of the entire image. This can be done with very few additional program lines.

Another fascinating effect can be achieved by letting the polygon move across the image area, either staying the same size or decreasing in size. This involves simply adding a constant x offset in line 80 (see Figure 22). When this is combined with the concentric rings and/or a rotating outside group, some amazing effects are produced.

We have deliberately not pictured these effects, because we want you to discover things on your own and not be bound to our directions. We have set you moving; now it is up to you to go in the direction you want.

Yes, we promised spirals and the Sierpinskey curve in this tutorial, but they will just have to wait until next time. Until then . . ..

Photo: Figure 1. Hexagon produced by basic polygon program.

Photo: Figure 2. Polygon with 90 sides, size 150.

Photo: Figure 3. Hexagon made with second basic polygon program.

Photo: Figure 4. Concentric pentagons, size 80.

Photo: Figure 5. Nine-sided figure, size 80.

Photo: Figure 6. Horizontal (x) dimension offset by SZ/3.

Photo: Figure 7. Horizontal offset by SZ.

Photo: Figure 8. Both x and y offset by SZ/2.

Photo: Figure 9. Two hexagons of size 80 (side), 80 units apart.

Photo: Figure 10. Four hexagons (size 80), 100 units apart.

Photo: Figure 11. Four squares (size 50), 30 units apart.

Photo: Figure 12. Same as Fig. 11, but outside square rotated 45 degrees.

Photo: Figure 13. Generalized routine to draw outside polygon.

Photo: Figure 14. Generalized routine with eight sides, size 60.

Photo: Figure 15. Horizontal (x) offset increased to 50; y is 30.

Photo: Figure 16. Closer spacing of concentric polygons (6 units) produces interesting patterns.

Photo: Figure 17. Routine added to make spacing of outer polygon a function of the number of sides.

Photo: Figure 18. Triangles with five-unit concentric spacing.

Photo: Figure 19. Correction made for screen distortion.

Photo: Figure 20. Small factor added to starting point of outer polygon rotation.

Photo: Figure 21. Hexagons of size 60 with five-unit concentric spacing.

Photo: Figure 22. Adding a constant factor to x lets the polygon move across the image area.