javascript - webgl 中的递归分形二维树绘制

标签 javascript tree webgl trigonometry

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

这是一份周一到期的编程作业。我确实记得在高中时递归地画了一棵二元分形树,但它是用scratch完成的。我也已经很长时间没有做过任何需要三 Angular 函数的数学了。

下面的函数是一个递归函数,它将顶点的坐标推送到一个数组中,稍后该数组将被传递到一个 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 形状。 Twig 应从基干旋转 45 度。但是,正如您在我的输出中看到的那样,情况并非如此:

右分支实际上不是 45 度,尽管看起来很接近。

最佳答案

LINE_STRIPE 不是正确的 Primitive键入来做你想做的事,因为线条是一条连贯的线。
使用原始类型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) {

    if (depth <= 0)
        return;

    // end of current line segment
    let x2 = x + length * Math.sin(angle);
    let y2 = y + length * Math.cos(angle);

    // add segment
    points.push(x, y, x2, y2);

    // create 2 branches
    createPoints(depth-1, x2, y2, length/2, angle+Math.PI/4, points);
    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) {

    if (depth <= 0)
        return;

    // end of current line segment
    let x2 = x + length * Math.sin(angle);
    let y2 = y + length * Math.cos(angle);

    // add point
    points.push(x2, y2);

    // create 2 branches
    createPointsStrip(depth-1, x2, y2, length/2, angle+Math.PI/4, points);
    points.push(x2, y2);
    createPointsStrip(depth-1, x2, y2, length/2, angle-Math.PI/4, points);
    points.push(x2, y2);
}

在调用递归函数之前,必须将第一个点添加到点列表中:

let points = [0.0, -1.0];
createPointsStrip(4, 0, -1.0, 1.0, 0.0, points);

生成的原语完全不同,但看起来相同(在本例中)。

关于javascript - webgl 中的递归分形二维树绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58354311/

相关文章:

javascript - 轮监听器在事件发生后获取位置

c++ - 数据结构中的 MST 和唯一性问题已解决 Ex?

c++ - Qt中如何绘制数据流图?

algorithm - 展平二叉树的运行时间

graphics - 绘制像素化的纹理

javascript - 使用时输出的渲染方式不同(for循环与setInterval,requestAnimationFrame)

arrays - 我可以在 WebGL 的 GLSL 中将什么用作数组索引?

javascript - React 不在客户端代码中插入跨度?

javascript - Bootstrap scrollspy 未检测到 home

JavaScript 随机数组