Не найдено точки соответствия между 2 коллекциями System.Windows.Очки

#c# #wpf #linq #double

#c# #wpf #linq #двойной

Вопрос:

У меня есть функция, в которой я пытаюсь найти точку соответствия между 2 коллекциями по 4 точки в каждой, но иногда функция сообщает, что коллекции не имеют общей точки, хотя в отладчике я вижу, что они есть. неужели отладчик не показывает мне полную точность точек, поэтому я не вижу разницы? или здесь происходит что-то еще? виноват код:

 public static Point CorrectForAllowedDrawArea(Point previousDisplayLocation, Point newDisplayLocation, Rect displayLimitedArea, Rect newBoundingBox)
{
    // get area that encloses both rectangles
    Rect enclosingRect = Rect.Union(displayLimitedArea, newBoundingBox);
    // 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[] { displayLimitedArea.TopLeft, displayLimitedArea.TopRight, displayLimitedArea.BottomRight, displayLimitedArea.BottomLeft }.ToList();
    // get the first found corner that both rectangles share
    Point sharedCorner = outsideCorners.FirstOrDefault((corner) => insideCorners.Contains(corner));
    // find the index of the opposite corner
    int oppositeCornerIndex = (outsideCorners.IndexOf(sharedCorner)   2) % 4;
  

в последней строке для ‘sharedCorner’ иногда устанавливается значение по умолчанию (точка), хотя обе коллекции точек, по-видимому, разделяют 1 точку.

РЕДАКТИРОВАТЬ: я должен упомянуть, что если я помещу отладчик обратно в начало функции и перезапущу его, он все равно не найдет точку соответствия. Я должен также упомянуть, что эта функция использует класс Point системы.Пространство имен Windows, а не системы.Пространство имен рисования! Спасибо, что указали мне на это в комментариях.

Комментарии:

1. Где-то вы полагаетесь на Equals() для double или float здесь. И это приведет к сбою при наличии ошибок округления.

2. @HenkHolterman: Я тоже это подозревал, но, похоже, используются только целые Point числа, а не PointF .

3. @Leppie: правильно, если это из System. Рисование. Из вопроса не совсем ясно. Обратите внимание на «полную точность точек»

4. спасибо, что указали на это, я соответствующим образом отредактировал вопрос

Ответ №1:

Нам действительно нужно посмотреть, что такое определение insideCorners.Contains(corner) , но я подозреваю, что ваша проблема связана с присущими неточностями с числами с плавающей запятой.

Вы не можете сравнить два значения с плавающей запятой, подобные этому:

 if (a == b)
{
    // Values are equal
}
  

особенно, если либо a или b являются вычисляемыми значениями.

Вам нужно будет реализовать что-то вроде:

 if (Math.Abs(a - b) < some_small_value)
{
    // Values are equal
}
  

Комментарии:

1. вы правы, я изменил его на Point sharedCorner = outsideCorners . FirstOrDefault((outsideCorner) => insideCorners.Exists((insideCorner) => Math.Abs((insideCorner — outsideCorner) . Длина) < Math.Pow(10, -10))); который проверяет равенство с использованием порога допуска, и это работает, но также очень медленно, спасибо, что указали мне в этом направлении