smirea / Multi-Pong

A dynamic multiplayer pong with (potential) unlimited number of players
GNU General Public License v2.0
0 stars 0 forks source link

Fix Intersection Sorting #1

Open smirea opened 11 years ago

smirea commented 11 years ago

The way reflection is currently implemented is by taking every element in the scene and trying to see if the Ray and that Sprite intersect. All intersections are stored in array which is then sorted and the closes one is chosen and all others are discarded.

This works most of the times quite well, but it is still broken in some cases. Most notably now with Polygons.

Steps to reproduce:

// min 600 x 600 canvas
stage.
    add(new Rectangle({x:0, y:0, w:600})).
    add(new Rectangle({x:0, y:600, w:600, angle:Math.PI * 3/2})).
    add(new Rectangle({x:600, y:0, w:600, angle:Math.PI * 1/2})).
    add(new Rectangle({x:600, y:600, w:600, angle:Math.PI * 2/2})).
    grid(50).
    add(new Polygon({x:300, y:300, radius:150, edges:6, style:{fillStyle:'cyan', lineWidth:10}})).
    add('ray', new Ray({x:300, y:250, angle:Math.PI * 3/8, style:{strokeStyle:'crimson'} })).
    draw();

screen shot 2013-08-28 at 28 08 13 1 16 24 am

smirea commented 11 years ago

I implemented a different intersection sorting which now works for Circles as well. But somehow this is still not fixed. It's probably because when looking at the reflections I check if the intersection and the reflection origin do not overlap which probably screws up in this image

Still open, still an issue

dmitrc commented 11 years ago

Issue still persists, even with Circles. Problem seems to be, that the intersection dot is found is closer to the outside, rather than inside of the walls, which ultimately makes it penetrate the shape.

Still unsure yet how, where and why does this work in a code, but looking for it :)

screen shot 2013-08-30 at 6 47 26 pm

smirea commented 11 years ago

I think it has to do more with how the reflection angle is calculated than the points because the intersection points are correct but the reflection angle is outside instead of inside. Most likely has to do with the fact that circles need a tangent to the intersection surface to reflect off of and that is not taken into account in the code

Current the angle is calculated without any regard for surface tangets as I initially wrote this logic with rectangles in mind and there the tangent is the surface itself, but for circles it is a different issue. If you look in the code you'll see that the reflection angle is currently is only dependant on the angle on incidence of the rotation of the element - which in the circle case is wrong

// classes.js:603
var refl_angle = 2 * data.line.angle - ray.angle;

One way to go about it is that every .intersect() method can also optionally return a tangent_angle attribute and then the refl_angle would be using that if it exists - if not default to the object angle and hope for the best ^.^