webgl中的递归分形2d树图

问题描述 投票:0回答:1

我正在尝试在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度,尽管看起来很近。

javascript tree webgl trigonometry
1个回答
0
投票

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);

© www.soinside.com 2019 - 2024. All rights reserved.