IMAGE WRAP AND SPIN

Use this short program by Nathan Williams to wrap flat images around a sphere, and spin them anywhere on the screen.

You will need at least 50K of sprite space to run this program.

You may have seen Arc screen displays of rotating worlds similar to the BBC1 world logo. The technique used to generate these is to produce a single flat world map (i.e. a Mercator projection), and then wrap it around a sphere. To give the impression of rotation, a series of wrapped images are created from the original flat map, each differing from the next by a few degrees. When the sequence is played back a very powerful impression of rotation is created.

The accompanying program uses similar techniques, but since it is written in Basic, and has been made modular, it is easy to adjust to provide different effects. If you type it in and run it as it stands, you will see a rectangular image containing the words "RISC USER" at the bottom left hand corner of the screen. This serves as the image to be wrapped. The wrapping process begins immediately, and you will see a spherical transform of the flat map slowly build up in the upper right-hand quadrant of the screen.

As soon as the image is complete, it will be stored in the machine's sprite area as a sprite named Sphere1, and a new spherical image, similar to the first, but offset by a small rotational angle, will be generated. This will be stored as the sprite Sphere2. The process will continue until the sphere has been mapped from all angles, and the display will then begin. This simultaneously rotates three spheres, each carrying the RISC USER title.

It is possible to save the sprites used by the program. To do this, press Escape during the display phase, and use:
*SSAVE mysprites
To make use of the sprites at any time, use:
*SLOAD mysprites
Then, with the program in memory, type:
PROCplay

As I mentioned earlier, the program is easily customisable. You can change the original image, the size of the sphere, the angle of rotation, and the lighting and reflective properties of the sphere. You can also alter the program so that it generates just a single wrapped image rather than a whole sequence.

Firstly, the original image: this is generated by PROCscreen, which may be replaced by your own routine. The image used must be twice as wide as it is high, and its height must be equal to the value held in the variable map% (in PROCinit). This is currently set to 96 for an image 192x96 graphics units in size.

The size of the resultant sphere is determined by the variable rad%, set up in PROCinit. This is currently set to 75. Remember that increasing this will radically affect the space needed to store the resultant sprites, and the time taken to generate them.

To alter the rotation from vertical to horizontal, change the main FOR loop variable in line 120 from anglev to angleh.

The angle of lighting of the sphere is determined by the x, y and z co-ordinates of the light source, held in the variables lx, ly and lz (defined in PROCinit), which range in value from -1 to +1. To remove the shading effect, set the variable shaded to FALSE in line 260, and to remove the highlighting effect, set the variable highl to FALSE in line 270.

If the shading effect is to work fully, then the original flat image should only use colours of maximum brightness. That is to say for example, if there is a blue component in a given colour, it must be maximum blue. The reason for this is that shading is achieved by reducing the intensity of each component of a given colour, and if colour components are at half intensity at the start, the result of shading may be to alter the colour rather than the shade of a given pixel. If the colours of an image do not contain full intensity components, such as would be the case for a digitised image, for example, it will be best to remove the shading option; though you should be aware that the current program does not pick up tint information when transferring each pixel to the sphere.

There is already plenty to experiment with here, but there is even greater scope for altering PROCplay. At present, this displays three spinning spheres. But you could alter the plotting positions so that one or more spheres appears to bounce around the screen. Remember, though, that if you intend to have more than one moving sphere on screen, then you will need to use bank switching to achieve smooth animation, since you will not be able to use Exclusive OR plotting to erase previous images.

10 REM >Wrap
20 REM Program Image Wrap
30 REM Version A 0.3
40 REM Author Nathan Williams
50 REM RISC User March 1989
60 REM Program Subject to Copyright
70 :
80 ON ERROR MODE 13:PRINT REPORT$;" @ line ";ERL:END
90 MODE13:OFF
100 PROCscreen
110 PROCinit
120 FOR anglev=0 TO 2*PI STEP PI/15
130 PROCsphere(rad%,anglev,angleh)
140 PROCgetsphere(rad%)
150 NEXT
160 PROCplay
170 END
180 :
190 DEFPROCinit
200 DIM col%(20,3)
210 ORIGIN 840,712
220 FOR C%=0 TO 13
230 READ col%(C%,1),col%(C%,2),col%(C%,3)
240 NEXT
250 lx=-0.55:ly=0.5:lz=0.7:REM Light
260 shaded=TRUE: REM Shading On
270 highl=TRUE: REM Highlight On
280 map%=96: REM Image Height
290 rad%=75: REM Sphere Radius
300 HP=PI/2:sprite%=1
310 anglev=0:angleh=0
320 ENDPROC
330 :
340 DEFPROCscreen
350 GCOL 0,12:RECTANGLE FILL 0,0,384,192
360 COLOUR 140 TINT 240:COLOUR 0
370 PRINTTAB(1,28);"RISC"
380 COLOUR 3
390 PRINTTAB(1,29);"USER"
400 COLOUR 32:PRINTTAB(0,27);" * *"
410 PRINTTAB(0,30);" * *"
420 MOVE 300,100
430 FOR J%=1 TO 20
440 GCOL 0,RND(63)
450 DRAW 224+RND(128),32+RND(128)
460 NEXT
470 ENDPROC
480 :
490 DEFPROCsphere(R%,anglev,angleh)
500 COLOUR 63:COLOUR 128 TINT 0
510 PRINTTAB(0,1)"Sprite ";sprite%
520 FOR Y%=R% TO -R% STEP -4
530 FOR X%=R% TO -R% STEP -4
540 Z%=FNgetz(X%,Y%)
550 IF Z%>0 THEN
560 PROCtransform(X%,Y%,Z%,anglev,angleh)
570 PROCgcol(X,Y)
580 PLOT 69,X%,Y%
590 ENDIF
600 NEXT
610 NEXT
620 ENDPROC
630 :
640 DEFPROCgetsphere(R%)
650 MOVE -R%,-R%:MOVE R%,R%
660 OSCLI("SGET sphere"+STR$(sprite%))
670 sprite%=sprite%+1
680 ENDPROC
690 :
700 DEFFNgetz(X%,Y%)
710 Z%=rad%^2-X%^2-Y%^2
720 =Z%
730 :
740 DEFPROCtransform(X%,Y%,Z%,anglev,angleh)
750 newz=SQR(Z%)*COS(anglev)-Y%*SIN(anglev)
760 newy=Y%*COS(anglev)+SQR(Z%)*SIN(anglev)
770 theta=X%/SQR(X%^2+newz^2)
780 X=rad%*ASN(theta)
790 Y=rad%*ATN(newy/SQR(newz^2+X%^2))
800 IF newz<0 THEN X=(PI*R%)-X
810 X+=rad%*angleh
820 ENDPROC
830 :
840 DEFPROCgcol(X,Y)
850 colour%=FNcol(X,Y)
860 brightness=FNbright(X%,Y%,SQR(Z%))
870 highlight%=(brightness*13+RND(1)/15)
880 light%=(brightness*12+RND(1))
890 IF shaded THEN colour%=colour% AND col%(light%,1):tint%=col%(light%,2) ELSE tint%=0
900 IF highl THEN colour%=colour% OR col%(highlight%,3)
910 GCOL 0,colour% TINT tint%
920 ENDPROC
930 :
940 DEFFNcol(X,Y)
950 x%=X/rad%/HP*map%:y%=Y/R%/HP*map%
960 x%=(x%+map%) MOD (map%*4):y%=(y%+map%) MOD (map%*2)
970 =POINT(x%-840,y%-712)
980 :
990 DEFFNbright(x%,y%,z%)
1000 x=x%/rad%:y=y%/rad%:z=z%/rad%
1010 =(x*lx+y*ly+z*lz)/2+.5
1020 :
1030 DATA %01010101,63,0,%01010101,63,0
1040 DATA %01010101,127,0,%01010101,191,0
1050 DATA %10101010,63,0,%10101010,127,0
1060 DATA %10101010,191,0,%10101010,255,0
1070 DATA %11111111,63,0,%11111111,127,0
1080 DATA %11111111,191,0
1090 DATA %11111111,255,0
1100 DATA %11111111,255,%010101
1110 DATA %11111111,255,%101010
1120 :
1130 DEFPROCplay
1140 MODE 13
1150 ORIGIN 0,0
1160 REPEAT
1170 FOR J%=1 TO 30
1180 OSCLI("SCHOOSE sphere"+STR$(J%))
1190 PLOT &ED,0,500
1200 PLOT &ED,880,500
1210 PLOT &ED,440,50
1220 WAIT:WAIT
1230 NEXT
1240 UNTIL FALSE
1250 ENDPROC