Drawing recursive 2D tree fractals using WebGL technology

Attempting to create a binary fractal tree in webgl, but struggling with the branch angles not aligning as desired. The approach involves plotting vertex points into an array, converting it into a float32array, and then utilizing drawArrays(LINE_STRIPE) for rendering.

This task is part of a programming assignment due soon. While I have prior experience with recursively drawing a binary fractal tree in scratch during high school, it has been a while since I delved into trigonometry.

Below is a recursive function that populates an array with vertex coordinates for use in a 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);

    //backtrack
    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;
}

Expected output is a simple Y-shaped tree of recursion depth 2 with 45-degree rotated branches. However, the generated output does not align as intended:

https://i.sstatic.net/2jZZw.png

The right branch does not align at 45 degrees, despite appearing close.

Answer №1

LINE_STRIPE may not be the most suitable Primitive type for your needs, as a line strip consists of one coherent line.
Instead, consider using the primitive type LINES. This way, each branch will create a separate line segment:

The function must calculate the end point of the current branch and add the 2 vertices for the line segment to the point list:

let x2 = x + length * Math.sin(angle);
let y2 = y + length * Math.cos(angle);

points.push(x, y, x2, y2);

Add 2 new branches at the end of the current branch through a recursive call:

createPoints(depth-1, x2, y2, length/2, angle+Math.PI/4, points);
createPoints(depth-1, x2, y2, length/2, angle-Math.PI/4, points);

Here is the complete code of the function:

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

For example, with 4 levels:

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

https://i.sstatic.net/scC1f.png


If you still prefer to use the primitive type LINE_STRIP, then each branch should add a single end point, but return to this point after each child branch:

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

The first point must be added to the list of points before calling the recursive function:

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

The resulting primitive is entirely different but appears the same (in this particular case).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What's the importance of including (req, res, next) in the bodyParser function within Express?

My original use of bodyParser looked like this: app.use(bodyParser.json()); However, I now have a need to conditionally use bodyParser: app.use((req, res, next) => { if (req.originalUrl === '/hooks') { next(); } else { ...

CSS and Javascript functioning correctly within internal server, but encountering issues when accessed externally

I am in the process of creating a website for a friend. The goal is to have a flashy animated style website that functions well on IOS and allows him to make changes easily. To achieve this, I am utilizing JQuery, my own javascript, and multiple css files. ...

The error message "The useRef React Hook cannot be invoked within a callback function" is displayed

I'm currently working on developing a scroll-to feature in Reactjs. My goal is to dynamically generate referenced IDs for various sections based on the elements within an array called 'labels'. import { useRef } from 'react'; cons ...

Problem with deleting or substituting symbols and character codes within a String

I am attempting to send an object called dataO from Node.js/Express/EJS to the client side. On the Node.js script side: var dataO = {"first":[20000, 14000, 12000, 15000, 18000, 19000, 22000], "second":[12000, 11000, 18000, 12000, 19000, 14000, 26000]}; var ...

Angular 2 decorators grant access to private class members

Take a look at this piece of code: export class Character { constructor(private id: number, private name: string) {} } @Component({ selector: 'my-app', template: '<h1>{{title}}</h1><h2>{{character.name}} detai ...

Can you point me to the location where the 'req' parameter is specified?

I've been exploring a new authentication approach detailed in this article. One issue I'm encountering is locating where the req parameter is declared in the snippet below. It seems like my code won't compile because this parameter isn&apos ...

Creating a dynamic webpage using Javascript that responds to user clicks on page links

I am interested in the process of inserting JavaScript objects from a JSON file in order to dynamically create a unique page based on a user's clicked link. This concept is similar to having a wildcard page in popular frameworks like Laravel or Django ...

Tips for sending an email without using MAILTO in JavaScript or jQuery

Today is a great day for many, but unfortunately not for me. I've been struggling with this issue for over two weeks now and can't seem to find a solution anywhere on the internet. Stack Overflow always comes to my rescue when things get really t ...

Dropdown Menu with Bootstrap 4 Toggle Checkbox

Within a Bootstrap 4 dropdown menu, I integrated a checkbox styled with the Bootstrap Toggle Plugin. However, upon clicking the toggle switch, the menu abruptly closes. To address this issue, I added onclick="event.stopPropagation();" to the menu item, as ...

Dealing with click events on layers with z-index positioning

In the map application I am developing, I have implemented 2 z-index layers. However, a problem arises when attempting to zoom in by clicking on these layers. The click handler is located on the lower z-index layer and I do not want it to execute when a co ...

Utilizing Laravel for Making Ajax Calls to Controller

I am a beginner in using Laravel and I am trying to create an API with Laravel using AJAX calls. However, when I make the AJAX call, the URL appears to show an invalid server path. Below is my code: My Route file : Route::get("a/b","AController@c"); My ...

A JavaScript function written without the use of curly braces

What makes a function good is how it is declared: export declare class SOMETHING implements OnDestroy { sayHello() { // some code to say hello } } However, while exploring the node_modules (specifically in angular material), I stumbled up ...

Unlocking request header field access-control-allow-origin on VueJS

When attempting to send a POST request to the Slack API using raw JSON, I encountered the following error: Access to XMLHttpRequest at '' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field acces ...

Order JSON Array Using LoDash Library

Recently I encountered a JSON array with the following structure: var json = [ { key: 'firstName', value: 'Bill' }, { key: 'lastName', value: 'Mans' }, { key: 'phone', value: '123.456.7890&apo ...

Flask caches JSON files automatically

I am currently working on a visualization app using js and python. The functionality of my app is as follows: There is a textbox in the browser where I input an URL The URL is then sent to Python via Flask In Python, the URL is processed to create ...

Placing the date of each blog post at the end of the excerpt

Currently, there is a grid section on the homepage of our site showcasing the two most recent blog posts. I am looking for a Javascript solution to relocate the date to the bottom of each block, outside of the border. For reference, you can visit the follo ...

Include the HTTP header in a GET request for an HTML hyperlink

Within my HTML code, I am using an <a> tag that will trigger a 302 redirect when clicked. However, I need to incorporate some HTTP headers into this GET request. Is there a way to achieve this without including the headers in the href attribute? Tha ...

Incorporating database coordinates into Marker React Leaflet: A Step-by-Step Guide

When I retrieve coordinates from the database, they are structured as "lat" and "lon" fields. In my mapping application, I have multiple markers to display. How can I combine these two fields to pass coordinates (coord.lat and coord.lon) to the Marker comp ...

Ways to incorporate external JavaScript files into a React component

I have been attempting to incorporate external javascript files into my react component. When I included them in a basic html file using script tags, everything worked smoothly. However, I am unsure of how to achieve this within a react component. < ...

"Two vibrant hues in a showdown for dominance over a single pixel on the screen in

When using this Three.js application (), the issue arises where the black wireframe competes with the yellow solid, causing pixel flickering on the screen. Is there a way to prevent this from happening? It's worth noting that the flickering effect is ...