简体   繁体   English

使用交点找到最小平移向量

[英]Finding the minimum translation vector using intersection points

I'm building an application based on Paper.js . 我正在构建一个基于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. 拖动项目时,使用Path#getIntersections(path)方法对照同一层中的任何其他路径检查其组件( 组成的路径)

  2. If the method returns a non empty array (of CurveLocations, which describe the points of intersection) I know there's a collision. 如果该方法返回一个非空数组(CurveLocations,它们描述的交叉点的)我知道有一个碰撞。 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: 而现在,这是我需要在步骤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). 现在,我可以实现SAT或GJK并使用getIntersections方法来解决它,但是我唯一缺少的就是MTV(如果我没记错的话)。

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) onMouseDown:保存鼠标偏移(项目位置减去鼠标位置)

  2. onMouseDrag: Check for intersections. onMouseDrag:检查交叉点。 If so, translate the dragged object by event.delta.negate() while the check returns true. 如果是这样,则在检查返回true时,通过event.delta.negate()翻译拖动的对象。 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. onMouseUp:与拖动事件相同,除了如果未检测到碰撞,则什么也不做。

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. 但是,如果您将U或O之类的形状围绕另一个较小的形状,则此方法可能不会给出最短的距离。 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 . 因此,我想使用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. Edit2:第二个示例 ,用于检查相交并将形状移到外部。 As you can see intersection alone is not enough to check for if the obstacle gets bigger than the dragged item. 如您所见,仅交叉点不足以检查障碍物是否大于拖动的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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