Search code examples
javascriptprocessinglinep5.js

p5.js How do I let a Line go endless in both directions


I wanna let a line in P5.js go endless/ 100/200 Pixels in both directions and let it cut two points

I know line() but it only goes from one point two the other and stops there


Solution

  • You've to find to points which are out of the canvas (on opposite sides) and on the line which is defined by the 2 points. It is not necessary that the points are exactly at the border of the canvas, they've to be just out of the canvas.
    The largest possible distance on the canvas is the length of the diagonal of the canvas. So if you go form any point on the canvas, in any direction, by a length which is grater than the length of the diagonal, then you're out of the canvas. Find the direction of the line, start at one point and in this direction, by the length of the canvas diagonal. This is the first point end point of the endless line. The 2nd point can be found when you go int he opposite direction.

    To do the necessary calculations I recommend to use p5.Vector.

    Calculate the length of the diagonal, this is the magnitude (mag()) of the vector (windowWidth, windowHeight):

    let dia_len = new p5.Vector(windowWidth, windowHeight).mag();
    

    Find the direction of the line. The direction vector can be found py subtracting (sub()) the 2 points of the line. Set the length of the vector to the length of the canvas diagonal (setMag()):

    let p1 = new p5.Vector(x1, y1);
    let p2 = new p5.Vector(x2, y2);
    let dir_v = p5.Vector.sub(p2, p1).setMag(dia_len);
    

    Calculate the to points on the endless line, by adding (add()) and subtracting (sub()) the direction vector from on of the points:

    let lp1 = p5.Vector.add(p1, dir_v);
    let lp2 = p5.Vector.sub(p2, dir_v);
    

    Finall draw the line:

    line(lp1.x, lp1.y, lp2.x, lp2.y);
    

    A function which draw a endless line:

    function endlessLine(x1, y1, x2, y2) {
    
        p1 = new p5.Vector(x1, y1);
        p2 = new p5.Vector(x2, y2);
    
        let dia_len = new p5.Vector(windowWidth, windowHeight).mag();
        let dir_v = p5.Vector.sub(p2, p1).setMag(dia_len);
        let lp1 = p5.Vector.add(p1, dir_v);
        let lp2 = p5.Vector.sub(p1, dir_v);
    
        line(lp1.x, lp1.y, lp2.x, lp2.y);
    }
    

    See the example:

    var sketch = function( p ) {
    
    p.setup = function() {
        let sketchCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
        sketchCanvas.parent('p5js_canvas')
    }
    
    let points = [];
    let move = []
    
    p.endlessLine = function(x1, y1, x2, y2) {
    
        p1 = new p5.Vector(x1, y1);
        p2 = new p5.Vector(x2, y2);
    
        let dia_len = new p5.Vector(p.windowWidth, p.windowHeight).mag();
        let dir_v = p5.Vector.sub(p2, p1).setMag(dia_len);
        let lp1 = p5.Vector.add(p1, dir_v);
        let lp2 = p5.Vector.sub(p1, dir_v);
    
        p.line(lp1.x, lp1.y, lp2.x, lp2.y);
    }
    
    p.draw = function() {
            
        if (points.length == 0) {
    
            points = [];
            move = [];
            for (let i=0; i < 2; ++i ) {
                points.push( new p5.Vector(p.random(p.windowWidth-20)+10, p.random(p.windowHeight-20)+10));
                move.push( new p5.Vector(p.random(2)-1, p.random(2)-1) );
            }
        }
        else
        {
            for (let i=0; i < 2; ++i ) {
                points[i] = points[i].add(move[i]);
                if (points[i].x < 10 || points[i].x > p.windowWidth-10)
                    move[i].x *= -1; 
                if (points[i].y < 10 || points[i].y > p.windowHeight-10)
                    move[i].y *= -1;    
                move[i].x = Math.max(-1, Math.min(1, move[i].x+p.random(0.2)-0.1))
                move[i].y = Math.max(-1, Math.min(1, move[i].y+p.random(0.2)-0.1))
            }
        }
    
        // draw the scene
    
        p.background(192);
        
        p.stroke(0, 0, 255);
        p.fill(128, 128, 255);
        for (let i=0; i < points.length; ++i ) {
            p.ellipse(points[i].x, points[i].y, 10, 10);
        }
    
        p.stroke(0, 255, 0);
        p.fill(128, 255, 128, 128);
        p.endlessLine(points[0].x, points[0].y, points[1].x, points[1].y)
    }
    
    p.windowResized = function() {
        p.resizeCanvas(p.windowWidth, p.windowHeight);
        points = [];
    }
    
    p.mouseClicked = function() {
        points = [];
    }
    
    p.keyPressed = function() {
        points = []
    }
    
    };
    
    var endless_line = new p5(sketch);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
    <div id="p5js_canvas"></div>

    Demo