CPCWiki forum

General Category => Programming => Topic started by: Bytebreaker on 00:28, 13 June 16

Title: Fractal Coding - Koch Curve
Post by: Bytebreaker on 00:28, 13 June 16
Hello,


when I released my little triangles basic demo lately I announced that drawing a Koch snowflake would be my next project and I encouraged everyone to sit and find a proper Amstrad BASIC algorithm to draw it.


I finally managed but I am not satisfied. The results look ok but the code behind the lines is crap. Has anyone experience with line-based fractal code in Basic (i.e. Sirpinski Triangles, Koch Curves) and has anyone of you an idea how to implement a properly nested "for next" loop to achieve the same result with less code?


I attached a very nice Java applet code besides my own snowflake code as readable text files. My snowflake code is easy to read but it's very repetitive. I want it to be as short as the java version, knowing that you cannot adapt object oriented code 1:to procedural code.


On the dsk file, you find with koch1.bas and koch2.bas my failed attempts to use subroutines and loops to shorten the code. I didn't include text files in the archive of these two because the code is inefficient and awful to read anyway. koch3.bas is the snowflake code from which I included a txt copy for text editors and because it's easy to understand.


Due to code inefficiency I could not add many iterations. I had to stop at iteration 3. The ideal thing would be a text input letting you specify the number of iterations and the program does the rest.


So please take this and play/watch, maybe some CPC math junkies see a challenge here and make this better.


Regards,


Bytebreaker
Title: Re: Fractal Coding - Koch Curve
Post by: Bytebreaker on 12:46, 13 June 16
A colleague of mine at work told me today that there's a difference between iteration and recursion.
I believe the Java source file I posted works recursively (I can only suppose so since I cannot code Java, I am learning it at the moment and just started with "Hello World").


Amstrad Basic cannot cope with recursion, only with iteration. And maybe that's why I can't compress the code better than I did in koch1.bas and koch2.bas.
Still, I look forward to improvements, variations or different expamples how to visualize infinite data relations.
Title: Re: Fractal Coding - Koch Curve
Post by: mr_lou on 13:28, 13 June 16
Quote from: Bytebreaker on 12:46, 13 June 16
Amstrad Basic cannot cope with recursion, only with iteration.

Not true.

A GOSUB can go to itself - just not as many times as a Java app can.


10 a = 10
20 GOSUB 100
30 END

100 ' A recursive sub-routine
110 a = a - 1
120 IF a>0 GOSUB 100
130 RETURN

Title: Re: Fractal Coding - Koch Curve
Post by: andycadley on 13:35, 13 June 16
True, but recursive code often relies on local variables having appropriate scope, which Locomotive BASIC lacks. It can be faked with Arrays, if required, though rewriting it iteratively is usually better (a recursive algorithm can always be rewritten to work iteratively)
Title: Re: Fractal Coding - Koch Curve
Post by: Devilmarkus on 13:37, 13 June 16
You can also do like this:


10 a = 10
20 GOSUB 100
30 END

100 ' A recursive sub-routine
110 a = a - 1
120 IF a>0 THEN GOTO 100
130 RETURN


You then will not run into an overflow here.
Title: Re: Fractal Coding - Koch Curve
Post by: AMSDOS on 10:26, 15 June 16
Quote from: Devilmarkus on 13:37, 13 June 16
You can also do like this:


10 a = 10
20 GOSUB 100
30 END

100 ' A recursive sub-routine
110 a = a - 1
120 IF a>0 THEN GOTO 100
130 RETURN


You then will not run into an overflow here.


Or it could be done like this if you don't like GOTO  :laugh:




10 a = 10
20 GOSUB 100
30 END


100 ' A recursive sub-routine
105 WHILE a>0
110    a = a - 1
120 WEND
130 RETURN
Title: Re: Fractal Coding - Koch Curve
Post by: andycadley on 13:41, 15 June 16
Quote from: Devilmarkus on 13:37, 13 June 16
You can also do like this:


10 a = 10
20 GOSUB 100
30 END

100 ' A recursive sub-routine
110 a = a - 1
120 IF a>0 THEN GOTO 100
130 RETURN


You then will not run into an overflow here.

That only works for tail recursion, a special case, it's not a technique you can apply to generic recursive algorithms.
Title: Re: Fractal Coding - Koch Curve
Post by: Bytebreaker on 15:10, 15 June 16
Quote
though rewriting it iteratively is usually better


If I knew how in this case I would have done it.



I believe this (https://www.youtube.com/watch?v=hHF-bvBmjA0) is another recursive way to draw the curve.
Here (https://en.wikipedia.org/wiki/Koch_snowflake) some general infos about the simple math behind it.


The only piece of code that can be repeated endlessly without manual adaption is my koch1.bas.
The subroutines 4000 and 5000 are part of the same for next loop, whereas routine 4000 saves the start coordinates of all 4 lines of the last iteration and routine 5000 uses these "to go deeper".


The result can be seen as a fractal drawn to a certain depth, but it's not the original curve as in koch2.bas, which is manually put together to make it look like iteration 3.


My problem is that due to lack of recursive function call I don't know how to calculate sidelengths and coordinates properly from the start. If you look at the java applet in my archive (call it with commandline prompt "appletviewer koch_kurve.html) and press the left mouse button often, you will see at a certain point that the curve is being written each time from the very start and the program already knows what to draw where. I don't do that. I try to append instead of rewrite, which is obviously the wrong approach.
Title: Re: Fractal Coding - Koch Curve
Post by: Overflow on 14:54, 16 June 16
Hi guys!
RUN"KOCH0 from attached dsk.
I did not look at your own code, I just tried by myself to get the result as expected.
A few tips:That's all, tell me what you think about it.
PS: I had a lot of fun today coding it this afternoon! very first lines on CPC since many months. Thanks for motivating me with this.
  10 pmax=3
20 DIM c(5),s(5),a(pmax)
30 w=100/(3^(pmax-1))
40 DEG:FOR i=0 TO 5:c(i)=w*COS(60*i):s(i)=w*SIN(60*i):NEXT
50 MODE 2:MOVE 0,300:p=0
110 a(p)=0:GOSUB 1000
120 a(p)=4:GOSUB 1000
130 a(p)=2:GOSUB 1000
140 END
1000 IF p=pmax THEN DRAWR c(a(p)),s(a(p)):RETURN
1010 p=p+1
1020 a(p)=a(p-1):GOSUB 1000
1030 a(p)=(a(p-1)+1)MOD 6:GOSUB 1000
1040 a(p)=(a(p-1)+5)MOD 6:GOSUB 1000
1050 a(p)=a(p-1):GOSUB 1000
1060 p=p-1:RETURN

EDIT: optimized a bit more...
Title: Re: Fractal Coding - Koch Curve
Post by: SRS on 20:14, 16 June 16
If it is JAVA - try JAVAGRINDER to bring it to CPC :D

Title: Re: Fractal Coding - Koch Curve
Post by: SRS on 20:22, 16 June 16
@Overflow (http://www.cpcwiki.eu/forum/index.php?action=profile;u=695):

If you add

5 defint a,p,c,s,i

you get it to run about 20% faster :D
Title: Re: Fractal Coding - Koch Curve
Post by: Bytebreaker on 21:07, 16 June 16
Congrats!


This was damn excellent!
It is very motivating to see what good coders can do with 30+ years old Basic (ok, the best Home Computer Basic ever, though).
Title: Re: Fractal Coding - Koch Curve
Post by: Overflow on 10:55, 17 June 16
Quote from: SRS on 20:22, 16 June 165 defint a,p,c,s,i
Good catch!
Talking about integers: this is why it did not run well with pmax=4 i.e. higher details.
Attachment updated, RUN"KOCH0-4
DRAWR with integers value has been replaced by DRAW x,y with x,y as real.
Now it looks better if pmax=4.

Powered by SMFPacks Menu Editor Mod