I have a recursive function for moving some circles on a canvas. Overed circle is enlarged (zoom in) and all the other circles is pushed away. Pushed circles push other circles
It doesn't surprise this overflows because the algorithm grows the stack as it iterates but the exit condition is unpredictable, actions are not tightly localized (they have knock-on effects to nearby circles), so processing time will be chaotic.
I would reconsider the algorithm. Consider finding the two closest circles, if these are further apart than a given threshold apart, abort. Otherwise move them apart a little and repeat.
You don't need to know the number or operations needed for you to make an iterative solution. The point is to replace the JavaScript stack with one of your own. Check this answer to see an example how to implement it: Link
You can use an Array object as a stack in JavaScript since it supports push()
and pop()
.
PS: As Jim's answer suggested, you can usually find an algorithm that doesn't need this many levels of recursion.
Try to make sure the recursion step is only done for greater than base case. For example in quicksort here:
function qsort(k){
if(k == []){
return k;
}
if(k.length == 1){
return k;
}
//pick random pivot
var p = Math.floor(Math.random()*k.length);
console.log("pivot is" + p + "\n");
//set left and right iter
var l = 0; var r = k.length - 1;
while( l < r){
console.log('hi\n');
//move l until its element is bigger than pivot
while(k[l] < k[p] && l < k.length) {
l++;
console.log('h1i\n');
}
//move r until its element is smaller than pivot
while(k[r] > k[p] && r >= 0) {r--;
console.log('h2i\n');
}
//swap k[l] with k[r]
var temp = k[l]; k[l] = k[r]; k[r] = temp;
}
if(l == r){
//swap k[l] with k[p]
temp = k[l]; k[l] = k[p]; k[p] = temp;
}
var lk = k.slice(0,p); var rk = k.slice(p,k.length);
console.log(lk);
console.log(rk);
if(lk.length > 1){
lk = qsort(lk);
}
if(rk.length > 1){
rk = qsort(rk);
}
result = lk.concat(rk);
console.log(result);
return result;
}
var k = [23,245,67,34,24];
var result = qsort(k);
console.log(result);
//document.write(result);
If instead of lk.length > 1
you used something like lk != []
or not have a check, it could sometimes give call stack size exceeded errors and sometimes work depending on which pivots got chosen.
1) I can not implement iteration because of unknown count of operations needed;
Well, I have not looked at your code, but a general avoidance of linear recursion (you have a linear one here) looks like this:
while (1 == 1) {
if (breakcondition)
break;
doSomeCode()
}
So you do not have to know the exact number of iterations like in the for
- loop case.