我正在尝试在webgl中绘制一个简单的二进制分形树,但是这些分支并没有按照我想要的适当角度移动。我通过将顶点绘制到数组中来绘制树,然后将该数组插入float32array中,然后调用drawArrays(LINE_STRIPE)。
这是本周一的编程任务。我确实记得在高中时递归绘制了二叉树,但这是使用草稿完成的。自从我进行任何需要触发的数学运算以来,也已经很长时间了。
下面的函数是一个递归函数,它将顶点的坐标推入一个数组,然后将其传递到float32array中。
function createPoints(x, y, length, depth, angle, points)
{
if(depth > 0)
{
//draws line
points.push((x + length) * Math.sin(angle));
points.push((y + length) * Math.cos(angle));
let currentx = (x + length) * Math.sin(angle);
let currenty = (y + length) * Math.cos(angle);
//draw left branch
angle += Math.PI / 4;
console.log(angle);
createPoints((x + length/2) * Math.sin(angle), (y + length/2) * Math.cos(angle), length/2, depth - 1, angle, points);
//goes back somehow
points.push(currentx);
points.push(currenty);
//draw right branch
angle -= Math.PI / 2;
console.log(angle);
createPoints((x + length/2) * Math.sin(angle), (y + length/2) * Math.cos(angle), length/2, depth - 1, angle, points);
return points;
}
return;
}
预期的输出是递归深度为2的树,它只是一个简单的Y形。分支应与基本树干旋转45度。但是,正如您在我的输出中看到的,情况并非如此:
右分支实际上似乎不在45度,尽管看起来很近。
LINE_STRIPE
不是正确的Primitive类型以执行所需的操作,因为线带是一条连贯的线。使用基本类型LINES
。因此,每个分支都创建一个单独的线段。
在功能createPoints
中,需要一个附加参数。除了当前分支的全局角度之外,您还必须知道与当前分支相比,当前分支通过其更改其方向的角度。
function createPoints(depth, x, y, length, angle, deltaAng, points) { // [...] }
该函数必须计算当前分支的终点并将线段的2个顶点添加到点列表中:
let x2 = x + length * Math.cos(angle); let y2 = y + length * Math.sin(angle); points.push(x, y, x2, y2);
以及通过递归调用在当前分支的末尾添加2个新分支:
let newDeltaAng = deltaAng/2; createPoints(depth-1, x2, y2, length/2, angle+newDeltaAng, newDeltaAng, points); createPoints(depth-1, x2, y2, length/2, angle-newDeltaAng, newDeltaAng, points);
功能的完整编码:
function createPoints(depth, x, y, length, angle, deltaAng, points) { if (depth <= 0) return; // end of current line segment let x2 = x + length * Math.cos(angle); let y2 = y + length * Math.sin(angle); // add segment points.push(x, y, x2, y2); // create 2 branches let newDeltaAng = deltaAng/2; createPoints(depth-1, x2, y2, length/2, angle+newDeltaAng, newDeltaAng, points); createPoints(depth-1, x2, y2, length/2, angle-newDeltaAng, newDeltaAng, points); }
例如4个级别:
let points = [];
createPoints(4, 0, -1.0, 1.0, Math.PI/2, Math.PI/2, points);