ISSN 0964-5640

FRACTAL REPORT 32

And Innovative Computer Applications

Editorial and Announcements 2

Fractal Meanderings G.T. Swain 2

Compression Ed Hersom 3

Circle Residue Art Dr Mike Ecker 6

Fractals from cyclotonic polynomials Mikel Paternain 7

A Programme For Generating the Menger Sponge Roger Castle-Smith 8

Candy Jean van Mourik 14

Fractal Stars (in good time for) Christmas (1994) Dr Jules Verschueren 15

Strophoid Loops in Space-Time Simulated Roger Bagula 18

and Tachyon Transient Dimensions





Fractal Report is published by Reeves Telecommunications Laboratories,

West Towan House, Porthtowan, Truro, Cornwall TR4 8AX, United Kingdom.

Volume 6 no 32 First published April 1994. ISSN 0964-5640.



Editorial and Announcements

Editorial



We have not yet had any result from the press handouts sent with copies of Fractal Report 31 and the change of content. This is hardly surprising as magazines usually run on a three month cycle just as we do, despite the fact that they appear every month.



Nevertheless, we have a good crop of mainly fractal articles this issue. Hopefully by next issue we will have some new readers with new ideas, and the "innovative computer applications" side will begin to gain momentum, giving us some spectacular results by the autumn (and peak season for this sort of thing.)



Enthusiasm is a strange thing. We still get people buying all the back issues, but many people who started subscribing in the early volumes gave up after a year or two. This time I am making a special offer (see enclosed) for those of you who do not have a complete set. Usually we offer a discount when every volume plus the current issue is bought, which means that you buy now or forever hold your peace. (Or pay over the odds for your complete set.) For a limited period paid up subscribers can make up the set at discounted prices. Use the form printed on the back of your mailing label.



I have bought a second hand A3 photocopier, which will enable the now relatively small circulation to be met at less expense than professional printing. Also it will be easier to continue with the back number services as the odd issue can be reprinted. The "new" machine is considerably better than the last one, as it is about five years old whereas the other (a Sharp SF740) is 15 years old. The Sharp still goes, and I was disappointed to find that the toner is no longer available. I made enquiries so I could sell it.



One photocopy shop told me that they throw away three perfectly good machines each week as toner supplies run out. It strikes me as amazing that it is not possible to modify machines to use current toners - they are all fine black powders that are heat fusible. Any ideas anyone?



Another plea for ideas: some Immortalists have the opinion that there is an "ageing gene" that once found can be switched off and lo! we have immortality. I rather doubt this, because if there was such a gene why don't we have cases where it goes wrong and a few people live for two or three hundred years? Statistically, if accidents were the only cause of death the average age of death would be 600 years. I prefer the conjecture that ageing is a result of the culmination of the side effects of living.



The challenge for readers of Fractal Report is to devise a computer program to illustrate this idea. One possibility would have a large number of variables in closed feedback loops whose aim is to keep a point moving along a line. Each feedback loop would not work on its own, only the sum total keep the point on the straight and narrow. How long does the system run before the point gets off the line? Or maybe you can think of different ideas to illustrate the point, or even have your own point to make about the so called ageing gene.



Another point for thought: A number of firms are offering analogue to digital convertors for sale for about �60. They plug into the serial ports of PCs and can be used as real time oscilloscopes up to 20 kHz or so or sampling oscilloscopes after that. They come with software to enable the ports to be run from BASIC and also ready made programmes for oscilloscopy and frequency analysis.



Any ideas for making pretty patterns to music? I would doubt whether it is very easy to get patterns that have any relation to how the brain perceives the music, but maybe it could be done. For that matter, I would expect it to be quite difficult to simply extract the musical beat unless there is any obvious drum sound one could latch on to in pop music.



It will be a long time before we can get a program that you can play music into and it will print out the score! I hear that programs that read in musical score from a scanner and produce MIDI files are very expensive and virtually useless - like OCR a few years back. But no doubt, like OCR, someone will get it right eventually.



Frac'cetera 2.8 Issued at Last



Serious time problems at HI-LO Enterprises have hit the production schedule of this PC disk based fractals product. It is not quite like a magazine as parts of it are the same each issue, but the data is constantly upgraded. They say that they have lost subscribers because many are still using PCs that cannot support it through lack of disk reading or memory storage capacity. The great advantage of the medium is that one can use the computer to search and find items, and the reference sections are large enough to make this useful.



They also support an ongoing fractal program in QBASIC which can be used to learn more about programming than one can from Fractint. However they do run a Fractint user group, FRUG.



The product contains a number of GIF images that can be viewed directly from the "magazine", which has a Windows type point and shoot front page (although it runs from DOS). Also Fractint can be run directly.



Like Fractal Report, Frac'cetera has about 100 subscribers, some of whom are exchange or on a free list or whatever. Those who pay, pay �12/�13/�15 or $25/�16 (UK/Europe/N. America/ Rest) for four issues, or �5/�5.5/�6 or $10/�6.5 for a single issue. A free four page A5 leaflet is available which details the contents. (Frac'cetera, Le Mont Ardaine, Rue des Ardaines, St Peters, Guernsey GY7 9EU, CI, UK)



IFS Query



Roger Bagula (11759 Waterhall Road Lakeside CA 92040 USA) would like to know how to extract the IFS data from a single bit plane (black & white) image for Barnsley compression.



It seems to me that this could be a worthwhile subject for articles in Fractal Report. The author may well be able to sell or get copying fees for short modules that import images into BASIC programs for such demonstrations.



Unfortunately the image compression market seems to be moving away from fractal compression towards other methods, but whether the move just political or is justified on a scientific basis I do not know.



Fractal Meanderings



by G.T. Swain



After reading in a recent Fractal Report article about constructing true shapes using fractal methodology, I started to wonder if the same principles of construction could be applied elsewhere. I cast around for some parallels and a few stray thoughts occurred which I offer for discussion in the hope other contributors might take up the gauntlet.



Music



I have read in the newsletter and elsewhere of music composition based on the mathematics of chaos. I even purchased a cassette of material thus produced. However without more understanding of either the precise formulae or how it was being employed, and lacking a sufficiently precise musical ear I found it difficult to differentiate between the "Fractal" music and other free forms such as Stockhausen or even some types of modern jazz. I did however enjoy the music, which I suppose counts for something.



Thinking about musical composition, and applying my meagre understanding of Chaos theory I concluded, perhaps incorrectly, the method of composition was perhaps more important than the end product. Taking this tortured thinking one stage further It occurred to me the composer who most typified a fractal approach to music was John Cage.



I can remember some years ago, when his music was enjoying a brief period of popularity, listening to parts of a Radio Three concert in which one of the featured compositions devolved on a complicated musical game. Unfortunately I can not remember the title of the piece, but I can describe its essence. A small group of musicians were given an intricate musical theme with the instructions they were to stay with the theme as long as they chose, but when they made a mistake, or in some way lost the theme or even if they deliberately decided to introduce their own improvisations, they should make no attempt to return to the main theme. In essence they were told if they got lost they were to stay lost.



The resulting accidental composition, taken overall retained many similarities with the originating theme. Similar I suppose to the way that iterations in a Mandelbrot Set at succeeding magnifications retain some similarity with the original plot. Whether or not John Cage was ever aware of Chaos theory, I have no way of knowing. Perhaps I am stretching coincidence too far. Just possibly there are some ideas here worth exploring further.



Nature



Crop marks whether shaped like a natural fractal set or the more traditional circle, seem to be a constant cause of speculation. The shape of the Mandelbrot set however is one which frequently occurs in nature. I can think immediately of various types of cactus, which propagate by producing smaller oval leaves at the outer edges of larger surfaces. There is also a naturally occurring plant(weed!) which frequently invades my garden, to which the colloquial name "Honesty" has been given. The shape of the leaves of this plant are reminiscent of the Mandelbrot's appearance. Perhaps this has escaped the notice of your readers because it is so obvious as to be unworthy of mention, or perhaps I missed the issue in question.



Nevertheless I am willing to bet there are other plants or naturally occurring phenomena which are equally significant.



Journalism



In the same way that iteration is important in the construction of fractal graphics so it can also be a useful tool in conveying information. If I wish to explore an idea one useful technique is to break the subject down into separate components and focus on each of these in turn as a means of helping the reader to understand the whole concept. Since any original subject has to be viewed as an amalgamation of different elements, so each of these have in some way to relate to the whole. In this respect unless there are levels of similarity, such as are to be found in a fractal plot, the exercise of explanation will probably be unsuccessful.



Within the scope of a news letter like Fractal Report there ought to be space for the Theory of Chaos to be discussed or expressed in non mathematical terms. Perhaps this might be contentious, I leave it to the readers to respond.



Editorial Comment



Maybe Fractal Report itself could be considered as a fractal, growing in the substrate of human interest in computers. Each issue could be regarded as an iteration from the previous one.



Music Mandala

I've just burned off a couple of hours playing with this program from Newtronic, 62b Manor Avenue, London SE4 1TE. Excellent random composition program for non musicians.(�31 req Windows. Atari ST version also available -BUY IT!) More next time.

Compression

by Ed Hersom

Much is heard these days of the ability to compress screen data, files and other digital signals into much shorter formats, but I have seen little on how this is achieved. From what is in the magazines, I have obtained the impression the journalists do not really understand it themselves! I am not in the business myself but opening up the subject might produce some further information from others.



There are obviously many ways to compress strings of bits depending on the redundancy they contain. For example, in my pocket Agenda (from MicroWriter Systems that was!) it stores characters as 8-bit bytes as usual, but the codes 128 - 255 are not used for foreign characters or other funny symbols. Instead if the most significant bit is 1 it indicates that a space follows the character represented by the other 7 bits. By not having to store the space as a separate byte saves, in English text, about 16% on storage space.



Another is the Graphical Interchange Format (GIF) put into the public domain by CompuServe Inc. Full details are obtainable from Dr. Larry Cobb but I give the "hard core" here. It is an algorithm based on the Lempel-Ziv Welch algorithm and is obviously intended for compressing screen data, but I have used it more generally. We start with a string of "characters", for example a string of bytes each representing a pixel of 256 colours and the encoder translates these into code symbols, each symbol representing a string of the original characters. The receiver or decoder converts these code symbols back into the original characters without initially knowing much about the code table used by the coder. The only disadvantage is the receiver is a step behind the sender. Both start with a table of all codes which represent pixels, plus 2 other special codes. If the pixels are represented by n bits, then the positions 0 to 2^n - 1 of the table contain these codes and the special codes, <CC> and <EOI> occupy positions 2^n and 2^n + 1 in this table. <CC> just means "Clear", i.e. set the table as described, and <EOI> means end of transmission or of the file or whatever. The receiver knows n, i.e. he knows the initial codes will be of length n+1 bits - the code size. We shall call the input to the coder the "charstream" and its output of codes the "codestream". The individual codes in this stream are just the binary numbers representing the addresses of the code table. The coder's algorithm is:

(1) Initialize his code table and send the code for <CC>.

(2) Set a location which holds a code, C, empty.

(3) Get next character in the charstream, store it in K.

(4) Is the string of characters represented by C + K in the table?

If yes, put code for this string into C and go to (3)

If no, send the code in C to the codestream, add the string for C + K to the next available space in the code table, put the code for K into C then go to (3).



If the code table is "full", i.e the latest address was all 1's, then the code size must be increased by 1 so that all subsequent codes are 1 bit longer (whether they need it or not). If the code size reaches 12 bits, the coder either sticks with this table or sends the code in C and goes to (1) and the code size reverts to the original length. If there are no more characters in the charstream, he just sends the code in C followed by <EOI>. Since each code in the table (apart from one of the initial set) represents a string which iself is represented by an earlier entry in the table plus another character, the new entry need be only of this character plus the address of the earlier entry. The only time-consuming operation is the searching of the code table for the previously stored code. Hashing of the table is recommended, but in the BASIC program given below a simpler scheme is adopted which is good enough for demonstration purposes. It makes use of the fact that we are looking for strings of the form C + K, where C is a known code (one of the addresses of the code table) and K is a character. We have therefore only to search from the address C to the end of the table.



The algorithm for the receiver (decoder or decompressor) is simpler to implement, if more difficult to understand. It is:



(1) On receipt of <CC>, initialise code table, in particular set the code size to n + 1.

(2) Get first code, <code>, from the codestream. (Always of a single character.)

(3) Output this character to the charstream.

(4) Put C = <code>. C is now <old code>

(5) Get next code, <code>.

If this is <CC>, go to (1).

If it is <EOI>, finish.

(6) Is <code> in the code table? (This is easy. Is <code> less than address of the next vacant slot?)

If so, send the string represented by <code> to the charstream and put K = first character of this string

If not, put K = 1st character of the string represented by the old code, C, and output the string C + K.

(7) Add C + K to the table and put C = <code>.

If the entry to the code table is the maximum, i.e. 2^(code size) - 1, immediately increase code size by 1 (or else a bit of the next code will be lost!), then go to (5).



This is surprisingly simple and it does work! There is also more to GIF, for example, there is a protocol for sending a header before the code, which includes details of the initial code table when that is necessary. Again, no details are given since they are irrevelent here.



To test the algorithm I needed a way of producing a stream of "characters". I rejected finding a standard "screen" or even a standard text in ASCII. A random set of bits would not do since compression would be minimal. Finally I chose an unpredictable but near random set formed by the sieve of Eratosthenes. This is the string of bits representing all the odd numbers 3,5,7,9,11, ... Initially all bits are 1's, but by converting every 3rd, 5th, 7th, 11th, ... bit to 0, the 1's remaining represent all the prime numbers (or as many as there is room for!). The code for this is given so that others may experiment. This sequence is not truly random since the ratio of 1's to 0's steadily decreases. The bits are of course normally packaged in a string of bytes, but my BASIC does not support working in bytes, even 15 & 16 bits are not easily manipulated, so I have chosen to use 12 bits of my 16 bit words. The program will run with 2, or 3 bits to a character and if printing is not required (see below) with 4 or 6. Just 1 causes minor complications, so that is not an option. The experiment was to compare the number of bits in this string with that in the code stream. (In practice this stream should also be sent in packed bytes, but that is not necessary here as long as the bits, not words, are counted in the output.)



The program is in three sections:



(1) ERATOSTHENES (the % sign appearing everywhere in the code only indicates I am working in 16 bit integers, not floating point.) The length of the string is set at line 9. With N = 100, we will get all primes less than about 2500. Printing at line 155 is solely for monitoring progress. The program can be made "stand alone" simply by putting STOP at line 200, otherwise it just runs into the GIF routine which reads Eratos as the char_stream. From 3000 onwards is a piece of coding for testing for primes. If n is the odd number you wish to test, just key in P% = n : GOTO 3000.



(2) Encode section. The no. of bits to represent a character is set in line 5020, and the no. of words read from ERATOS (5 in my listing), is set at 5100.

(3) This is the Decode section. It is written as a subroutine of the coding section, but the only information it takes is CODE, as if it has been "sent" this over a transmission channel. It "knows" of course all about char_size, the initial code table and so on, but it definitely does not know how this table is being built up during the transmission. It has to build up its own, identical,table from the code received. Program code is included, at line 10700, to print out the deduced code table. The combined output from these routines shows the characters from ERATOS, the code that is "sent" and the no. of bits of these characters and the no. of bits used in the code. There is then the output from the decoder showing that the intepretation of the code is correct. In this demonstration there is no packing and unpacking of the code stream (according to the current value of the code size) but the output of the decoder shows an "*" when it would have increased its code size to grab the necessary no. of bits, and it is seen from the output that it does this in sufficient time so as not to miss a bit. The other output shows the code table (as produced by the encoder; the decoder's is the same). Note that:

(1) It is up to the encoder to decide when to re-initialise the table. In my case I do not go beyond 2048 entries since I haven't any room for more! He may stick with a full table, and as long as he does not attempt to send a code longer than 12 bits, he is within his rights.

(2) In line 5260 the encoder does not increase the code size until there is a real possibility that an extra bit will be necessary, but then he has to, even though it is not immediately necessary.



On this short demonstration run there is no compression, just the reverse! However, by printing out only the no. of bits used, and then only at infrequent intervals, we can see compression occuring. With 2 bits/character (not a critical factor) and taking the sub-totals when the encoder has to add another bit to the code_size, I obtained the following table:



Char_bits Code_bits Compression(%)

30 44 -47 i.e. an expansion

90 124 -38

258 316 -22

680 764 -12

1732 1788 - 3

4276 4092 4 we have compression!

10380 9212 11



If you cut out all printing as such and just plot char_bits against code_bits, you get a line which has a very slight curve. It is not a great compression ratio but it is continually increasing. Far from being a criticism of GIF, this indicates that with the many thousands of bits in the input stream it is likely to attain a good compression ratio even with the "Sieve" which has so little pattern.



Char_bits Code_bits Compression(%)

30 44 -47 i.e. an expansion

90 124 -38

258 316 -22

680 764 -12

1732 1788 - 3

4276 4092 4 we have compression!

10380 9212 11



If you cut out all printing as such and just plot char_bits against code_bits, you get a line which has a very slight curve. It is not a great compression ratio but it is continually increasing. Far from being a criticism of GIF, this indicates that with the many thousands of bits in the input stream it is likely to attain a good compression ratio even with the "Sieve" which has so little pattern.



Input   Code   Char bits  Code bits   Output

           4         0         3        
d         
b          3         4         6        d
d          1         6         9        b
c          3         8         12       d *
b          2         10        16       c
b          1         12        20       b
c          1         14        24       b
b         
c          9         18        28       cb
c          2         20        32       c
b         
b          9         24        36       cb
c         
a          11        28        40       bc
d          0         30        44       a *
a          3         32        49       d
b          0         34        54       a
d         
a          7         38        59       bd
b         
b          18        42        64       ab
c         
a         
c          15        48        69       bca
c         
b          13        52        74       cc
d         
c          7         56        79       bd
a          2         58        84       c
a          0         60        89       a
a         
b          25        64        94       aa
b         
c          10        68        99       bb
b         
a          9         72        104      cb
           0         72        109      a
           5         72        114      

Encoder's table (char_bits = 2):

Address  Link   Char
         Addr

 0       -1       a          )
 1       -1       b          )
 2       -1       c          )   Root table
 3       -1       d          )
 4       -1       e  = <CC>  )
 5       -1       f  = <EOI> )
 6        3       b
 7        1       d
 8        3       c
 9        2       b
 10       1       b
 11       1       c
 12       9       c
 13       2       c
 14       9       b
 15       11      a
 16       0       d
 17       3       a
 18       0       b
 19       7       a
 20       18      b
 21       15      c
 22       13      b
 23       7       c
 24       2       a
 25       0       a
 26       25      b
 27       10      c
 28       9       a

1 REM ERATOSthenes is the array of 12 bit words to be sieved, dimension N.

2 REM A dimension of N gives 12(N+1) bits, (array goes from 0 to N),

3 REM Since nth bit represents the no. 2*n+3, max no. = 24N+27

4 REM MASKs are used for extracting bits from words.

5 REM W0,W1 are 1st 2 words of ERATOS when sieved by 3

6 REM W1 repeats to the end. 13th to 16th bit always = 0, i.e. not used

7 REM W1 = 0000 1101 1011 0110 ; W0 = 0000 1101 1011 0111



9 N% := 100 : REM Set N as required.

10 DIM Eratos%(N%), Mask%(11) : Mask%(0) := 1

20 FOR I% := 1 TO 11

21 Mask%(I%) := 2 * Mask%(I% - 1)

22 NEXT I%

25 W0% := &DB7 : W1% := &DB6 : REM W0, W1 in HEX

30 Eratos%(0) := W0% : REM Initialise string

31 FOR I% := 1 TO N%

32 Eratos%(I%) := W1%

33 NEXT I%

40 Maxp% := INT(SQRT(24 * N% + 27)) : REM No need to go further

50 P% := 5 : REM First prime for sieving



99 REM ************* Main program ******************

100 REPEAT : REM i.e. repeat for all primes up to Maxp

110 FOR M% := P% * P% TO 24 * N% + 27 STEP 2 * P% : REM For each odd product of P

130 GOSUB Zero_Bit

140 NEXT M%

150 GOSUB Next_Prime

155 PRINT P%,

160 UNTIL P% > Maxp%

200 GOTO 5000 : REM ******** End of prime program, go to GIF **************



1000 SUBROUTINE Next_Prime

1010 REPEAT

1020 P% := P% + 2 : D% := (P% - 3) \ 2

1030 Word% := Eratos%(D% \ 12) : Bit_Pos% := D% MOD (12)

1040 Bit% := Word% AND Mask%(Bit_Pos%)

1050 UNTIL Bit% <> 0

1060 RETURN



2000 SUBROUTINE Zero_Bit

2010 D% := (M% - 3) \ 2 : Addr% := D% \ 12

2020 Word% := Eratos%(Addr%) : Bit_Pos% := D% MOD (12)

2030 Bit% := Mask%(Bit_Pos%)

2040 Eratos%(Addr%) := Word% AND (&FFF - Bit%)

2050 RETURN



3000 REM Program for testing an odd no., in P, for primarity

3010 D% := (P% - 3) \ 2 : Addr% := D% \ 12

3020 Word% := Eratos%(Addr%) : Bit_Pos% := D% MOD (12)

3030 Bit% := Word% AND Mask%(Bit_Pos%)

3040 PRINT P%; : IF Bit% <> 0 THEN PRINT "is prime" ELSE PRINT "is composite"

3050 STOP

4000 REM Program for printing code table

4010 PRINT #2 : PRINT #2 "Address", "Link addr", "Char" : PRINT #2

4020 FOR I := 0 TO Pointer% - 1 : REM Print table with a,b,c . . . instead of 1,2,3 . . .

4030 PRINT #2 I, Table%(1, I), CHR$(Table%(2, I) + 97)

4040 NEXT I

4100 STOP



5000 REM GIF testing with Eratosthenes. Charstream is in ERATOS

5001 REM Codestream is output as 12 bits of 16-bit words, even with short code

5002 REM A code of a string is in TABLE(.,code), where TABLE(1,code) holds

5003 REM the address (code) of the string without the last char and

5004 REM TABLE(2,code.) is this last char.

5005 REM The code at the "root" of the table is -1 and the char is the 1st

5006 REM (or only) char of the string.



5010 DIM Table%(2, 2048), D_Table%(2, 2048), Reverse%(100)

5020 Char_Size% := 2 : REM or 3, 4 or 6, i.e any submultiple of 12, but not 1.

5030 Cc% := 2 ^ Char_Size% : Eoi% := Cc% + 1

5035 Char_Bits% := 0 : Code_Bits% := 0 : REM Zero bit counts

5040 FOR I% := 0 TO Eoi% : REM Form initial table

5050 Table%(1, I%) := - 1 : Table%(2, I%) := I%

5060 NEXT I%

5070 Mask%(0) := Cc% - 1 : REM Redefine masks.

5072 FOR I% := 1 TO (12 \ Char_Size%) - 1

5073 Mask%(I%) := Cc% * Mask%(I% - 1)

5074 NEXT I%

5080 PRINT #2 : PRINT #2 " Input", " Code", "Char bits", "Code bits", "Output" : PRINT #2

5090 GOSUB Initialise : REM Initialise the rest

5100 FOR I% := 0 TO 5 : REM Read the input

5110 Word% := Eratos%(I%)

5120 FOR J% := 0 TO (12 \ Char_Size%) - 1 : REM i.e for each "character"

5130 K% := Word% AND Mask%(J%) : Char_Bits% := Char_Bits% + Char_Size%

5140 IF J% = 0 GOTO 5180 : REM No need to shift 1st char

5150 FOR Jj% := 1 TO J% : REM Shift char down to l.s. position

5160 K% := K% \ Cc%

5170 NEXT Jj%

5180 PRINT #2 CHR$(K% + 97),

5190 IF Code% = - 1 THEN : PRINT #2 : GOTO 5250

5200 GOSUB In_Table?

5210 IF Found% = TRUE THEN Code% := Addr% : PRINT #2 : GOTO 5300

5230 Table%(1, Pointer%) := Code% : Table%(2, Pointer%) := K%

5240 Pointer% := Pointer% + 1 : GOSUB Send

5250 Code% := K% : REM Having "sent" old code, start a new string.

5260 IF Pointer% = Limit% + 1 THEN Limit% := 2 * Limit% : Code_Size% := Code_Size% + 1

5270 IF Limit% < 2048 THEN GOTO 5300 ELSE GOSUB Send : REM Send remaining code

5290 GOSUB Initialise : REM and restart

5300 NEXT J% : REM next char

5310 NEXT I% : REM Next word from ERATOS.

5320 PRINT #2 " ", : GOSUB Send : REM Send remaining code

5330 PRINT #2 " ", : Code% := Eoi% : GOSUB Send

5350 STOP



5400 SUBROUTINE Send

5410 Code_Bits% := Code_Bits% + Code_Size%

5420 PRINT #2 Code%, Char_Bits%, Code_Bits%, : GOSUB Decode

5430 RETURN



6000 SUBROUTINE Initialise

6010 Limit% := 2 * Cc% : Code_Size% := Char_Size% + 1

6020 Pointer% := Eoi% + 1 : Code% := Cc%

6030 PRINT #2 " ", : GOSUB Send : REM No input, just send "start"

6040 Code% := - 1 : REM Set Code "empty"

6050 RETURN



7000 SUBROUTINE In_Table?

7010 Found% := FALSE : Addr% := Code%

7020 REPEAT

7030 IF Table%(1, Addr%) <> Code% THEN Addr% := Addr% + 1 : GOTO 7060

7040 IF Table%(2, Addr%) <> K% THEN Addr% := Addr% + 1 : GOTO 7060

7050 Found% := TRUE : REM Got it!

7060 UNTIL Found% = TRUE OR Addr% = Pointer% : REM i.e found or end of table.

7070 RETURN



10000 REM The decoder builds own decode table, D_table, and prints out the code

10001 REM received as a, b, c . . .



10020 SUBROUTINE Decode

10030 IF Code% = Cc% THEN GOTO 10410 : REM Just initialise and return

10031 IF Code% = Eoi% THEN PRINT #20 : RETURN : REM Finished

10035 IF First% = TRUE THEN GOTO 10500 : REM First Code is always of 1 character

10040 IF Code% < D_Pointer% GOSUB Old_Code ELSE GOSUB New_Code

10050 IF D_Pointer% = D_Limit% THEN D_Limit% := 2 * D_Limit% : PRINT #2 " *" ELSE PRINT #2

10070 RETURN



10095 REM Code already exists in table

10100 SUBROUTINE Old_Code

10110 GOSUB String : REM Convert Code to a string (in reverse order)

10120 GOSUB Output

10130 Kk% := Reverse%(Rev_Pointer% - 1) : REM Kk is first char of the string

10140 GOTO 10600 : REM Insert Old/K in table & save code as old.



10149 REM Reverse still has string for old

10150 SUBROUTINE New_Code

10160 Kk% := Reverse%(Rev_Pointer% - 1)

10170 Reverse%(Rev_Pointer%) := Kk% : Rev_Pointer% := Rev_Pointer% + 1

10180 GOSUB Output : REM As before, but first char is added as last

10190 GOTO 10600 : REM Insert next entry



10200 SUBROUTINE String

10210 Rev_Pointer% := 0 : Addr% := Code%

10220 REPEAT

10230 Reverse%(Rev_Pointer%) := D_Table%(2, Addr%) : Addr% := D_Table%(1, Addr%)

10240 Rev_Pointer% := Rev_Pointer% + 1

10250 UNTIL Addr% = - 1 : REM i.e. until root table is reached

10260 RETURN



10300 SUBROUTINE Output

10305 FOR M% := Rev_Pointer% - 1 TO 0 STEP - 1 : REM Print in correct order

10310 PRINT #2 CHR$(Reverse%(M%)); : REM on one line

10320 NEXT M%

10340 RETURN



10400 REM Initialisation routine

10410 FOR Ir% := 0 TO Eoi%

10420 D_Table%(1, Ir%) := - 1 : D_Table%(2, Ir%) := Ir% + 97

10430 NEXT Ir%

10440 First% := TRUE : D_Pointer% := Eoi% + 1

10450 D_Limit% := 2 * Cc% : Old% := Code%

10455 PRINT #2

10460 RETURN



10500 REM First code (in the root-table) has been received

10505 Kk% := D_Table%(2, Code%) : Old% := Code%

10510 PRINT #2 CHR$(Kk%) : Rev_Pointer% := 1 : Reverse%(0) := Kk%

10520 First% := FALSE : RETURN : REM That's all!



10600 REM Insert CODE/K into decode table

10605 IF D_Pointer% = 2048 THEN RETURN : REM Table full. Only occurs when encoder keeps full table

10610 D_Table%(1, D_Pointer%) := Old% : D_Table%(2, D_Pointer%) := Kk%

10620 D_Pointer% := D_Pointer% + 1 : Old% := Code% : RETURN



10700 REM For printing decode table

10705 PRINT #2

10710 FOR Ip% = 0 TO D_Pointer% - 1

10720 PRINT #2 Ip%, D_Table%(1, Ip%), CHR$(D_Table%(2, Ip%))

10730 NEXT Ip%

11000 END



Mikel Paternain



Fractals from clyclotonic ploynomials

(rem the text of this articles is only in the printed issue)



c1 = {z=c=pixel :z=(-1+z)+c, z<=4}

c2 = {z=c=pixel :z=(1+z)+c, z<=4}

c3 = {z=c=pixel :z=(1+z+z^2)+c, z<=4}

c4 = {z=c=pixel :z=(1+z^2)+c, z<=4}

c5 = {z=c=pixel :z=(1+z+z^2+z^3+z^4)+c, z<=4}

c6 = {z=c=pixel :z=(1-z+z^2)+c, z<=4}

c7 = {z=c=pixel :z=(1+z+z^2+z^3 +z^4+z^5 +z^6)+c, z<=4}

c8 = {z=c=pixe1 :z=(1+z^4)+c, z<=4}

c9 = {z=c=pixel :z=(1+z^3 +z^6)+c, z<=4}

c10 = {z=c=pixel :z=(1-z+z^2-z^3 +z^4)+c, z<=4}

c11 = {z=p1, c=pixel: z=(1-z+z^2)+c, z<=4}

c12 = {z=pixel, c=p1: z=(1-z+z^2)+c, z<=4}

c21 = {z=p1, c=pixel: z=(1+z)+c, z<=4}



c22 = {z=pixel, c=p1: z=(1+z)+c, z<=4}

c31 = {z=p1, c=pixel: z=(1+z+z^2)+c, z<=4}

c32 = {z=pixel, c=p1: z=(1+z+z^2)+c, z<=4}

c41 = {z=p1, c=pixel: z=(1+z^2)+c, z<=4}

c42 = {z=pixel, c=p1: z=(1+z^2)+c, z<=4}

c51 = {z=p1, c=pixel: z=(1+z+z^2+z^3 +z^4)+c, z<=4}

c52 = {z=pixel, c=p1: z=(1+z+z^2+z^3 +z^4)+c, z<=4}

c61 = {z=p1, c=pixel: z=(1-z+z^2)+c, z<=4}

c62 = {z=pixel, c=p1: z=(1-z+z^2)+c, z<=4}

c71 = {z=p1, c=pixel: z=(1+z+z^2+z^3+z^4+z^5 +z^6)+c, z<=4}

c72 = {z=pixel, c=p1: z=(1+z+z^2+z^3+z^4+z^5 +z^6)+c, z<=4}

c81 = {z=pl, c=pixel: z=(1+z^4)+c, z<=4}

c82 = {z=pixel, c=pl: z=(1+z^4)+c, z<=4}

c91 = {z=p1, c=pixel: z=(1+z^3+z^6)+c, z<=4}

c92 = {z=pixel, c=p1: z=(1+z^3+z^6)+c, z<=4}

c101 = {z=p1,c=pixe1: z=(1-z+z^2-z^3 +z^4)+c, z<=4}

c102 = {z=pixel,c=p1: z=(1-z+z^2-z^3+z^4)+c, z<=4}

Candy



by Jean van Mourik (4, Pantllyn Llandybie Ammanford Dyfed SA18 3JT UK)



Candy is a cellular automaton, devised on an Archimedes computer. The generated image suggests piles of coloured candy, according to the palette as defined in line 40. Both arrays, A%() and B%() maintain a constantly updated record of all pixel coordinates at the edges of the growing pattern. The screen size on an Archimedes is 1280 by 1024, and pixel size varies according to the diferent screen resolution modes. The mode in which this program works has a pixel size of 4 by 4 screen units. It should not be too difficult to adapt the code to your machine. Line 60 contains a loop which is exited by a mouse click. It also contains the RND command, which prevents the same image being generated each time. The use of MOD causes the pattern to be wrapped. Top/bottom and left/right are connected.



H% = Horizontal screen size

V% = Vertical screen size

F% = Pixel size

N% = No of edge pixels, starting with 12 at line 80

GCOLC defines the colour to be used

MOD is modulus

POINT(X,Y) reads a pixel's colour

POINT X,Y (ie without the brackets) plots a pixel

COLOUR 0 background colour


This page hosted by Get your own Free Home Page
Hosted by www.Geocities.ws

1