Adam Adam - 3 months ago 25
Javascript Question

calculating the point of intersection of two lines

I have dynamically generated lines that animate and I want to detect when a lines hits another. I'm trying to implement some basic linear algebra to obtain the equation of the lines and then solving for x,y, but the results are erratic. At this point I'm testing only with two lines which means I should be getting one point of intersection, but I get two. I just want to make sure my math is ok and that I should be looking elsewhere for the problem.

function collision(boid1, boid2) {
var x1 = boid1.initialX, y1 = boid1.initialY, x2 = boid1.x, y2 = boid1.y, x3 = boid2.initialX, y3 = boid2.initialY, x4 = boid2.x, y4 = boid2.y;

slope1 = (y1 - y2)/(x1 - x2);
slope2 = (y3 - y4)/(x3- x4);

//console.log("slope1:"+slope1);
//console.log('x2:'+x2+' y2:'+y2);

if(slope1 != slope2){
var b1 = getB(slope1,x1,y1);
var b2 = getB(slope2,x3,y3);

if(slope2 >= 0){
u = slope1 - slope2;
}else{
u = slope1 + slope2;
}

if(b1 >= 0){
z = b2 - b1;
}else{
z = b2 + b1;
}

pointX = z / u;

pointY = (slope1*pointX)+b1;

pointYOther = (slope2*pointX)+b2;

console.log("pointx:"+pointX+" pointy:"+pointY+" othery:"+pointYOther);
//return true;
context.beginPath();
context.arc(pointX, pointY, 2, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#003300';
context.stroke();



}

return false;


}




function getB(slope,x,y){

var y = y, x = x, m = slope;

a = m*x;

if(a>=0){
b = y - a;
}else{

b = y + a;
}

return b;
}


EDIT:

The problem is that I'm getting two different values for the point of intersection. There should only be one, which leads me to believe my calculations are wrong. Yes, x2,y2,x4,y4 are all moving, but they have a set angle and the consistent slopes confirm that.

Answer

You don't need to alternate between adding/subtracting y-intersects when plugging 'found-x' back into one of the equations:

(function () {
    window.linear = {
        slope: function (x1, y1, x2, y2) {
            if (x1 == x2) return false;
            return (y1 - y2) / (x1 - x2);
        },
        yInt: function (x1, y1, x2, y2) {
            if (x1 === x2) return y1 === 0 ? 0 : false;
            if (y1 === y2) return y1;
            return y1 - this.slope(x1, y1, x2, y2) * x1 ;
        },
        getXInt: function (x1, y1, x2, y2) {
            var slope;
            if (y1 === y2) return x1 == 0 ? 0 : false;
            if (x1 === x2) return x1;
            return (-1 * ((slope = this.slope(x1, y1, x2, y2)) * x1 - y1)) / slope;
        },
        getIntersection: function (x11, y11, x12, y12, x21, y21, x22, y22) {
            var slope1, slope2, yint1, yint2, intx, inty;
            if (x11 == x21 && y11 == y21) return [x11, y11];
            if (x12 == x22 && y12 == y22) return [x12, y22];

            slope1 = this.slope(x11, y11, x12, y12);
            slope2 = this.slope(x21, y21, x22, y22);
            if (slope1 === slope2) return false;

            yint1 = this.yInt(x11, y11, x12, y12);
            yint2 = this.yInt(x21, y21, x22, y22);
            if (yint1 === yint2) return yint1 === false ? false : [0, yint1];

            if (slope1 === false) return [y21, slope2 * y21 + yint2];
            if (slope2 === false) return [y11, slope1 * y11 + yint1];
            intx = (slope1 * x11 + yint1 - yint2)/ slope2;
            return [intx, slope1 * intx + yint1];
        }
    }
}());