Two illusions, one visual [the Penrose stairs] and one audible [the Shepard scale], are combined in James Allwright's cunning program. A man walks up a closed uphill staircase to the sound of notes which appear to be constantly rising in pitch.

The staircase was originally drawn by M C Escher. It is a three-dimensional projection drawing for which some parameters are:

D -- distance of observer from screen

SF -- scale factor

VY and SF -- constants which can be chosen fairly arbitrarily

SS -- step size

VX -- constant which must be adjusted to make the illusion work.

The UD at line 180 is the delay time. If you cannot tell what is going on you may reduce this but the author suggests that you do so only as a last resort.

Run the program in JSBeeb:

Here's the listing:

Code: Select all

```
10 REM
20 REM "Climbing Man"
30 REM
40 REM by James Allwright
50 REM
60 REM
70 REM With Acknowledgements to
80 REM
90 REM The Royal Institution
100 REM
110 REM Christmas Lectures for the
120 REM
130 REM original demonstration.
140 REM
150ONERRORVDU4:ONERROROFF:END
160DIMMX(35),MY(35),MN(35)
170DISP=40:D=3000:SF=130:VX=D+6*SF:VY=4000
180SS=VY*2*SF/(16*D+70*SF):UD=30
190VDU23,224,0,0,6,&F,&1F,&1F,&1F,&C
200VDU23,225,4,&C,&1E,&3E,&7F,&DF,&9F,&BF
210VDU23,226,&FF,&FE,&7E,&7E,&7E,&F8,&F0,&E0
220VDU23,227,0,0,0,1,3,3,7,&F
230VDU23,228,&FF,&FF,&C1,&C0,&80,0,0,0
240VDU23,229,0,&80,&80,&C0,&66,&3E,&1C,&18
250VDU23,230,&E,&1C,&18,&30,&60,&C0,&F0,&F0
260VDU23,231,&F8,&FC,&CE,&C7,&C3,&C1,&C0,&C1
270VDU23,232,0,0,0,0,&80,&C0,&C0,&C0
280VDU23,233,&C7,&CC,&CC,&CE,&C6,&C0,&F0,&F0
290VDU23,234,0,0,0,&18,&3C,&7E,&3C,&18
300VDU23,235,0,0,0,1,3,7,6,6
310VDU23,236,&7E,&FF,&FF,&FF,&7E,&7E,&7E,&7E
320VDU23,237,0,0,0,&80,&C0,&E0,&60,&60
330VDU23,238,4,4,6,2,2,0,0,0
340VDU23,239,&7E,&7E,&7E,&7E,&7E,&7E,&7E,&7E
350VDU23,241,&7E,&66,&66,&66,&66,&C6,&C6,&66
360VDU23,242,6,6,6,6,6,6,6,6
370VDU23,243,&7E,&66,&66,&66,&66,&63,&63,&66
380VDU23,244,&60,&60,&60,&60,&60,&60,&60,&60
390VDU23,245,0,0,&60,&F0,&F8,&F8,&F8,&30
400VDU23,246,&20,&30,&78,&7C,&FE,&FB,&F9,&FD
410VDU23,247,&FF,&7F,&7E,&7E,&7E,&1F,&F,7
420VDU23,248,0,0,0,&80,&C0,&C0,&E0,&F0
430VDU23,249,&FF,&FF,&83,3,1,0,0,0
440VDU23,250,0,1,1,3,&66,&7C,&38,&18
450VDU23,251,&70,&38,&18,&C,6,3,&F,&F
460VDU23,252,&1F,&3F,&77,&E3,&C3,&83,3,&83
470VDU23,253,0,0,0,0,1,3,3,3
480VDU23,254,&E3,&33,&33,&73,&63,3,&F,&F
490MODE1
500MOVEDISP,0:DRAWDISP,DISP
510PROCMV(SF,0,5*SF):PROCMV(SF,0,SF)
520PLOT85,FNX(SF,5*SF),FNY(0,SF)
530MOVEFNX(6*SF,4*SF),0:MOVEFNX(6*SF,0),0
540PROCTRI(6*SF,8*SS,4*SF):PROCTRI(6*SF,8*SS,0)
550X=5*SF
560FORA=0TO2:Z=A*SF:Y=(5+A)*SS
570PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
580PROCQUAD(X,Y,Z+SF,X+SF,Y,Z+SF,X+SF,Y+SS,Z+SF,0)
590NEXT
600Z=3*SF
610FORA=0TO2:X=(5-A)*SF:Y=(8+A)*SS
620PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
630PROCQUAD(X,Y,Z,X,Y,Z+SF,X,Y+SS,Z+SF,3)
640NEXT
650X=0
660FORA=5TO1STEP-1:Y=-A*SS:Z=A*SF
670PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
680IFA<>5PROCMV(X+SF,Y,Z):PROCMV(X+SF,Y,Z+SF):PROCTRI(X+SF,Y-SS,Z+SF)
690NEXT
700Z=0
710FORA=0TO5:X=SF*A:Y=A*SS
720PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
730IFA<>5PROCMV(X+SF,Y+SS,Z):PROCMV(X+SF,Y,Z):GCOL0,0:PROCTRI(X+2*SF,Y+SS,Z):GCOL0,3:PROCMV(X+SF,Y+SS,Z):PROCDW(X+SF,Y,Z)
740NEXT
750FORA=0TO10:MN(A)=A MOD2
760MX(A)=FNX((A DIV2+0.5)*SF,SF/2)
770MY(A)=FNY((A DIV2)*SS,SF/2)
780NEXT
790FORA=11TO17:MN(A)=2+A MOD2
800MX(A)=FNX(5.5*SF,SF*(A-10)/2)
810MY(A)=FNY(((A-1)DIV2)*SS,SF*(A-10)/2)
820NEXT
830FORA=18TO24:MN(A)=4+A MOD2
840MX(A)=FNX((29-A)DIV2*SF+SF/2,3.5*SF)
850MY(A)=FNY(((A-2)DIV2)*SS,3.5*SF)
860NEXT
870FORA=25TO35:MN(A)=2+A MOD2
880MX(A)=FNX(SF/2,((35-A)/2)*SF+SF/2)
890MY(A)=FNY(-((35-A)DIV2)*SS,((35-A)/2)*SF+SF/2)
900NEXT
910GCOL3,1:VDU19,1,2,0,0,0:VDU19,2,2,0,0,0:VDU5
920A%=0:N%=0
930REPEAT
940PROCMAN(MN(A%),MX(A%),MY(A%))
950IF(A%MOD2)<>0SOUND0,0,0,UD/2:GOTO1000
960SOUND&300,0,0,UD/2:N%=(N%+1)MOD36
970SOUND&301,INT(ABS(18-N%)*5/6)-15,53+4*N%,UD
980T%=(N%+12)MOD36:SOUND&302,INT(ABS(18-T%)*5/6)-15,53+4*T%,UD
990T%=(N%+24)MOD36:SOUND&303,INT(ABS(18-T%)*5/6)-15,53+4*T%,UD
1000PROCMAN(MN(A%),MX(A%),MY(A%)):A%=(A%+1)MOD36
1010UNTIL0
1020END
1030DEFPROCQUAD(X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,C)
1040X4=X1+X2-X3:Y4=Y1+Y3-Y2:Z4=Z1+Z3-Z2
1050GCOL0,C
1060PROCMV(X2,Y2,Z2):PROCMV(X1,Y1,Z1)
1070PROCTRI(X3,Y3,Z3):PROCTRI(X4,Y4,Z4)
1080GCOL0,3-C
1090PROCMV(X1,Y1,Z1):PROCDW(X2,Y2,Z2)
1100PROCDW(X3,Y3,Z3):PROCDW(X4,Y4,Z4)
1110PROCDW(X1,Y1,Z1)
1120ENDPROC
1130DEFPROCMV(X,Y,Z):MOVEFNX(X,Z),FNY(Y,Z)
1140ENDPROC
1150DEFPROCDW(X,Y,Z):DRAWFNX(X,Z),FNY(Y,Z)
1160ENDPROC
1170DEFPROCTRI(X,Y,Z):PLOT85,FNX(X,Z),FNY(Y,Z)
1180ENDPROC
1190DEFFNX(X,Z)=DISP+VX+D*(X-VX)/(D+Z)
1200DEFFNY(Y,Z)=DISP+VY+D*(Y-VY)/(D+Z)
1210DEFPROCMAN(A,X,Y)
1220ON A+1 GOSUB1240,1270,1300,1330,1360,1390
1230ENDPROC
1240MOVEX,Y+5*32
1250VDU224,10,8,225,8,10,226,8,10,231,232,8,8,10,233
1260RETURN
1270MOVEX+4,Y+5*32
1280VDU9,224,10,8,225,8,10,226,8,8,10,227,228,229,8,8,8,10,230
1290RETURN
1300MOVEX-4*4,Y+5*32
1310VDU234,10,8,8,235,236,237,8,8,8,10,238,239,240,8,8,10,241,8,10,242
1320RETURN
1330MOVEX-7*4,Y+5*32
1340VDU234,10,8,8,235,236,237,8,8,8,10,238,239,240,8,8,10,243,8,10,244
1350RETURN
1360MOVEX,Y+5*32
1370VDU245,10,8,246,10,8,247,10,8,8,253,252,8,10,254
1380RETURN
1390MOVEX-9*4,Y+5*32
1400VDU245,10,8,246,10,8,247,10,8,8,250,249,248,10,8,251
1410RETURN
```

EDIT: inserted the names of the illusions into the quotation, above.