procedural road generation Issue

48 views Asked by At

So im trying to create a procedural road generator (I cant find code online I can look at to be inspired by), and I've managed to get vectors to generate the start of the road (at the red dot, as origin)and the start of its lengthening using new segments created where the end of the starting segments end using recursion. but for some reason I cant comprehend why each new segment is longer and longer despite min max variables

I still need to implement collision detection, rules to deal with that and branching.

here is an example of what it looks like

longer and longer new segments

ive tried a depth parameter to control recursion and reduces the length of segments as the depth increases. but its still happening.

// This function tries to extend a road segment based on certain conditions
function extendRoadSegment(segment, svgElement, depth = 0) {
    var minLength = 2; // Minimum length for a new road segment
    var depthLengthReduction = 0.5; // Reduction factor per depth level
    var maxLength = 5 - (depth * depthLengthReduction); // Reduce max length as depth increases
    maxLength = Math.max(minLength, maxLength); // Ensure maxLength does not go below minLength
    var maxAngleVariance = Math.PI / 8; // Max variance in angle for new road direction
    var maxDepth = 5; // Maximum recursion depth

    // Stop the recursion if the maximum depth is exceeded
    if (depth > maxDepth) {
        return;
    }

    // Determine whether to stop extending the current segment
    var shouldStop = Math.random() < (0.01 + depth * 0.01); // Increasing chance to stop with depth

    if (shouldStop) {
        return; // Stop extending this segment
    }

    // Determine whether to branch the current segment
    var shouldBranch = Math.random() < (0.3 - depth * 0.05); // Decreasing chance to branch with depth

    // Rotate the direction of the new segment within the allowed variance
    var newDirection = segment.direction.clone();
    newDirection.rotate(getRandomArbitrary(-maxAngleVariance, maxAngleVariance));


    // Determine the length of the new segment, ensuring it's not less than the minimum
    var newLength = getRandomInt(minLength, maxLength);
    console.log(`Depth: ${depth}, New Segment Length: ${newLength}`);

    // Create the new segment and draw it on the SVG
    var newSegment = new RoadSegment(segment.end, newDirection, newLength);
    var drawableSegment = newSegment.toDrawable();
    svgElement.appendChild(drawableSegment);
    console.log(`New Segment Start: (${newSegment.start.x}, ${newSegment.start.y})`);
    console.log(`New Segment End: (${newSegment.end.x}, ${newSegment.end.y})`);

    // Recursively extend from the new segment
    if (shouldBranch) {
        extendRoadSegment(newSegment, svgElement, depth + 1);
    }
    console.log(`Should Stop: ${shouldStop}, Should Branch: ${shouldBranch}`);
}

I suspect the issue could be here? are the newLength generated seems consistent:

    class Vector2 {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    clone() {
        return new Vector2(this.x, this.y);
    }

    add(vector) {
        this.x += vector.x;
        this.y += vector.y;
    }

    rotate(angle) {
        const cos = Math.cos(angle);
        const sin = Math.sin(angle);
        const x = this.x * cos - this.y * sin;
        const y = this.x * sin + this.y * cos;
        this.x = x;
        this.y = y;
    }
    

    multiplyScalar(scalar) {
        this.x *= scalar;
        this.y *= scalar;
        return this;
    }

    // Additional vector operations as needed...
}


[1]: https://i.stack.imgur.com/t0v8y.png
0

There are 0 answers