intersect rect

utility

Log in to post a comment.

Canvas.setpenopacity(-1.0);

const t = new Turtle();

function draw_page(rx, ry, ax, ay, w, h) {
    const x1 = rx, y1 = ry;
    const x2 = x1 + ax * w, y2 = y1 + ay * w;
    const x3 = x2 - ay * h, y3 = y2 + ax * h;
    const x4 = x1 - ay * h, y4 = y1 + ax * h;
    
    t.jump(x1, y1);
    t.goto(x2, y2);
    t.goto(x3, y3);
    t.goto(x4, y4);
    t.goto(x1, y1);
}

function clip_local(x1, y1, x2, y2, rx, ry, w, h) {
    let s_c = [];

    let iy1_t = (rx - x1) / (x2 - x1);
    let iy1 = y1 + (y2 - y1) * iy1_t;
    let iy1_in = (iy1 >= ry) && (iy1 <= ry + h) && (iy1_t >= 0) && (iy1_t <= 1);
    
    let iy2_t = (rx + w - x1) / (x2 - x1);
    let iy2 = y1 + (y2 - y1) * iy2_t;
    let iy2_in = (iy2 >= ry) && (iy2 <= ry + h) && (iy2_t >= 0) && (iy2_t <= 1);
    
    let ix1_t = (ry + h - y1) / (y2 - y1);
    let ix1 = x1 + (x2 - x1) * ix1_t;
    let ix1_in = (ix1 >= rx) && (ix1 <= rx + w) && (ix1_t >= 0) && (ix1_t <= 1);
    
    let ix2_t = (ry - y1) / (y2 - y1)
    let ix2 = x1 + (x2 - x1) * ix2_t;
    let ix2_in = (ix2 >= rx) && (ix2 <= rx + w) && (ix2_t >= 0) && (ix2_t <= 1);
    
    let p1_in = (x1 >= rx) && (x1 <= rx + w) && (y1 >= ry) && (y1 <= ry + h);
    
    let p2_in = (x2 >= rx) && (x2 <= rx + w) && (y2 >= ry) && (y2 <= ry + h);
    
    if (p1_in && p2_in) {
        // return nothing
    }
    else if (!iy1_in && !iy2_in && !ix1_in && !ix2_in) {
        s_c.push([x1, y1, x2, y2]);
    } 
    else if (p1_in && !p2_in) {
        if (iy1_in) {
            s_c.push([x2, y2, rx, iy1]);
        }

        if (iy2_in) {
            s_c.push([x2, y2, rx + w, iy2]);
        }
        
        if (ix1_in) {
            s_c.push([x2, y2, ix1, ry + h]);
        }
        
        if (ix2_in) {
            s_c.push([x2, y2, ix2, ry]);
        }
    }
    else if (!p1_in && p2_in) {
        if (iy1_in) {
            s_c.push([x1, y1, rx, iy1]);
        }

        if (iy2_in) {
            s_c.push([x1, y1, rx + w, iy2]);
        }
        
        if (ix1_in) {
            s_c.push([x1, y1, ix1, ry + h]);
        }
        
        if (ix2_in) {
            s_c.push([x1, y1, ix2, ry]);
        } 
    }
    else {
        if (iy1_in) {
            if (x1 <= rx) {
                s_c.push([x1, y1, rx, iy1]);
            }
            else {
                s_c.push([x2, y2, rx, iy1]);
            }
        }    
        
        if (iy2_in) {
            if (x2 > rx + w) {
                s_c.push([rx + w, iy2, x2, y2]);
            }
            else {
                s_c.push([rx + w, iy2, x1, y1]);
            }
        }
        
        if (ix1_in) {
            if (y2 > ry + h) {
                s_c.push([ix1, ry + h, x2, y2]);
            }
            else {
                s_c.push([ix1, ry + h, x1, y1]);
            }
        }
        
        if (ix2_in) {
            if (y1 < ry) {
                s_c.push([ix2, ry, x1, y1]);
            }
            else {
                s_c.push([ix2, ry, x2, y2]);
            }
        }
    } 
    
    return s_c;
}

function clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h) {
    x1_loc = (x1 - rx) * ax + (y1 - ry) * ay;
    y1_loc = (x1 - rx) * (-ay) + (y1 - ry) * ax;
    x2_loc = (x2 - rx) * ax + (y2 - ry) * ay;
    y2_loc = (x2 - rx) * (-ay) + (y2 - ry) * ax;
    
    sc = clip_local(x1_loc, y1_loc, x2_loc, y2_loc, 0, 0, w, h);
    
    for (let i = 0; i < sc.length; i++) {
        let cx1 = sc[i][0], cy1 = sc[i][1];
        sc[i][0] = cx1 * ax + cy1 * -ay + rx;
        sc[i][1] = cx1 * ay + cy1 * ax + ry;

        let cx2 = sc[i][2], cy2 = sc[i][3];
        sc[i][2] = cx2 * ax + cy2 * -ay + rx;
        sc[i][3] = cx2 * ay + cy2 * ax + ry;
    }
    
    return sc;
}

let rx = -25 + 50 * Math.random(), ry = -25 + 50 * Math.random();
let phi = 2 * Math.PI * Math.random();
let ax = Math.cos(phi), ay = Math.sin(phi);
let w = 20 + 50 * Math.random(), h = 50 + 100 * Math.random();

draw_page(rx, ry, ax, ay, w, h);

// for (let i = 0; i < 100; i++) {
//     let x1 = -100, y1 = 0;
//     let phi = Math.PI * (-0.5 + Math.random());
//     let len = 150;
//     let x2 = x1 + len * Math.cos(phi), y2 = y1 + len * Math.sin(phi);
    
//     s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
    
//     for (let j = 0; j < s_c.length; j++) {
//         t.jump(s_c[j][0], s_c[j][1]);
//         t.goto(s_c[j][2], s_c[j][3]);
//     }
// }

// for (let i = 0; i < 100; i++) {
//     let x1 = 100, y1 = 0;
//     let phi = Math.PI * (0.5 + Math.random());
//     let len = 150;
//     let x2 = x1 + len * Math.cos(phi), y2 = y1 + len * Math.sin(phi);
    
//     s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
    
//     for (let j = 0; j < s_c.length; j++) {
//         t.jump(s_c[j][0], s_c[j][1]);
//         t.goto(s_c[j][2], s_c[j][3]);
//     }
// }

// for (let i = 0; i < 100; i++) {
//     let x1 = 00, y1 = 100;
//     let phi = Math.PI * (-1.0 + Math.random());
//     let len = 170;
//     let x2 = x1 + len * Math.cos(phi), y2 = y1 + len * Math.sin(phi);
    
//     s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
    
//     for (let j = 0; j < s_c.length; j++) {
//         t.jump(s_c[j][0], s_c[j][1]);
//         t.goto(s_c[j][2], s_c[j][3]);
//     }
// }

// for (let i = 0; i < 100; i++) {
//     let x1 = 0, y1 = -100;
//     let phi = -Math.PI * (-1.0 + Math.random());
//     let len = 170;
//     let x2 = x1 + len * Math.cos(phi), y2 = y1 + len * Math.sin(phi);
    
//     s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
    
//     for (let j = 0; j < s_c.length; j++) {
//         t.jump(s_c[j][0], s_c[j][1]);
//         t.goto(s_c[j][2], s_c[j][3]);
//     }
// }

// for (let i = 0; i < 100; i++) {
//     let x1 = 0, y1 = 0;
//     let phi = Math.PI * (2.0 * Math.random());
//     let len = 150;
//     let x2 = x1 + len * Math.cos(phi), y2 = y1 + len * Math.sin(phi);
    
//     //s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
//     s_c = clip(x2, y2, x1, y1, rx, ry, ax, ay, w, h);
    
//     for (let j = 0; j < s_c.length; j++) {
//         t.jump(s_c[j][0], s_c[j][1]);
//         t.goto(s_c[j][2], s_c[j][3]);
//     }
// }

for (let i = 0; i < 100; i++) {
    let x1 = -100 + 200 * Math.random();
    let y1 = -100 + 200 * Math.random();
    let x2 = -100 + 200 * Math.random();
    let y2 = -100 + 200 * Math.random();
    
    s_c = clip(x1, y1, x2, y2, rx, ry, ax, ay, w, h);
    
    for (let j = 0; j < s_c.length; j++) {
        t.jump(s_c[j][0], s_c[j][1]);
        t.goto(s_c[j][2], s_c[j][3]);
    }
}