The Lorenz Attractor in RISC OS on the Raspberry Pi

By Mike Cook, Jonathan Evans, Brock Craft

Interested in a new Raspberry Pi project? The Lorenz attractor almost singlehandedly originated a whole branch of science chaos theory. It seems fitting that a man who worked for so much of his life in Cambridge, Massachusetts, be remembered for a program that runs on an operating system designed in Cambridge, England.

Edward Norton Lorenz was working on systems to predict the weather. He had constructed a simple mathematical model of how the atmosphere convection should behave. It boiled down to a system of three ordinary differential equations. He was using one of the earliest computers in the 1950s to solve these equations by numerical methods because there is no analytical way to solve them. This involved repeated calculations or iterations of values in order to home in on the result. The output of one set of calculations was fed into the input of another. This is a well-known technique first invented by Isaac Newton; the results either home in on the correct answer, getting smaller and smaller, or shoot off into infinity.

What Lorenz found was a class of equations that neither homed in on one result nor shot off to infinity but did something in between. It produced what appeared to be a cycling result with the same values repeating in a pattern. However, closer inspection revealed that although the results did cycle, they never repeated — in other words, they cycled without end but stayed within certain bounds. A sort of never-ending, never-repeating finite set of numbers.

This pattern of numbers consisted of three values that would change with respect to each other. If you were to use these numbers to plot a position in three-dimensional space, they would describe a line or orbit that never repeated but went on forever. This shape was later christened a fractal, and this class of fractals is known as a strange attractor. No matter what the initial starting conditions were, the equations always ended up on this curve (hence, the name attractor, and because it’s an odd thing to happen, the word strange).

The shape of this curve is a twisted figure-eight loop known as a butterfly curve or the Lorenz attractor. In 1969, Lorenz described the butterfly effect, which states that an almost insignificant change in initial conditions (like the beating of a butterfly’s wings) could cause a large change in the outcome of an iterated system.

All that Lorenz had to visualize his numbers with was a crude teleprinter, but these days we have high-speed computers with graphic displays Lorenz never dreamed of. It’s comparatively easy to see his curve in more detail than Lorenz ever could.


The implementation of the BASIC language in RISC OS makes it easy to write a program to display the Lorenz attractor very quickly and in great detail. This is shown in the following code.

   10 : REM The Lorenz Attractor - by Mike Cook
   20 : MODE 28
   30 : CLS:CLG
   40 : PROC_Size
   50 : S=Ymax%/80:SX=Xmax%/70:SZ=2
   60 : N%=70:F%=0:INC=4E-3
   70 : SX%=Xmax%/2:SY%=Ymax%/2:SZ%=0
   80 : X=-6.5:Y=-8.8:Z=20
   90 : P1=10:P2=28:P3=2.66666
   100 :
   110 : REPEAT
   120 : N%=N%+1
   130 : IF N%>200 THEN N%=0:GCOL 0,RND(63) TINT 255
   140 : D1=P1*(Y-X)
   150 : D2=P2*X-Y-X*Z
   160 : D3=X*Y-P3*Z
   170 : X=X+D1*INC
   180 : Y=Y+D2*INC
   190 : Z=Z+D3*INC
   200 : PROC_PLOT(X,Y)
   210 : TIME=0
   220 : REPEAT
   230 : UNTIL TIME>0
   240 : B%=ADVAL(-1)
   250 : UNTIL B%<>0
   260 : A$=GET$
   270 : IF A$ ="s" THEN *ScreenSave Attract
   280 : END
   290 :
   300 : DEF PROC_PLOT(X,Y)
   310 : X%=X*SX:Y%=Y*S
   320 : X%=X%+SX%:Y%=Y%+SY%
   330 : IF F% = 0 THEN MOVE X%,Y% ELSE DRAW X%,Y%
   340 : F%=1 : REM move only the first time
   350 : ENDPROC
   360 :
   370 : DEF PROC_Size
   380 : SYS"OS_ReadModeVariable",-1,3 TO ,,Ncolours%
   390 : SYS"OS_ReadModeVariable",-1,4 TO ,,Xfact%
   400 : SYS"OS_ReadModeVariable",-1,5 TO ,,Yfact%
   410 : SYS"OS_ReadModeVariable",-1,11 TO ,,XLim%
   420 : SYS"OS_ReadModeVariable",-1,12 TO ,,YLim%
   430 : Xmax%=XLim%<<Xfact%
   440 : Ymax%=YLim%<<Yfact%
   450 : VDU 5
   460 : ENDPROC

The initial starting positions are given in line 80, and the parameters of the equation are given in line 90. The main loop in the program goes from line 110 to line 280. This simply repeats until you press any keyboard key. If the key you press is an S, then a screen dump is done to save a picture of the screen in sprite format. The loop works by lines 140 to 160 finding the difference in values from the last to the present iteration. The iteration calculation is then scaled with the variable INC, which is set to be 0.004 in lines 170 to 190, and the resultant number is plotted on the screen. Notice how only the x and y values are plotted, giving a view looking into the z-axis. You can change the two variables passed in the PROC PLOT call to be any two values to get a different view on the curve. You can combine the x, y, and z values in this call to give any angle of orthographic projection if you like. For example, making the following changes to the code will give an isometric view of the curve:

   42  : C1= 0.707107 : C2 = 0.408241
   43  : C3 = 0.816597 : C4 = -C2
   200 : PROC_PLOT(C1*X + C1*Z, C2*X + C3*Y + C4*Z)

Lines 210 to 230 simply make a time delay, making it longer by increasing the number at the end of line 230 or eliminating it altogether by skipping these three lines.

The PLOT procedure itself simply scales the two points and then shifts them to the middle of the screen. Finally, if it’s the first time plotting, it gives a move command; otherwise, it gives a draw from the last point graphics command.

The Size procedure gets the size of the screen in pixels so the graph fills the screen, and lines 120 and 130 add a bit of variety by changing the line’s color every 200 points.