Prozi / detect-collisions

Points, Lines, Boxes, Polygons (also hollow), Ellipses, Circles. RayCasting, offsets, rotation, scaling, bounding box padding, flags for static and ghost/trigger bodies
https://prozi.github.io/detect-collisions/
MIT License
207 stars 22 forks source link

Line: Rounding error on maxY #47

Closed tmanninger closed 1 year ago

tmanninger commented 1 year ago

I create the following line:

      let line = new Line(
        { x: 600.51305, y: 69.7 },
        { x: 600.51305, y: 229.052 }
      );

After system.update(), the min/max auf the body have the following values:

minX: 600.51305
minY: 69.7
maxX: 600.51305
maxY: 229.05199999999996

Why is maxY rounded to 229.05199999999996?

Now, when i check, if on position { x: 600.51305, y: 229.052 } is a collision, the check returns false.

See example (see console output): https://codesandbox.io/s/proud-snowflake-04p5nh?file=/src/App.tsx:352-459

tmanninger commented 1 year ago

My current dirty lifehack:

Instead auf using system.update():

        for (let body of this._collisionSystem.all()) {
            this._collisionSystem.updateBody(body)
            if (body instanceof Line) {
                if (body.points[0].x < body.points[1].x) {
                    body.minX = body.points[0].x
                    body.maxX = body.points[1].x
                }
                else {
                    body.minX = body.points[1].x
                    body.maxX = body.points[0].x
                }
                if (body.points[0].y < body.points[1].y) {
                    body.minY = body.points[0].y
                    body.maxY = body.points[1].y
                }
                else {
                    body.minY = body.points[1].y
                    body.maxY = body.points[0].y
                }
            }
        }
Prozi commented 1 year ago

the reason @tmanninger is that in javascript 229.052 - 69.7 + 69.7 === 229.05199999999996 :smiling_face_with_tear:

your implementation ignores padding and line position

tmanninger commented 1 year ago

Ok thanks for feedback!

tmanninger commented 1 year ago

@Prozi other question (i know this is not issue related): Is there a way to update a Line object without adding it to the system object?

i will create a new Line object, update the attributes, check if there is a collision with the Line object. After this, the line object is not longer needed. My current way: 1.) Create Line object 2.) Add it to system 3.) call system.update(line) 4.) Check collision with another object. 5.) Delete line from system.

Prozi commented 1 year ago

@Prozi other question (i know this is not issue related): Is there a way to update a Line object without adding it to the system object?

i will create a new Line object, update the attributes, check if there is a collision with the Line object. After this, the line object is not longer needed. My current way: 1.) Create Line object 2.) Add it to system 3.) call system.update(line) 4.) Check collision with another object. 5.) Delete line from system.

you can either

// this is the way to go skip step 3 (adding to system is same as updating body) skip step 5 (just remove line from system, but keep it for reuse if you plan to do this again)

or

you can just try to do 1) const line = new Line({}, {}) 2) system.all().filter((body) => body !== line && this.checkCollision(line, body))

but I dont recommend this unless you have a very small number of bodies as BVH is always faster for idk >100 bodies?

Prozi commented 1 year ago

closing as [wont-fix] (the issue described in https://github.com/Prozi/detect-collisions/issues/47#issuecomment-1377062769 )