clouds hatching

y intersect union of circles

Log in to post a comment.

Canvas.setpenopacity(-1);

const t = new Turtle();

function rects_intersect(r1, r2) {
    return !((r1.x2 < r2.x1) || (r2.x2 < r1.x1) || (r1.y2 < r2.y1) || (r2.y2 < r1.y1))
}

const rects = []
for (let i = 0; i < 10; i++) {
    while (true) {
        let cx = -100 + 200 * Math.random()
        let cy = -100 + 200 * Math.random()
        
        let crx = 20 + 20 * Math.random()
        let cry = crx * (0.3 + 0.4 * Math.random())
        
        rects[i] = {x1: cx - crx, x2: cx + crx, y1: cy - cry, y2: cy + cry}
        
        if (i == 0) {
            break
        }
        else
        {
            ok = true
            
            for (let j = 0; j < i; j++) {
                if (rects_intersect(rects[i], rects[j])) {
                    ok = false
                    break
                }
            }
            
            if (ok) {
                break
            }
        }
    }
}

const circles = []

for (let r of rects) {
    let cr = Math.min(r.x2 - r.x1, r.y2 - r.y1) / 3
    let n = Math.floor(0.6 * 3 * Math.floor(Math.max(r.x2 - r.x1, r.y2 - r.y1) / cr))
    
    for (let i = 0; i < n; i++) {
        circles.push({x: r.x1 + cr + (r.x2 - r.x1 - 2 * cr) * Math.random(),
                      y: r.y1 + cr + (r.y2 - r.y1 - 2 * cr) * Math.random(),
                      r: cr})
    }
}

// for (let r of rects) {
//     t.jump(r.x1, r.y1)
//     t.goto(r.x2, r.y1)
//     t.goto(r.x2, r.y2)
//     t.goto(r.x1, r.y2)
//     t.goto(r.x1, r.y1)
// }

// for (let c of circles) {
//     t.jump(c.x, c.y - c.r)
//     t.circle(c.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
}

for (let y = -100; y <= 100; y += 2) {
    segm_x = intersect_circles_y(circles, y)
    
    for (let s of segm_x) {
        t.jump(s.x1, y)
        t.goto(s.x2, y)
    }
}