Extrapolate coordinates to edges of canvas object

I am writing a browser application which attempts to discover points of interest in an image.

Once I have computed these points I draw a line between them.

My application needs to extrapolate these lines to the edges of my canvas.

Does anyone have any experience with linear graph calculation in javascript?

I have knocked up a demonstration

(function(){

    function drawLine(points){
        context.beginPath();
        points.forEach(function(point){
            context.lineTo(point.x, point.y);   
        });
        context.stroke();
    }

    var canvas = document.createElement('canvas');
    canvas.setAttribute('width', 500);
    canvas.setAttribute('height', 300);
    document.body.appendChild(canvas);
    context = canvas.getContext("2d");

    // top
    drawLine([{x: 100, y: 40}, {x: 400, y: 10}]);
    // bottom
    drawLine([{x: 50, y: 220}, {x: 300, y: 290}]);
    // left
    drawLine([{x: 40, y: 20}, {x: 80, y: 260}]);
    // right
    drawLine([{x: 490, y: 60}, {x: 440, y: 290}]);

})();

https://jsfiddle.net/y87a0dec/

Many thanks.

Answers:

Answer

The line segment between p = (p.x, p.y) and q = (q.x, q.y) can be extended to the line y - p.y = a * (x - p.x), where a is the slope (p.y - q.y) / (p.x - q.x). (If p.x = q.x, this is invalid, but this is a special case we can handle separately.)

By solving for y and for x, we get the equivalent formulations: y = a * (x - p.x) + p.y and x = (y - p.y) / a + p.x. Inserting our canvas edges into these equations gives us the points where the extended line intersects the canvas.

With a suitable case analysis, we can determine which two of the four canvas edges the extended line intersects. Here is an implementation for the general case of the line segment between p and q extended into the canvas [x0, x1] × [y0, y1]:

function extend(p, q, x0, x1, y0, y1) {
    var dx = q.x - p.x;
    var dy = q.y - p.y;
    if (dx === 0) return [{x: p.x, y: y0}, {x: p.x, y: y1}];
    var slope = dy / dx;

    var y_at_x0 = slope * (x0 - p.x) + p.y;
    var y_at_x1 = slope * (x1 - p.x) + p.y;
    var x_at_y0 = (y0 - p.y) / slope + p.x;
    var x_at_y1 = (y1 - p.y) / slope + p.x;

    var r, s;
    if (y_at_x0 < y0) r = {x: x_at_y0, y: y0};
    else if (y_at_x0 <= y1) r = {x: x0, y: y_at_x0};
    else r = {x: x_at_y1, y: y1};

    if (y_at_x1 < y0) s = {x: x_at_y0, y: y0};
    else if (y_at_x1 <= y1) s = {x: x1, y: y_at_x1};
    else s = {x: x_at_y1, y: y1};

    return [r, s];
}

In the following jsfiddle, drawExtended passes the result from extend into your drawLine. The top and left segments have been extended into the canvas edges: https://jsfiddle.net/y87a0dec/1/

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.