我有一個遞歸函數來移動畫布上的一些圓圈。內圈被放大(放大),所有其他圈被推開。 推動的圓圈推動其他圓圈等,直到縮放完成。JavaScript遞歸:超出最大調用堆棧大小
我得到一個錯誤「最大調用堆棧大小超過了」,我理解這個問題,但我只是不知道如何解決它... 我發現了三個可能的解決方案用於解決一般的遞歸問題:
- 更改遞歸進行迭代
- 使用memoization
- 使用的setTimeout
但我認爲,我可以使用他們沒有:
- 我無法實現,因爲操作的未知數量需要反覆
- 我不明白,記憶化不夠好,但我認爲它不適合或者(或也許我錯了,有人可以告訴我)
- 我不能使用SetTimeout,因爲它應該阻止在這個特定動畫的函數調用。
如何解決此問題?
// Pushes circles aside when some other circle leans on these circles (on zoom in)
var moveCirclesAside = function(circle1, circleToSkip, groupOfMoves) {
var count = circles.length;
for (var i = 0; i < count; i++) {
// Skip the same circle
if (i == circle1.i) {
continue;
}
// Also skip the circle which was intended not to move any further
if (circleToSkip != null && i == circleToSkip.i) {
continue;
}
// Get second circle
var circle2 = circles[i];
// Calculate a distance between two circles
var dx = circle2.x - circle1.x;
var dy = circle2.y - circle1.y;
var distance = Math.sqrt((dx * dx) + (dy * dy));
// If circles already collided need to do some moving...
if (distance <= circle1.r + circle2.r + OD.config.circleSpacing) {
// Get collision angles
var angle = Math.atan2(dy, dx);
var sine = Math.sin(angle);
var cosine = Math.cos(angle);
// Some circle position calculation
var x = OD.config.circleSpacing;
var xb = x + (circle1.r + circle2.r);
var yb = dy * cosine - dx * sine;
// Save each state (move) of any circle to the stack for later rollback of the movement
groupOfMoves.push(copyCircleByVal(circle2));
// Move the circle
circle2.x = circle1.x + (xb * cosine - yb * sine);
circle2.y = circle1.y + (yb * cosine + xb * sine);
// Make sure that circle won't go anywhere out of the canvas
adjustCircleByBoundary(circle2);
// If moved circle leans against some other circles make sure that they are moved accordingly
// And such related moves must be grouped for correct rolback of moves later - so we pass 'groupOfMoves' var
moveCirclesAside(circle2, circle1, groupOfMoves);
}
}
};
您的回答也很有幫助,但可悲的是我只能接受一個答案......謝謝! – fizis 2012-02-29 13:35:32
我已經爲你表達了這種感悟。 – agm1984 2017-11-12 21:07:11