![]() |
Forum Index : Microcontroller and PC projects : Trying to draw fractal trees, odd behavior
Author | Message | ||||
daveculp Newbie ![]() Joined: 02/07/2020 Location: United StatesPosts: 22 |
Im trying to draw a simple fractal tree which draws a horizontal line then recursively draws two lines from the end point of that line by rotating -25 and + 25 degrees then keeps going fro a set number of iterations. Here is the code, a bit messy as I've been fiddling around with it.: The print statements are simply debug statements to let me see some values and can be REM'd out. drawTreeLeft(MM.HRES/2, MM.VRES,-90,10) drawTreeRight(MM.HRES/2, MM.VRES,-90,10) SUB drawTreeLeft (x1,y1, angle, iter) if iter >0 then x2 = x1 + int(cos( RAD(angle) ) * iter * 10.0) y2 = y1 + int(sin( RAD (angle) ) * iter * 10.0) print angle,":";x1,y1,":",x2,y2 line x1,y1,x2,y2,1,RGB(brown) drawTreeLeft(x2,y2, angle -25, iter - 1) REM drawTree(x2,y2, angle +25, iter - 1) else circle x1,y1,3,1,1,RGB(GREEN), RGB(GREEN) end if END SUB SUB drawTreeRight (x1,y1, angle, iter) if iter >0 then x2 = x1 +int(( cos( RAD(angle) )) * iter * 10.0) y2 = y1 +int(( sin( RAD (angle) )) * iter * 10.0) print angle,":";x1,y1,":",x2,y2 line x1,y1,x2,y2,1,RGB(brown) REM drawTree(x2,y2, angle -25, iter - 1) drawTreeRight(x2,y2, angle +25, iter - 1) else circle x1,y1,3,1,1,RGB(GREEN), RGB(GREEN) end if END SUB The odd behavior is the following two things: 1. x1 and x2 and y1 and y2 turn out to be the same and they shouldnt. I NEVER change the value of x1 and y1. Why is this? 2. Problem #1 is solved if I do something like the following in the function: drawTreeLeft(MM.HRES/2, MM.VRES,-90,10) drawTreeRight(MM.HRES/2, MM.VRES,-90,10) SUB drawTreeLeft (x1,y1, angle, iter) start_x = x1 start_y = y1 if iter >0 then x2 = x1 + int(cos( RAD(angle) ) * iter * 10.0) y2 = y1 + int(sin( RAD (angle) ) * iter * 10.0) print angle,":";x1,y1,":",x2,y2 line start_x,start_y,x2,y2,1,RGB(brown) drawTreeLeft(x2,y2, angle -25, iter - 1) REM drawTree(x2,y2, angle +25, iter - 1) else circle x1,y1,3,1,1,RGB(GREEN), RGB(GREEN) end if END SUB 3. I originally had it as one function which would call the drawTree sub twice (see the REM), one for drawing the left branch and one for the right. However, it only ever drew the left branch. 4. It should be recursively calling the drawTree function for EVERY LINE, but it doesn't. I figure #3 and #4 are probably due to the way MMBASIC handles recursion and I know there is a limit of 50 recursive calls. I will probably need to figure out another way to do this. I cant figure out #1 though. Why are x1 and y2 being set to x2 and y2? Edited 2020-07-09 07:50 by daveculp |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
Does it improve if you use local variables in the subroutines? Visit Vegipete's *Mite Library for cool programs. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
How about "Christmas in July" ' seasons greetings option explicit option default float mode 1 dim stX=mm.hres/2 'Tree starting point dim stY=mm.vres*0.9 dim newX, newY, leng dim angle = 30 '-30 dim stL = mm.vres/5 dim delta = stL/7 dim dr = 270 dim TurtleSpeed = 15 'speed options DIM as float stack(100) 'FILO stack DIM AS INTEGER cols(6) cols(0)= RGB(RED) cols(1)= RGB(WHITE) cols(2)= RGB(yellow) cols(3)= RGB(green) cols(4)= RGB(blue) cols(5)= RGB(magenta) dim stackpos=1 dim c=0 ' melody globals DIM AS FLOAT melody(160,2) DIM AS INTEGER tonePos, endTone, endMelody, t endMelody = 1 ' needs to be set so that the first melody will start playing CLS do IF endMelody = 1 THEN if tempr(42) <> 1000 then ' only print temperature if available text stX, stY+30, " "+str$(tempr(42),2,2)+" C ", cm endif t = (t+1) mod 2 select case t ' rotate melodies case 0 RESTORE jingleBells case 1 restore jinglebells2 end select playMelody ENDIF newX=stX newY=stY leng = stL angle = 0 - angle ' flip this each cycle to give windscreen washer action dr = 270 c=(c+1) mod 6 LINE newX, newY-1, newX, newY ,1,cols(c) drawtree loop END SUB drawtree local oldx, oldy, c, n IF endTone = 1 THEN playNextTone IF (leng > 0) THEN c = int(rnd()*6) oldX=newX oldY=newY newX=oldX - COS(RAD(dr))*leng newY=oldY + SIN(RAD(dr))*leng LINE oldX, oldY, newX, newY,1,cols(c) for n = 1 to TurtleSpeed ' break up the pause to allow for the tune to play smoothly PAUSE 1 IF endTone = 1 THEN playNextTone next n dr=dr+angle stack(stackpos)=leng stackpos=stackpos+1 leng = leng - delta drawtree 'recursive calling itself dr=dr-(angle * 2) drawtree 'recursive calling itself dr=dr+angle stackpos=stackpos-1 leng = stack(stackpos) oldX=newX oldY=newY newX=oldX - COS(RAD(dr)+3.14159)*leng newY=oldY + SIN(RAD(dr)+3.14159)*leng LINE oldX, oldY, newX, newY,1,cols(c) for n = 1 to TurtleSpeed PAUSE 1 IF endTone = 1 THEN playNextTone next n text stX, stY+10, time$, cm ENDIF END SUB ' music melodies SUB playMelody LOCAL AS INTEGER n ' assumes that the DATA pointer has been restored ' and the DATA ends with a pair of zeros tonePos = 0 endMelody = 0 FOR n = 1 TO 160 READ melody(n,1), melody(n,2) IF melody(n,1) + melody(n,2) = 0 THEN EXIT FOR NEXT n endTone = 1 ' ready to start playing END SUB SUB toneEnd endTone = 1 END SUB SUB playNextTone endTone = 0 tonePos = tonePos + 1 'settick 0,0,1 'turn off the 'rest' timer ' print melody(tonePos,1),melody(tonePos,2) if melody(tonePos,1) + melody(tonePos,2) > 0 then play tone melody(tonePos,1),melody(tonePos,1),melody(tonePos,2),toneEnd else ' don't re-set the end of tone flag ' just flag the end of melody endMelody = 1 endif end sub ' frequency, time pairs of DATA ' a zero frequency indicates a period of silence ' 0, 0 to indicate end of the melody JingleBells: DATA 392.0, 240.0, 659.3, 240.0, 587.3, 240.0, 523.3, 240.0 DATA 392.0, 960.0, 392.0, 240.0, 659.3, 240.0, 587.3, 240.0 DATA 523.3, 240.0, 440.0, 960.0, 440.0, 240.0, 698.5, 240.0 DATA 587.3, 28.2, 493.9, 240.0, 392.0, 240.0, 493.9, 240.0 DATA 587.3, 240.0, 784.0, 360.0, 784.0, 120.0, 698.5, 240.0 DATA 587.3, 240.0, 659.3, 960.0, 392.0, 240.0, 659.3, 240.0 DATA 587.3, 240.0, 523.3, 240.0, 392.0, 960.0, 370.0, 120.0 DATA 392.0, 240.0, 587.3, 28.2, 523.3, 240.0, 440.0, 960.0 DATA 440.0, 240.0, 698.5, 240.0, 659.3, 240.0, 587.3, 240.0 DATA 784.0, 240.0, 784.0, 120.0, 740.0, 120.0, 784.0, 120.0 DATA 740.0, 120.0, 784.0, 120.0, 830.6, 120.0, 784.0, 123.1 DATA 659.3, 240.0, 587.3, 240.0, 523.3, 480.0, 784.0, 480.0 DATA 659.3, 240.0, 659.3, 240.0, 659.3, 360.0, 622.3, 120.0 DATA 659.3, 240.0, 659.3, 240.0, 659.3, 360.0, 622.3, 120.0 DATA 659.3, 240.0, 784.0, 240.0, 587.3, 123.1, 659.3, 960.0 DATA 698.5, 240.0, 698.5, 240.0, 698.5, 360.0, 698.5, 120.0 DATA 698.5, 240.0, 659.3, 240.0, 659.3, 240.0, 659.3, 120.0 DATA 659.3, 120.0, 659.3, 240.0, 587.3, 240.0, 587.3, 240.0 DATA 659.3, 240.0, 587.3, 960.0, 0,0 ' End of JingleBells JingleBells2: DATA 392.0, 210.0, 0.0, 30.0, 659.3, 210.0, 0.0, 30.0 DATA 587.3, 210.0, 0.0, 30.0, 523.3, 210.0, 0.0, 30.0 DATA 392.0, 840.0, 0.0, 120.0, 392.0, 210.0, 0.0, 30.0 DATA 659.3, 210.0, 0.0, 30.0, 587.3, 210.0, 0.0, 30.0 DATA 523.3, 210.0, 0.0, 30.0, 440.0, 840.0, 0.0, 120.0 DATA 440.0, 210.0, 0.0, 30.0, 698.5, 210.0, 0.0, 30.0 DATA 587.3, 24.7, 0.0, 3.5, 493.9, 210.0, 0.0, 30.0 DATA 392.0, 210.0, 0.0, 30.0, 493.9, 210.0, 0.0, 30.0 DATA 587.3, 210.0, 0.0, 30.0, 784.0, 315.0, 0.0, 45.0 DATA 784.0, 105.0, 0.0, 15.0, 698.5, 210.0, 0.0, 30.0 DATA 587.3, 210.0, 0.0, 30.0, 659.3, 840.0, 0.0, 120.0 DATA 392.0, 210.0, 0.0, 30.0, 659.3, 210.0, 0.0, 30.0 DATA 587.3, 210.0, 0.0, 30.0, 523.3, 210.0, 0.0, 30.0 DATA 392.0, 840.0, 0.0, 120.0, 370.0, 105.0, 0.0, 15.0 DATA 392.0, 210.0, 0.0, 30.0, 587.3, 24.7, 0.0, 3.5 DATA 523.3, 210.0, 0.0, 30.0, 440.0, 840.0, 0.0, 120.0 DATA 440.0, 210.0, 0.0, 30.0, 698.5, 210.0, 0.0, 30.0 DATA 659.3, 210.0, 0.0, 30.0, 587.3, 210.0, 0.0, 30.0 DATA 784.0, 210.0, 0.0, 30.0, 784.0, 105.0, 0.0, 15.0 DATA 740.0, 105.0, 0.0, 15.0, 784.0, 105.0, 0.0, 15.0 DATA 740.0, 105.0, 0.0, 15.0, 784.0, 105.0, 0.0, 15.0 DATA 830.6, 105.0, 0.0, 15.0, 784.0, 107.7, 0.0, 15.4 DATA 659.3, 210.0, 0.0, 30.0, 587.3, 210.0, 0.0, 30.0 DATA 523.3, 420.0, 0.0, 60.0, 784.0, 420.0, 0.0, 60.0 DATA 659.3, 210.0, 0.0, 30.0, 659.3, 210.0, 0.0, 30.0 DATA 659.3, 315.0, 0.0, 45.0, 622.3, 105.0, 0.0, 15.0 DATA 659.3, 210.0, 0.0, 30.0, 659.3, 210.0, 0.0, 30.0 DATA 659.3, 315.0, 0.0, 45.0, 622.3, 105.0, 0.0, 15.0 DATA 659.3, 210.0, 0.0, 30.0, 784.0, 210.0, 0.0, 30.0 DATA 587.3, 107.7, 0.0, 15.4, 659.3, 840.0, 0.0, 120.0 DATA 698.5, 210.0, 0.0, 30.0, 698.5, 210.0, 0.0, 30.0 DATA 698.5, 315.0, 0.0, 45.0, 698.5, 105.0, 0.0, 15.0 DATA 698.5, 210.0, 0.0, 30.0, 659.3, 210.0, 0.0, 30.0 DATA 659.3, 210.0, 0.0, 30.0, 659.3, 105.0, 0.0, 15.0 DATA 659.3, 105.0, 0.0, 15.0, 659.3, 210.0, 0.0, 30.0 DATA 587.3, 210.0, 0.0, 30.0, 587.3, 210.0, 0.0, 30.0 DATA 659.3, 210.0, 0.0, 30.0, 587.3, 840.0, 0.0, 120.0, 0,0 ' End of JingleBells2 Jim VK7JH MMedit |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
I wonder if in each drawtree you need local x2, y2 I'm not sure if you meant not to specify any types and are happy with the default. John Edited 2020-07-09 16:33 by JohnS |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
CLS drawTreeLeft(MM.HRES/2, MM.VRES,-90,10) drawTreeRight(MM.HRES/2, MM.VRES,-90,10) SUB drawTreeLeft (x1,y1, angle, iter) LOCAL xx1, yy1 xx1 = x1 yy1 = y1 IF iter >0 THEN x2 = xx1 + INT(COS( RAD(angle) ) * iter * 10.0) y2 = yy1 + INT(SIN( RAD (angle) ) * iter * 10.0) PRINT angle,":";xx1,yy1,":",x2,y2 LINE xx1,yy1,x2,y2,1,RGB(BROWN) drawTreeLeft(x2,y2, angle -25, iter - 1) REM drawTree(x2,y2, angle +25, iter - 1) ELSE CIRCLE x1,y1,3,1,1,RGB(GREEN), RGB(GREEN) END IF END SUB SUB drawTreeRight (x1,y1, angle, iter) LOCAL xx1, yy1 xx1 = x1 yy1 = y1 IF iter >0 THEN x2 = xx1 +INT(( COS( RAD(angle) )) * iter * 10.0) y2 = yy1 +INT(( SIN( RAD (angle) )) * iter * 10.0) PRINT angle,":";xx1,yy1,":",x2,y2,"**" LINE xx1,yy1,x2,y2,1,RGB(BROWN) REM drawTree(x2,y2, angle -25, iter - 1) drawTreeRight(x2,y2, angle +25, iter - 1) ELSE CIRCLE x1,y1,3,1,1,RGB(GREEN), RGB(GREEN) END IF END SUB Jim VK7JH MMedit |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |