# Phaser.Line.intersects does not work for floats

Go to solution Solved by CtlAltDel,

## Recommended Posts

Phaser.Line.intersects does not work for floats. Take these two lines for example:

`var line1 = new Phaser.Line(507.39999999999986, 271.60000000000014, 888.3738480697393, 576);var line2 = new Phaser.Line(384, 320, 608, 320);var intersection = Phaser.Line.intersects(line1, line2); // This is null`

I did not delve into the Phaser code, but it's pretty apparent the issue has to do with floats. I pulled the intersection function from this post and did some modification to it to work as I expected with floats:

`function linesIntersect (line1, line2) {        var x1 = line1.start.x, y1 = line1.start.y, x2 = line1.end.x, y2 = line1.end.y;        var x3 = line2.start.x, y3 = line2.start.y, x4 = line2.end.x, y4 = line2.end.y;        var realx=((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4));        var realy=((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4));        // These next lines where we round are key. If we don't do this, this function acts         // the same as Phaser.Line.intersects        x1 = Math.round(x1), y1 = Math.round(y1), x2 = Math.round(x2), y2 = Math.round(y2),         x3 = Math.round(x3), y3 = Math.round(y3), x4 = Math.round(x4), y4 = Math.round(y4);        var x = Math.round(realx);        var y = Math.round(realy);        if (isNaN(x)||isNaN(y)) {            return;        } else {            if (x1>=x2) {                if (!(x2<=x&&x<=x1)) {return;}            } else {                if (!(x1<=x&&x<=x2)) {return;}            }            if (y1>=y2) {                if (!(y2<=y&&y<=y1)) {return;}            } else {                if (!(y1<=y&&y<=y2)) {return;}            }            if (x3>=x4) {                if (!(x4<=x&&x<=x3)) {return;}            } else {                if (!(x3<=x&&x<=x4)) {return;}            }            if (y3>=y4) {                if (!(y4<=y&&y<=y3)) {return;}            } else {                if (!(y3<=y&&y<=y4)) {return;}            }        }        return {x: realx, y: realy};        }`

Of course, this has the chance of returning an intersection point where two lines don't actually intersect but are really close to intersecting, but I think this is preferable to not acknowledging an intersection when there actually is one.

I can make the modification myself and submit the pull request, but I wanted to get thoughts from others on whether or not this change makes sense. So, thoughts?

##### Share on other sites

I recently fixed the line intersection code for phaser. It should work fine with floats, and shouldn't need rounding or anything. Will look into it. Just to make sure, you are using phaser 2.0.5?

##### Share on other sites
• Solution

Just tested the code and the problem is the intersection is at:

Phaser.Point {x567.9753424657532y319.99999999999994copyFromfunctioninvertfunctionsetTofunction}

Which is ofcourse real close to the 320. This has to do with floating point accuracy.

I added a rounding to 3 decimals in the Phaser.Line.intersectsPoints function:
`    /*    Round to 3 decimals here, due to javascript floating point is 'broken'    http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript    See workaround explanation there in accepted answer there..    */    result.x = Math.round( ((((b1 * c2) - (b2 * c1)) / denom)+0.00001)*1000 ) / 1000;    result.y = Math.round( ((((a2 * c1) - (a1 * c2)) / denom)+0.00001)*1000 ) / 1000;`

That seems to fix the issues properly. 3 decimal accuracy should be plenty.

Will make a pull request shortly.

##### Share on other sites

Just tested the code and the problem is the intersection is at:

Phaser.Point {x567.9753424657532y319.99999999999994copyFrom: function, invert: function, setTo: function…}

Which is ofcourse real close to the 320. This has to do with floating point accuracy.

I added a rounding to 3 decimals in the Phaser.Line.intersectsPoints function:
`    /*    Round to 3 decimals here, due to javascript floating point is 'broken'    http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript    See workaround explanation there in accepted answer there..    */    result.x = Math.round( ((((b1 * c2) - (b2 * c1)) / denom)+0.00001)*1000 ) / 1000;    result.y = Math.round( ((((a2 * c1) - (a1 * c2)) / denom)+0.00001)*1000 ) / 1000;`

That seems to fix the issues properly. 3 decimal accuracy should be plenty.

Will make a pull request shortly.

CtlAltDel,

This is what I was referring to. Obviously the actual intersection is at 320, since it's impossible for those two lines to intersect at anything other than y=320 (since one of the lines is essentially y=320). Rounding to 3 decimals should definitely resolve the issues from using floats and horizontal/vertical lines. Thanks.

##### Share on other sites

Just tested the code and the problem is the intersection is at:

Phaser.Point {x567.9753424657532y319.99999999999994copyFrom: function, invert: function, setTo: function…}

Which is ofcourse real close to the 320. This has to do with floating point accuracy.

I added a rounding to 3 decimals in the Phaser.Line.intersectsPoints function:
`    /*    Round to 3 decimals here, due to javascript floating point is 'broken'    http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript    See workaround explanation there in accepted answer there..    */    result.x = Math.round( ((((b1 * c2) - (b2 * c1)) / denom)+0.00001)*1000 ) / 1000;    result.y = Math.round( ((((a2 * c1) - (a1 * c2)) / denom)+0.00001)*1000 ) / 1000;`

That seems to fix the issues properly. 3 decimal accuracy should be plenty.

Will make a pull request shortly.

I made this change in my copy of the code, and I noticed some false intersections started popping up. I changed it to round to the fourth decimal place and I saw far fewer false collisions (almost unnoticeable), so I'd suggest trying that or perhaps even a little bit better precision.

`result.x = Math.round( ((((b1 * c2) - (b2 * c1)) / denom)+0.000001)*10000 ) / 10000;result.y = Math.round( ((((a2 * c1) - (a1 * c2)) / denom)+0.000001)*10000 ) / 10000;`

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.