【发布时间】:2017-10-11 11:10:24
【问题描述】:
我正在尝试解决“Eric S. Roberts (1986) 的递归思考”一书中的任务 9.3。 假设我们有一个简单的三角形:
.
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/_______________________\
将较小的跳蚤放在构成大跳蚤背面的两个部分中的每一个上,即可进入下一阶段:
.
/ \
/ \
/ \
_________/ \_________
\ / \ /
\ / \ /
\ / \ /
\ / \ /
/ \
/ \
/ \
/_______________________\
这两种新跳蚤中的每一种都有两个较小的跳蚤,它们为我们提供了以下动物园:
.
/ \
/ \
. / \ .
___/_\___/ \___/_\___
\ / \ /
: / \ :
/_\ / \ /_\
\ / \ /
/ \
/ \
/ \
/_______________________\
问题是我无法弄清楚这里的递归模式。我什至不知道我应该如何开始思考这个任务以找到解决方案。
对于绘图,我使用 3 个函数:
- setPointer(x, y) -- 将笔设置为坐标 x,y
- vector(dx,dy) -- 从 x, y 到 dx, dy 画线
- polarVec(l, angle) 从 x, y 画线,长度为 l,角度(度)
我在 Canvas 的绘画课:
var X_CENTER = 400;
var Y_CENTER = 400;
function DrawLib() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var inverted_y = 800;
var _dx = 0, _dy = 800;
this.setPoint = function (x, y) {
inverted_y = 800;
inverted_y -= y;
_dx = x;
_dy = inverted_y;
ctx.moveTo(x, inverted_y);
};
this.vector = function(dx, dy) {
_dx += dx;
_dy -= dy;
ctx.lineTo(_dx, _dy);
};
this.polarVec = function(lengthPx, angle) {
var radians = angle * Math.PI / 180;
this.vector(lengthPx * Math.cos(radians), lengthPx * Math.sin(radians));
}
this.stroke = function () {
ctx.stroke();
}
}
var drawLib = new DrawLib();
我的解决方案(仅适用于订单 0 和 1):
function fractLine(order, l, theta) {
if (order == 0) return drawLib.polarVec(l, theta);
fractLine(order - 1, 2 * l/3,theta);
fractLine(order - 1, l/3,theta - 120);
fractLine(order - 1, l/3,theta + 120);
fractLine(order - 1, 2* l/3,theta);
}
function triangleWithFleas(order, l) {
//left side of triangle
drawLib.setPoint(X_CENTER - l/2, Y_CENTER - Math.sqrt(3)* l/4);
//start drawing
drawLib.vector(l,0);
fractLine(order, l, 120);
fractLine(order, l, 240);
drawLib.stroke();
}
triangleWithFleas(1, 400);
【问题讨论】:
-
如果您只考虑
polarVec(),也许会更容易?您需要一个从特定起点以特定方向绘制三角形的函数。然后,它递归调用自己两次,调整每次调用的方向和起点。 -
@jxh 感谢您的重播!我在我的问题中添加了代码。它仅适用于订单 0 和 1。我无法发现我的错误在哪里。你能看一下吗?
-
@jxh 刚刚更新了我的代码。现在它完美地工作了。非常感谢!
标签: javascript recursion canvas fractals