XNA - проверьте, находится ли Vector2 внутри прямоугольника

Какой лучший способ проверить, находится ли Vector2 внутри прямоугольника?

myRect.contains(myVector2) не работает, так как ожидает Point или Rectangle.

Я знаю, что могу преобразовать Vector2 в точку или даже в прямоугольник размером 1/1, но я не уверен в производительности.

Каков ваш опыт?


person SwissCoder    schedule 21.01.2012    source источник


Ответы (2)


Хотя может быть дополнительное время выполнения при приведении по сравнению с созданием точки, такой как Point (myVector2.X, myVector2.Y), последствия, скорее всего, слишком малы, чтобы вы когда-либо заметили (как правило, следует избегать преждевременной оптимизации)

Выберите то, что выглядит самым чистым и простым в обслуживании. Если бы это был я, я бы, вероятно, просто создал новую точку в вызове метода...

Вы также можете написать метод расширения.

    public static Point Origin(this Vector2 v)
    {
        //original proposal
        //return new Point( (int)v.X, (int)v.Y );

        //better! does correctly round the values
        return new Point( Convert.ToInt32(v.X), convert.ToInt32(v.Y));
    }

Тогда вы могли бы сделать что-то вроде этого rect.Contains(vec.Origin)

Тем не менее, кое-что следует помнить: этот метод на самом деле не проверяет, содержится ли вектор в прямоугольнике, он проверяет только начало координат. Помните, что вектор — это направление и величина.

person Justin Self    schedule 21.01.2012
comment
возможно, при таком округлении производительность не такая, как при литье. Но все же я ничего не заметил, когда играл в игру. - person SwissCoder; 23.01.2012
comment
зачем вам использовать пользовательскую функцию, если у прямоугольника есть метод Contains? - person xus; 14.04.2012
comment
@xus, потому что метод contains не принимает вектор2. Так что, по крайней мере, для меня rect.Contains(vec.Origin) выглядит чище, чем rect.Contains((int)myVector2.X, (int)myVector2.Y) - person Justin Self; 16.04.2012

Одна из перегруженных версий Contains для структуры Rectangle принимает координаты X и Y.

Rectangle rect = new Rectangle(-5, -5, 10, 10);
Vector2 myVector2 = Vector2.Zero;

rect.Contains((int)myVector2.X, (int)myVector2.Y)

Я предполагаю, что вы говорите о myVector2, представляющем точку, а не расстояние или направление.

person Nic Foster    schedule 21.01.2012
comment
Нет, я использую Vector2 для хранения позиции. Это не может быть точкой! Если бы это была точка, перевод (перемещение) соответствующего объекта не был бы плавным. - person SwissCoder; 21.01.2012
comment
Ответ, который вы исключили, принимает Vector2, преобразует его в точку и проверяет его на прямоугольнике. Мой метод пропускает шаг, который преобразуется в точку. Я не вижу проблемы. Если точка - это не то, что вам нужно, то почему вы приняли ответ, в котором вы использовали точку. Я не уверен, кто здесь больше запутался, я или ты. Особенно, когда вы только что сказали, что используете Vector2 для хранения позиции, что делает его точкой. Если вы хотите проверить эту позицию на прямоугольнике, мой метод настолько эффективен, насколько вы найдете. - person Nic Foster; 21.01.2012
comment
Вам нужно будет преобразовать ваши X и Y в int, поскольку Rectangle.Contains принимает целые числа, а не числа с плавающей запятой. - person Justin Self; 22.01.2012
comment
@SwissCoder Одна из вещей, на которую (вероятно) намекал Ник, заключалась в том, что переход от позиции вектора к точке теряет точность, поскольку точка использует целые числа, а вектор2 использует числа с плавающей запятой. Поэтому, если ваш вектор равен 2,4, приведение 2,4 как int для проверки прямоугольника заставит точки перейти к 2, 2. Просто имейте это в виду при любом решении, которое вы решите реализовать. - person Justin Self; 22.01.2012
comment
@Nic: Мой вопрос был о преобразовании. И вы даже не заметили, что конверсия была необходима. Также прямое приведение к int - не лучшее решение. - person SwissCoder; 22.01.2012
comment
@justnS: Вы правы. Посмотрите мой комментарий, чтобы понять, почему я снял отметку с вашего ответа как правильный. - person SwissCoder; 22.01.2012
comment
Действительно, округление до ближайшего целого числа было бы более точным, чем приведение, которое эффективно округляет в меньшую сторону. - person Nic Foster; 22.01.2012