News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Fractal Coding - Koch Curve

Started by Bytebreaker, 00:28, 13 June 16

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bytebreaker

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

Bytebreaker

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.

mr_lou

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


andycadley

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)

Devilmarkus

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.
When you put your ear on a hot stove, you can smell how stupid you are ...

Amstrad CPC games in your webbrowser

JavaCPC Desktop Full Release

AMSDOS

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
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

andycadley

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.

Bytebreaker

#7
Quote
though rewriting it iteratively is usually better


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



I believe
this is another recursive way to draw the curve.
Here 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.

Overflow

#8
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:

       
  • only update on angle a(p) is required; the turtle is just RDRAWing the same line size
  • only 6 angles are required; so sinus and cosinus are stored in two 6-datas table
  • recursivity is used: GOSUB calls same GOSUB
  • p stands for "level of depth in sub-routine"; it is not stacked but just increases (+1) at each level
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...
Unregistered from CPCwiki forum.

SRS

If it is JAVA - try JAVAGRINDER to bring it to CPC :D


SRS

@Overflow:

If you add

5 defint a,p,c,s,i

you get it to run about 20% faster :D

Bytebreaker

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).

Overflow

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.

Unregistered from CPCwiki forum.

Powered by SMFPacks Menu Editor Mod