power plant (animation)

up it goes

Log in to post a comment.

const max_y = 70; // min=30, max=90, step=1
const top_h = 25; // min=0, max=20, step=1
const dispersion1 = 1.2; // min=0.1, max=3, step=0.1
const dispersion2 = 6; // min=0.1, max=10, step=0.1
const velocity_y = 0.5; // min=0.1, max=5, step=0.1
const N_circles = 30; // min=10, max=100, step=1
const min_r = 1; // min=0.5, max=10, step=0.1
const max_r = 8; // min=5, max=20, step=0.1
const dt = 0.17; // min=0.01, max=1.0, step=0.01
const hatch_step = 0.2; // min=0.1, max=3.0, step=0.1
const opacity = 0.002; // min=0.001, max=1, step=0.001
const N_frames = 3000; // min=1000, max=10000, step=100

Canvas.setpenopacity(-opacity);

const t = new Turtle();

const min_y = 100
const w = 10

const towers_cx = [-50, 0, 50]

const towers_circles = []

for (let j = 0; j < towers_cx.length; j++) {
    cx = towers_cx[j]
    
    towers_circles[j] = []
    
    for (let i = 0; i < N_circles; i++) {
        towers_circles[j].push({x: cx + w/2 * (-1 + 2 * Math.random()), y: min_y, r: min_r})
    }
}

function add_segment(segments, add_s) {
    let new_segments = []
    
    let min_x = add_s.x1
    let max_x = add_s.x2
    
    for (let s of segments) {
        if ((s.x2 < add_s.x1) || (add_s.x2 < s.x1)) {
            new_segments.push(s)
        }
        else {
            min_x = Math.min(min_x, s.x1)
            max_x = Math.max(max_x, s.x2)
        }
    }
    
    new_segments.push({x1: min_x, x2: max_x})
    
    return new_segments
}

function intersect_circles_y(circles, y) {
    segm_x = []
    
    for (let c of circles) {
        let dy = y - c.y
        
        if ((dy > -c.r) && (dy < c.r)) {
            let dx = Math.sqrt(c.r**2 - dy**2)
            
            segm_x = add_segment(segm_x, {x1: c.x - dx, x2: c.x + dx})
        }
    }
    
    return segm_x
}

function walk(frame) {
    for (let j = 0; j < towers_cx.length; j++) {
        for (let i = 0; i < N_circles; i++) {
            if (towers_circles[j][i].y <= -max_y) {
                let phi = 2 * Math.PI * Math.random()
                let psi = Math.PI * (-0.5 + Math.random())
                
                let dx = dispersion2 * Math.cos(psi) * Math.cos(phi)
                let dy = dispersion2 * Math.sin(psi)
                
                towers_circles[j][i].x += dx * dt
                
                towers_circles[j][i].y = Math.max(towers_circles[j][i].y, -(max_y + top_h))
                towers_circles[j][i].y += dy * dt
                
                towers_circles[j][i].r = max_r
            }
            else {
                let phi = 2 * Math.PI * Math.random()
                let dx = dispersion1 * Math.cos(phi)
                
                towers_circles[j][i].x += dx * dt
                
                towers_circles[j][i].y -= velocity_y * dt
                
                towers_circles[j][i].r = min_r + (max_r - min_r) * (min_y - towers_circles[j][i].y) / (min_y + max_y)
            }
        }

        shift = 0;//hatch_step / (towers_cx.length - 1) * j

        for (let y = -100 + shift; y <= 100; y += hatch_step) {
            segm_x = intersect_circles_y(towers_circles[j], y)
            
            for (let s of segm_x) {
                t.jump(s.x1, y)
                t.goto(s.x2, y)
            }
        }
    }

    // for (let c of circles) {
    //     t.jump(c.x, c.y - c.r)
    //     t.circle(c.r)
    // }
    
    return (frame < N_frames)
}