Сравнение векторов

Для того чтобы сравнить два вектора – определить, указывают ли оба вектора в одну и ту же точку, нужно сравнить координаты обоих векторов и если они соответственно равны, значит и вектора тоже равны. Однако координаты векторов задаются величинами типа float, сравнение которых на равенство, из-за особенностей хранения такого типа в памяти компьютера, никогда не бывает точным.

Рассмотрим это на примере. Добавим в сцену два объекта, состоящие каждый из одного ребра. Это ребро и будет обозначать вектор в пространстве 3D сцены. Назовем объекты V0 и V1 и расположим их в сцене совершенно одинаково – из начала сцены (0, 0, 0) в любую другую точку. Проще всего создать сначала один объект, а потом сделать его копию, нажав shift + d.

Теперь мы можем получить координаты векторов, образованных нашими объектами:

Как мы видим, координаты векторов полностью совпадают.

Глядя на это, кажется что мы можем написать элементарную функцию, которая будет сравнивать соответствующие координаты двух векторов и возвращать результат сравнения по всем трем координатам.

Что-то вроде этого:

И если мы попробуем протестировать эту функцию на наших двух векторах, мы получим правильный ответ:

Однако не будем спешить радоваться.

Из курса математики мы знаем, что значение не измениться, если произвести над ним какое-либо математическое действие, а потом произвести обратное действие. Например, прибавить единицу, а потом отнять единицу. Или поделить на десять, а потом умножить на десять.

Давайте в качестве эксперимента поделим координату X нашего вектора V1 на три, а потом обратно умножим ее на три.

Итоговое значение не должно отличаться от исходного, однако если мы напечатаем координаты векторов снова, мы увидим некоторые изменения.

Начиная примерно с пятого знака после запятой, значение координаты X теперь отличается от того же значения во втором векторе, которое мы не трогали.

Противоречий с математикой здесь нет, просто нужно помнить, что компьютерная память устроена так, что не может хранить числа с плавающей точкой с абсолютной точностью.

И теперь, если мы вновь попробуем сравнить вектора написанной нами выше функцией, мы получим противоположный результат.

Как же тогда нам сравнивать вектора?

Для того чтобы при сравнении чисел с плавающей точкой получать более предсказуемые результаты, обычно их не сравнивают на абсолютное равенство, а проверяют, отличается ли одно число от другого больше чем на заданную дельту – обычно маленькое число с тремя-пятью нулями после запятой.

Самая простая формула для такого сравнения выглядит так:

и ее более применимый аналог:

Такой вариант позволяет удобно разводить дельту сравнения, если сравниваются два очень больших числа. Вместе с тем, такая формула плохо работает, если сравниваются два числа близких к нулю.

Поэтому чаще всего используется вариант в котором учитываются две дельты: относительная rel_tol и абсолютная abs_tol. В этом случае формула выглядит следующим образом:

Вернемся к нашим векторам и попробуем применить данную формулу в функции их сравнения.

Применим ее к нашим векторам с различной дельтой.

Пока наши вектора абсолютно идентичны, мы получаем следующий результат:

А после появления погрешности, вызванной математическим действиями:

То есть, сравнивая два вектора с указываемой дельтой, мы можем считать, что вектора одинаковы в пределах заданной погрешности.

0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии