开发者

easiest way to move a Rect upto bounds of enclosing Rect when about to move out of it

开发者 https://www.devze.com 2023-04-08 20:18 出处:网络
I have a Rect开发者_如何学C A inside an enclosing Rect B. the enclosing Rect B is the area in which the Rect A is allowed to be moved. when trying to move Rect A beyond the borders of enclosing Rect B

I have a Rect开发者_如何学C A inside an enclosing Rect B. the enclosing Rect B is the area in which the Rect A is allowed to be moved. when trying to move Rect A beyond the borders of enclosing Rect B it should get stuck at a border or corner of enclosing Rect B and move no further. while moving I have the following parameters at hand: properties of enclosing Rect B, properties of Rect A before the move, potential topleft position of Rect A after the move. Note that the move is not necessarily per-pixel, it might just as well be (for example) 20 pixels, in any direction. please tell me how do I go about doing this efficiently but not over-complicated?

PS: these are simply drawn geometries on a canvas in WPF so the use of transforms is also allowed but I only have Rect variables at this particular bit, not RectangleGeometries.


eventually I created an enclosing Rect of A and B, and then applied the solution in this question, like this:

    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
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消