在 2D 空间中排列对象的标签而不重叠
我需要将文本标签附加到在屏幕上随机分布并不断移动的对象。
标签的默认和理想位置是在它所引用的对象的右侧。 我需要一种方法来动态地重新排列(或可能合并)标签,以便它们永远不会相互重叠或与其他对象重叠。
它们仍应尽可能靠近物体,并且在物体本身平稳移动的情况下,不应表现出任何突然的急速运动。
我不知道该怎么做,有类似的算法吗?
I need to attach text labels to objects that are spread randomly across the screen and keep moving.
The default and ideal position for a label is on the right side of the object it refers to. I need a way to dynamically rearrange (or possibly merge) the labels so that they never overlap each other or other objects.
They should still be as close to the objects as possible and should not, provided that the objects themselves move smoothly, show any suddent jerky movement.
I have no idea how to do it, is there an algorithm for something like this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议使用物理学。 用弹簧将标签贴在物体上,并对每个标签施加排斥力,这样它们就可以避免靠近其他物体(及其标签),但不包括它们所描述的物体。
I would suggest using physics. Attach the label to the object with a spring and apply a repelling force to every label so they avoid getting close to other objects (and their labels), excluding the one they describe.
放置标签:
您可以找出闭合物体的最紧密的正方形,然后从正方形的右侧向物体垂下一条垂线。 将标签放置在该交叉点处。
检测碰撞:
存储标签的坐标,在显示最终缓冲区之前,您可以使用坐标检测标签的碰撞。
避免突然的动作:
这是困难的部分,因为如果仅在检测到碰撞时才更改标签的位置,那么就会出现抖动。 简单的方法是在检测到碰撞时以及只要碰撞存在就将它们合并。 更困难的方法是移动标签。 为了使这一过程顺利进行,您必须事先检测可能出现在前面几帧的任何碰撞,并开始在某些轨迹上移动标签以避免任何碰撞。
Putting the label:
You can figure out the tightest square which closes the objects and then drop a perpendicular from the right side of the square onto the object. Place the label at this point of intersection.
Detecting collision:
Store the coordinates of the label and before you display the final buffer you can detect the collision of the labels using the coordinates.
Avoid sudden movements:
This is the hard part because if you change the location of the labels only when collision is detected then there is going to be a jerk. The simple approach is to merge them when the collision is detected and for as long as a collision is there. The harder approach would be to move the labels. To make this smooth you will have to detect beforehand any collision that may appear some frames ahead and start moving your labels on some trajectory that would avoid any collision.
我使用相当强力的方法解决了这个问题
,并在一个循环中多次执行此操作,因为对象在吞噬其他对象时会增长,因此必须再次进行碰撞检查(新的重叠可能会在循环中出现)。 不过,根据我正在处理的对象数量,永远不要超过 3 个周期。
should_swallow() 函数根据大小、位置以及前一帧中发生的情况来确定是吞掉物体更好还是被它吞掉,以防止闪烁。
I solved this using pretty much brute force
and do this in a cycle several times because objects grow when they swallow other objects, so the collision check has to be done again (new overlaps may appear mid-cycle). Never hit more than 3 cycles though, with the number of objects I'm working with.
The should_swallow() function determines if it's better to swallow an objects or get swallowed by it, based on size, position and what happened in previous frames to prevent flicker.