Discuss Scratch

eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

Hello there scratch, i have a problem, again. So, i made this function which calls 2 functions. both of these other functions are also recursion functions. but the 2nd recursion function wont be reached because the first one is running and for some reason it doesnt even run when the 1st one ends. Yes, i tried using broadcasts, nope nothing works. Basically this is just a fractal tree that im trying to make so theres this branch function which calls 2 functions to create left branch and right branch and i want it to run both of these function at the end of any new branch created but it never works only one branch is created due to the problem stated above. i have run out of ideas on how to fix this. Please help
kriblo
Scratcher
100+ posts

recursion function not allowing other function to run

eleventyOne wrote:

Hello there scratch, i have a problem, again. So, i made this function which calls 2 functions. both of these other functions are also recursion functions. but the 2nd recursion function wont be reached because the first one is running and for some reason it doesnt even run when the 1st one ends. Yes, i tried using broadcasts, nope nothing works. Basically this is just a fractal tree that im trying to make so theres this branch function which calls 2 functions to create left branch and right branch and i want it to run both of these function at the end of any new branch created but it never works only one branch is created due to the problem stated above. i have run out of ideas on how to fix this. Please help
To be honest, it sounds like you made a mistake somewhere… so we would have to look at the code. Do you have a link?
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

and for some reason its has become very slow. like, it used to draw everything instantly. it happened after i added the main branch function.
Scratch-Minion
Scratcher
1000+ posts

recursion function not allowing other function to run

You need to set up values for direction_rotate_x and direction_rotate_y otherwise your project does not produce the same results each time.

When you use recursion, you need a check or test to stop the recursion going on forever.
You have infinite recursive loops that never finish.


In your project, inside custom blocks Branch_1 and Branch_2 you should put an if block around the recursive call to the Branch custom block.

The test in the if block could be to check that the distance between the start and end points for the new branch is greater than 1 (otherwise you do not want to do any more recursion as the branches are too small).

Use Pythagoras for the distance check: ie. sqrt( (new_endX - endX) ^ 2 + (new_endY - endY) ^ 2 ) > 1
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

First of all that is not the main problem. i know it goes on forever. some time ago i added a block to continue only if clicked and even without that the recursion stops after some time by itself. and onto the main problem: its not branching off again and again like it should have two branches left and right at the end of every line but only the right branch is called. i also know that the nexxt recursion function might work if i stop the first recursion like u said above but it doesnt work.
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

Scratch-Minion wrote:

You need to set up values for direction_rotate_x and direction_rotate_y otherwise your project does not produce the same results each time.

When you use recursion, you need a check or test to stop the recursion going on forever.
You have infinite recursive loops that never finish.


In your project, inside custom blocks Branch_1 and Branch_2 you should put an if block around the recursive call to the Branch custom block.

The test in the if block could be to check that the distance between the start and end points for the new branch is greater than 1 (otherwise you do not want to do any more recursion as the branches are too small).

Use Pythagoras for the distance check: ie. sqrt( (new_endX - endX) ^ 2 + (new_endY - endY) ^ 2 ) > 1
wait, did u try what u said yourself and its working or are you just theorising?
deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

Can you explain what you expect to happen? Branch calls Draw Line which is fine but then calls branch_2 which calls Branch again. There is nothing to stop it looping forever. The key to recursion is to always ensure there is a stopping condition. Presumably the distance that is calculated being below a certain value should be the stopping condition.

Incidentally, it would be much better for the third sprite to just have it's size and rotation style set once. There's no point setting them repeatedly. Same goes for other sprites.
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

Once again i am saying there is no prob with stopping recursion. i just removed the stopping part for some time. This is the main problem: check out an image of a fractal tree, every branch has 2 more branches, left and right. mine just has one. how to fix that? and as i stated above stopping the recursion does not solve anything
deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

You've made major changes to the code. It's hard to help on a moving target!
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

deck26 wrote:

You've made major changes to the code. It's hard to help on a moving target!
no i actually did a lot of undo's this was my previous code. since no one seems to understand my code i changed it to its previous form. See what im trying to say? every EVERY line should have two branches. here only the starting line has 2 branches. this is what i want help with.
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

I made the main branch function to fix this but that just seems to mess things up even more and slow things down. And i dont knoww what the hell is the problem with broadcasts.

Last edited by eleventyOne (April 4, 2020 11:09:29)

deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

Recursion needs careful thought. Please specify how you expect this to happen in more detail. Are you expecting it to draw two branches and then split each of those into two and then split all branches so far in two and so on or will it draw all the right banches it can before adding any new left branch? Because those would be coded very differently.

The second is easier and is what you seemed to be trying to do when I first looked but since you weren't stopping the recursive drawing of the right branch when it got too small to draw you never got a single left branch. That is why we were saying the recursion has to have an end condition!
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

ok then, see for yourself, i addded a mouse pressed condition
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

This is the javascript code for reference which uses the p5.js library. I know lot of it is not implemented in the scratch project. But i kind of did a workaround? pls tell me how to fix it?


var tree = [];
var leaves = [];
var i = 0
function setup() {
  createCanvas(480, 360);
  var a = createVector(width / 2, height);
  var b = createVector(width / 2, height - 100);
  var root = new Branch(a, b);
  tree[0] = root;
}
function mousePressed() {
  for (var i = tree.length - 1; i >= 0; i--) {
    if (!tree[i].finished) {
      tree.push(tree[i].branchA());
      tree.push(tree[i].branchB());
    }
    tree[i].finished = true;
  }
}
function draw() {
  background(51);
  for (var i = 0; i < tree.length; i++) {
    tree[i].show();
  }
}

function Branch(begin, end) {
  this.begin = begin;
  this.end = end;
  this.finished = false;
  this.show = function() {
    stroke(255,60,2);
    line(this.begin.x, this.begin.y, this.end.x, this.end.y);
  }
  this.branchA = function() {
    var dir = p5.Vector.sub(this.end, this.begin);
    dir.rotate(PI/4);
    dir.mult(0.67);
    var newEnd = p5.Vector.add(this.end, dir);
    var b = new Branch(this.end, newEnd);
    return b;
  }
  this.branchB = function() {
    var dir = p5.Vector.sub(this.end, this.begin);
    dir.rotate(-PI /4);
    dir.mult(0.67);
    var newEnd = p5.Vector.add(this.end, dir);
    var b = new Branch(this.end, newEnd);
    return b;
  }
}
deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

eleventyOne wrote:

ok then, see for yourself, i addded a mouse pressed condition
So what you have there are two recursive functions. One is drawing the left branches only and the other the right branches only. But none ever completes.

So branch_1 calls branch_1 and waits for it to complete. But the second copy has called branch_1 and is waiting for it to complete and that copy has called branch_1 and is waiting for it to complete and so on. You haven't added a stop condition, just a pause until the mouse is clicked. What you need to be doing is stopping the script if the mouse is clicked. But that still only draws the left and right main branches because once you've called branch_1 you never call branch_2 for that branch.

What you need, I think, is a general Branch custom block which draws a line with the specified parameters and then calls itself to draw a line with new parameters but those should just be based on the parameters from the branch it just drew - from the look of the javascript that should be 0.67 times the length and the original direction plus/minus pi/4 radians which is 45 degrees.

That's why I asked the question earlier. If you do this

custom block branch (dist, dir)
point in direction dir
pen down
move dist
pen up
if (dist > 5) then
branch (dist*0.67), dir + 45)
branch(dist*.0.67), dir - 45)
endif

it will draw the entire first right branch first. Say dist started at 20 and dir = 0 we get (approx values for dist)

branch (20, 0)
branch(13, 45) - right branch
branch(9, 90) - right branch
branch (6, 135) - right branch
branch(4,180) - right twig and stop
branch(4,90) - left twig and stop
branch(6, 45) - left branch
branch(4, 90) - right twig and stop
branch(4,0) - left twig and stop

and so on. The indentation indicates the level of custom blocks calls

Last edited by deck26 (April 4, 2020 13:01:37)

eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

Would this still be vector based?
deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

You're still drawing with the pen in the same way. You'd need to pass the start position for each line but the next call just uses the position at the end of the last drawn line. Easiest modification is something like

draw line
branch dist, dir, x-position, y-positon

so both sub-branches start at the same place
eleventyOne
Scratcher
82 posts

recursion function not allowing other function to run

Is this what you're trying to say? or something similar to it?
var angle = 0;
var slider;
function setup() {
  createCanvas(400, 400);
  slider = createSlider(0, TWO_PI, PI / 4, 0.01);
}
function draw() {
  background(51);
  angle = slider.value();
  stroke(255);
  translate(200, height);
  branch(100);
}
function branch(len) {
  line(0, 0, 0, -len);
  translate(0, -len);
  if (len > 4) {
    push();
    rotate(angle);
    branch(len * 0.67);
    pop();
    push();
    rotate(-angle);
    branch(len * 0.67);
    pop();
  }
deck26
Scratcher
1000+ posts

recursion function not allowing other function to run

https://scratch.mit.edu/projects/382689035/

Approx 25 blocks, one sprite.

Powered by DjangoBB