当要移出矩形时,将矩形移动到封闭矩形的边界上的最简单方法

本文关键字:边界 方法 最简单 移动 移出 | 更新日期: 2023-09-27 18:10:08

我有一个矩形a在一个封闭的矩形B内,封闭的矩形B是允许矩形a移动的区域。当试图将矩形A移动到封闭矩形B的边界之外时,它应该卡在封闭矩形B的边界或角落上,并且不会再移动。在移动时,我手头有以下参数:封闭矩形B的属性,移动前矩形A的属性,移动后矩形A的潜在顶左位置。请注意,移动不一定是逐像素的,在任何方向上都可以是(例如)20像素。请告诉我如何才能有效地做到这一点,而不是过于复杂?

PS:这些只是在WPF的画布上绘制的几何图形,所以也允许使用变换,但我只在这个特定的位上有矩形变量,而不是矩形。

当要移出矩形时,将矩形移动到封闭矩形的边界上的最简单方法

最后我创建了A和B的封闭矩形,然后在这个问题中应用了解决方案,如下所示:

    private static Point CorrectForAllowedArea(Point previousLocation, Point newLocation, Rect allowedArea, Rect newBox)
    {
        // get area that encloses both rectangles
        Rect enclosingRect = Rect.Union(allowedArea, newBox);
        // get corners of outer rectangle, index matters for getting opposite corner
        var outsideCorners = new[] { enclosingRect.TopLeft, enclosingRect.TopRight, enclosingRect.BottomRight, enclosingRect.BottomLeft }.ToList();
        // get corners of inner rectangle
        var insideCorners = new[] { allowedArea.TopLeft, allowedArea.TopRight, allowedArea.BottomRight, allowedArea.BottomLeft }.ToList();
        // get the first found corner that both rectangles share
        Point sharedCorner = outsideCorners.First((corner) => insideCorners.Contains(corner));
        // find the index of the opposite corner
        int oppositeCornerIndex = (outsideCorners.IndexOf(sharedCorner) + 2) % 4;
        // calculate the displacement of the inside and outside opposite corner, this is the displacement outside the allowed area
        Vector rectDisplacement = outsideCorners[oppositeCornerIndex] - insideCorners[oppositeCornerIndex];
        // subtract that displacement from the total displacement that moved the shape outside the allowed area to get the displacement inside the allowed area
        Vector allowedDisplacement = (newLocation - previousLocation) - rectDisplacement;
        // use that displacement on the display location of the shape
        return previousLocation + allowedDisplacement;
        // move or resize the shape inside the allowed area, right upto the border, using the new returned location
    }