矩形。包含边界点

问题描述 投票:0回答:1

所谓的

Rect.Contains(Point)
方法有点间歇性问题。准确地说,这种情况只发生过一次,从那以后我就无法重现它了。 有一段代码可以找到一组点的上限,使得组中的第一个点和上边界点位于一定大小的矩形内。

List<Point> points = ...; // a list of points order by X
double groupSize = 10000.0;
while (points.Any())
{
    double left = points[0].X;
    Rect searchBound = new Rect(left, points[0].Y - groupSize, groupSize, 2.0 * groupSize);
    double top = points
        .Where(o => searchBound.Contains(o))
        .Min(o => o.Y);
        
    ...
}

问题是

Min()
抛出 InvalidOperationException:序列不包含元素。但
searchBound
至少应包含序列中恰好位于左边界上的第一个点。我是不是错过了什么?

我已经使用随机点生成器运行了一系列测试,但从未能够重现该异常。

Rect.Contains(Point)
文档也没有说明任何有关边界点的信息。

c# .net-4.8
1个回答
0
投票

方法

        /// <summary>
        /// ContainsInternal - Performs just the "point inside" logic
        /// </summary>
        /// <returns>
        /// bool - true if the point is inside the rect
        /// </returns>
        /// <param name="x"> The x-coord of the point to test </param>
        /// <param name="y"> The y-coord of the point to test </param>
        private bool ContainsInternal(double x, double y)
        {
            // We include points on the edge as "contained".
            // We do "x - _width <= _x" instead of "x <= _x + _width"
            // so that this check works when _width is PositiveInfinity
            // and _x is NegativeInfinity.
            return ((x >= _x) && (x - _width <= _x) &&
                    (y >= _y) && (y - _height <= _y));
        }

正在从

Contains
拨打电话:

        /// <summary>
        /// Contains - Returns true if the Point represented by x,y is within the rectangle inclusive of the edges.
        /// Returns false otherwise.
        /// </summary>
        /// <param name="x"> X coordinate of the point which is being tested </param>
        /// <param name="y"> Y coordinate of the point which is being tested </param>
        /// <returns>
        /// Returns true if the Point represented by x,y is within the rectangle.
        /// Returns false otherwise.
        /// </returns>
        public bool Contains(double x, double y)
        {
            if (IsEmpty)
            {
                return false;
            }
 
            return ContainsInternal(x,y);
        }

我们可以看到它收到一个

double
表示
x
和一个
y
,它确实进行了我们在
ContainsInternal
Contains
中所期望的比较,您调用的方法只要调用
ContainsInternal
因为
IsEmpty
是假的。
IsEmpty

        /// <summary>
        /// IsEmpty - this returns true if this rect is the Empty rectangle.
        /// Note: If width or height are 0 this Rectangle still contains a 0 or 1 dimensional set
        /// of points, so this method should not be used to check for 0 area.
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                // The funny width and height tests are to handle NaNs
                Debug.Assert((!(_width < 0) && !(_height < 0)) || (this == Empty));
 
                return _width < 0;
            }
        }

我们看到正在检查

_width
的大小是否为正,但未检查
_height
的大小。

所以,您的问题的可能原因似乎是:

  • 高度可能为负值
  • _x
    _y
    可能有一些奇怪的值
  • 也许你期望一个点位于矩形内,但它实际上并不在内部(这可能会发生)

因此,您需要确保使用各种值测试您的矩形,其中:

  • 肯定指向矩形内部
  • 点在边缘,但不在矩形的角上
  • 指向矩形的角点(所有左上角、右上角、左下角、右下角)
  • 有趣的值,例如 NaN

如果所有测试都通过了,那么完全可以认为这不是问题,除非它在某个时候再次发生。

© www.soinside.com 2019 - 2024. All rights reserved.