c# – 确定矩形是否在圆内的最佳算法

我必须绘制具有不同填充颜色的矩形,具体取决于它与同心圆的交点.显示的图片将让您更好地了解该场景,

(仅限代表)

目前我正在通过应用毕达哥拉斯定理来检查每个点的状态

伪代码:

SquareOf Point Distance from center (sqrOfDistance) = square(point X
– Circle center X) + square(point Y- Circle center Y)

将这些值与半径的平方(sqrOfInnerR)进行比较

if  sqrOfDistance == sqrOfInnerR
    Inline
else if sqrOfDistance > sqrOfInnerR
    Out
else 
    In

即使当前的逻辑有效;它需要对每个点(4或8次)执行这些检查,最后一起确定状态.在我的真实应用程序中,将有大约3,000,000个矩形出现在图片中.

private RectState CheckTheRectangleState(Rect rect, double radius, bool firstCall = true)
        {
            double SquareOfRadius = Square(radius);
            var _x = rect.X - ControlCenter.X;
            var _y = rect.Y - ControlCenter.Y;

            var squareOfDistanceToTopLeftPoint = Square(_x) + Square(_y);
            var squareOfDistanceToTopRight = Square(_x + rect.Width) + Square(_y);
            var squareOfDistanceToBottonLeft = Square(_x) + Square(_y + rect.Height);
            var squareOfDistanceToBottonRight = Square(_x + rect.Width) + Square(_y + rect.Height);

            var topLeftStatus = squareOfDistanceToTopLeftPoint == SquareOfRadius ? PointStatus.Inline : (squareOfDistanceToTopLeftPoint > SquareOfRadius ? PointStatus.Out : PointStatus.In);
            var topRightStatus = squareOfDistanceToTopRight == SquareOfRadius ? PointStatus.Inline : (squareOfDistanceToTopRight > SquareOfRadius ? PointStatus.Out : PointStatus.In);
            var bottonLeftStatus = squareOfDistanceToBottonLeft == SquareOfRadius ? PointStatus.Inline : (squareOfDistanceToBottonLeft > SquareOfRadius ? PointStatus.Out : PointStatus.In);
            var bottonRightStatus = squareOfDistanceToBottonRight == SquareOfRadius ? PointStatus.Inline : (squareOfDistanceToBottonRight > SquareOfRadius ? PointStatus.Out : PointStatus.In);

            if ((topLeftStatus == PointStatus.In || topLeftStatus == PointStatus.Inline) &&
                (topRightStatus == PointStatus.In || topRightStatus == PointStatus.Inline) &&
                (bottonLeftStatus == PointStatus.In || bottonLeftStatus == PointStatus.Inline) &&
                (bottonRightStatus == PointStatus.In || bottonRightStatus == PointStatus.Inline))
            {
                return firstCall ? RectState.In : RectState.Partial;
            }
            else
            {
                if (firstCall)
                    CheckTheRectangleState(rect, outCircleRadius, false);
            }
            return RectState.Out;
        }
    }

其中Square()是自定义函数以获得正方形. Square(x){return x * x;}
PointStatus和RectState是枚举以确定点的状态.

最佳答案 如果你正在处理很多矩形,并且如果大多数时候它们中的大多数将会在圆圈之外,那么在早期退出方式中优化检查的一种方法是首先想象一个包围圆圈的方形,从( – r,-r)到(r,r),其中r是圆的半径,圆的中心是(0,0)并检查矩形是否在该正方形内.这应该快得多,并且只有当这个成功时才需要检查与圆圈的碰撞.

编辑:@hvd为早期退出肯定检查添加了一个很好的主意.如果矩形在内部正方形内,它肯定在圆圈内.

根据矩形与圆的大小,您还可以更深一层,并在内部正方形和圆形之间制作矩形.但是你需要检查所查询矩形的点是否都在任何矩形(内部正方形)中,并且所有矩形都不需要在同一个矩形中.

点赞