简体   繁体   中英

Finding the minimum translation vector using intersection points

I'm building an application based on Paper.js .
I have a list of items, each composed from a top level group and a bunch of paths as children.
I need to implement collision detection, which currently works like so:

  1. When an item is dragged, its components (the paths it's comprised of) are checked against any other path in the same layer using the Path#getIntersections(path) method.

  2. If the method returns a non empty array (of CurveLocations, which describe the points of intersection) I know there's a collision. I stop dragging and combine the items.

  3. If the returned array is empty, there's no collision to handle so no need to interrupt the drag. I translate (move) the dragged item by the distance it was dragged.

And now, here's what I need to do in step 2:

Upon detecting a collision, I need to move the item to the nearest "legal" position (the closest to the current mouse position without overlapping any other shape/border).

Now I can go about implementing SAT or GJK and solving it without the getIntersections method, but the only thing I'm lacking here is the MTV (if I'm not mistaken).

Can someone please confirm if this is either possible or not, and if it is, then how?


Update

After some fiddling with the various mouse events, I've come to a current (imperfect) solution:

  1. onMouseDown: Save the mouse offset (item position minus mouse position)

  2. onMouseDrag: Check for intersections. If so, translate the dragged object by event.delta.negate() while the check returns true. When done, update the offset.
    If no intersection is detected, just move the dragged item to the mouse position minus offset.

  3. onMouseUp: The same as in the drag event, except if no collision is detected then do nothing.

This is more or less working, except it's jittery and it doesn't deal with containment.
Will update with an example as time permits.

If you only have two shapes and they are all quite close to circles and boxes and have similar sizes you could get the center of the bounding box of the shapes and use those center points as a direction vector. Then you move it incrementally away until there is no intersection anymore. But if you have shapes like a U or O that surround another smaller shape it is likely that this method will not give the shortest distance. The same if the moving away will hit other objects.

So I think what you really need is a numerical solution that moves the shape away from its center point in a circular fashion with growing diameter until there wont be any intersections anymore.

Another problem could be when your shape is enclosed in another shape and you will not even have any intersections. So I guess it would be better to use hittest .

Edit: Here is a very easy not very well optimized example of what I tried to explain with the middle points. Reload it if you do not see any overlays. For the circular way the checking just gets more complicated because you would move the shape not only away but also in all other kind of directions.

Edit2: Second example that checks for intersection and moves the shape outside. As you can see intersection alone is not enough to check for if the obstacle gets bigger than the dragged item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM