xzereus Posted May 31, 2014 Share Posted May 31, 2014 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 nullI 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? Link to comment Share on other sites More sharing options...
CtlAltDel Posted May 31, 2014 Share Posted May 31, 2014 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? Link to comment Share on other sites More sharing options...
CtlAltDel Posted May 31, 2014 Share Posted May 31, 2014 Just tested the code and the problem is the intersection is at:Phaser.Point {x: 567.9753424657532, y: 319.99999999999994, copyFrom: 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. Link to comment Share on other sites More sharing options...
xzereus Posted May 31, 2014 Author Share Posted May 31, 2014 Just tested the code and the problem is the intersection is at:Phaser.Point {x: 567.9753424657532, y: 319.99999999999994, copyFrom: 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. Link to comment Share on other sites More sharing options...
xzereus Posted May 31, 2014 Author Share Posted May 31, 2014 Just tested the code and the problem is the intersection is at:Phaser.Point {x: 567.9753424657532, y: 319.99999999999994, copyFrom: 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; Link to comment Share on other sites More sharing options...
Recommended Posts