问题定义:思维导图是由一个个节点组成,这里的节点视为有区域的矩形,然后希望给定思维导图一个边界,当思维导图被移出边界后能够自动回弹到可是区域内。有几点约束:
- 思维导图可以缩放位移,缩放位移后边界仍然有效;
- 若思维导图放大后,节点之间的空白区域在边界内仍然视为思维导图在边界内;
- 回弹后的至少有一个节点要在可视区域内;
- 边界范围小于可视区范围,边界范围允许适当调节,没有严格限制;
思路
当矩形边界与任意矩形节点相交时,说明当前的图没有超出边界。边界矩形不包含图的时候,可以获取到带最近节点,计算出所需的x,y偏移量,即是图回弹所需要的偏移量。
由于矩形边界一定在可是区域内,所以矩形边界内的节点一定在可是区域内。

特殊情况:

当图放大后,可能在节点间存在空白区域,这时候也需要判定为包含关系。
由上图可是,如果x轴方向和y轴方向都各自存在节点矩形与边界矩形有重合部分的话,那么也是存在包含关系的。

单向重叠的情况下,如果两边都存在节点,那也属于包含关系。所以存在x轴(或y轴)方向包含的时候,需要记录一下节点与边界矩形的位置关系。
节点在边界左边:
rightnode<=left边界
节点在边界右边:
leftnode>=right边界
同理,节点与边界矩形的上下位置关系判断也类似。
矩形的包含关系判定
两个矩形存在重叠部分,则:
P1:∣cxrect1−cxrect2∣≤2(widthrect1+widthrect2)
且,
P2:∣cyrect1−cyrect2∣≤2(heightrect1+heightrect2)
其中cx和cy是两个矩形的中心点,width和height分别是矩形的宽高。P1表达式表示x轴方向两个矩形有重叠,P2表示y轴方向两个矩形有重叠。
当两个矩形在x轴方向有重叠部分,且在y轴方向有重叠部分时,那么这两个矩形就重叠了。
同理,当x轴方向和y轴方向都有与边界矩形重叠的部分,那么可以判定图与边界矩形为包含关系。
判断距离边界最近的节点
当图与矩形边界不存在包含关系时,需要知道距离矩形边界最近的节点。
那么只需要定义一个距离公式,遍历所有节点,找出最小的距离所代表的节点即可。
首先定义距离公式:
其中,left、right、top和bottom分别表示矩形的左边界、右边界、上边界和下边界。可以通过矩形的坐标和宽高获取到。
左右边界:
leftrect=xrect,rightrect=xrect+widthrect
上下边界:
toprect=yrect,bottomrect=yrect+heightrect
获取到偏移量后,就可以计算距离了:
Dnodei=xnodeixnodei+ynodeiynodei
最小距离:
Dmin=Min{Dnode1,Dnode2,Dnode3,...,Dnodei}
得到最近节点所需要的偏移量:
(xnodemin,ynodemin)
缩放位移转换
在实际操作过程中,需要将边界矩形映射到位移缩放后的图像上,我们可以简化为矩形四个角的坐标点映射到位移缩放后的图像上,其中坐标点的映射公式为:
(x′,y′)=f(x,y)=(scalex−offsetX,scaley−offsetY)
其中offsetX和offsetY分别为当前图在x轴方向和y轴方向的偏移量,sacle为当前图的缩放比例。
得到上下左右的边界:
(left边界′,top边界′)=f(x边界,y边界),
(right边界′,bottom边界′)=f(x边界+width边界,y边界+height边界)
最后是利用最近节点与边界的偏移值,将图回弹到边界内:
(offsetX′,offsetY′)=(offsetX+xnodemin,offsetY+ynodemin)