猿问

在 webgl 中绘制递归分形 2d 树

我试图在 webgl 中绘制一个简单的二叉分形树,但是分支没有以我想要的正确角度。我通过将顶点的点绘制到一个数组中来绘制树,然后将该数组插入一个 float32array 中,然后调用 drawArrays(LINE_STRIPE)。


这是本周一到期的编程任务。我确实记得在高中时递归地绘制二叉分形树,但它是使用scratch完成的。自从我做任何需要触发的数学运算也已经很长时间了。


下面的函数是一个递归函数,它将顶点的坐标推入一个数组,稍后将传递给一个 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 度,尽管它看起来很近。


紫衣仙女
浏览 290回答 1
1回答

临摹微笑

LINE_STRIPE不是做你想做的合适的原始类型,因为线条是一条连贯的线。使用原始类型LINES。所以每个分支创建一个单独的线段:该函数必须计算当前分支的终点并将线段的 2 个顶点添加到点列表中:let x2 = x + length * Math.sin(angle);let y2 = y + length * Math.cos(angle);points.push(x, y, x2, y2);通过 e 递归调用,在当前分支的末尾有 2 个新分支:createPoints(depth-1, x2, y2, length/2, angle+Math.PI/4, points);createPoints(depth-1, x2, y2, length/2, angle-Math.PI/4, points);完整的函数编码:function createPoints(depth, x, y, length, angle, points) {&nbsp; &nbsp; if (depth <= 0)&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; // end of current line segment&nbsp; &nbsp; let x2 = x + length * Math.sin(angle);&nbsp; &nbsp; let y2 = y + length * Math.cos(angle);&nbsp; &nbsp; // add segment&nbsp; &nbsp; points.push(x, y, x2, y2);&nbsp; &nbsp; // create 2 branches&nbsp; &nbsp; createPoints(depth-1, x2, y2, length/2, angle+Math.PI/4, points);&nbsp; &nbsp; createPoints(depth-1, x2, y2, length/2, angle-Math.PI/4, points);}例如 4 个级别:let points = [];createPoints(4, 0, -1.0, 1.0, 0.0, points);如果你无论如何想使用原始类型LINE_STRIP,那么每个分支都必须添加一个端点,但必须在每个子分支之后返回到这个点:function createPointsStrip(depth, x, y, length, angle, points) {&nbsp; &nbsp; if (depth <= 0)&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; // end of current line segment&nbsp; &nbsp; let x2 = x + length * Math.sin(angle);&nbsp; &nbsp; let y2 = y + length * Math.cos(angle);&nbsp; &nbsp; // add point&nbsp; &nbsp; points.push(x2, y2);&nbsp; &nbsp; // create 2 branches&nbsp; &nbsp; createPointsStrip(depth-1, x2, y2, length/2, angle+Math.PI/4, points);&nbsp; &nbsp; points.push(x2, y2);&nbsp; &nbsp; createPointsStrip(depth-1, x2, y2, length/2, angle-Math.PI/4, points);&nbsp; &nbsp; points.push(x2, y2);}在调用递归函数之前,必须将第一点添加到点列表中:let points = [0.0, -1.0];createPointsStrip(4, 0, -1.0, 1.0, 0.0, points);生成的基元完全不同,但看起来相同(在这种情况下)。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答