Вот одна формула, которая избегает всей логики регистра.(Я сейчас работаю в JS, так что вот реализация JS).Пусть rect = {max:{x:_, y:_}, min:{x:_, y:_}}
и p={x:_, y:_}
function distance(rect, p) {
var dx = Math.max(rect.min.x - p.x, 0, p.x - rect.max.x);
var dy = Math.max(rect.min.y - p.y, 0, p.y - rect.max.y);
return Math.sqrt(dx*dx + dy*dy);
}
Объяснение: Это разбивает задачу на вычисление расстояния x dx
и расстояния y dy
.Затем он использует формулу расстояния.
Для расчета dx
, вот как это работает.(dy
аналогично)
Посмотрите на кортеж, предоставляемый функции max: (min-p, 0, p-max)
.Обозначим этот кортеж (a,b,c)
.
Если p осталось от min, тогда p (+,0,-), и поэтому функция max вернёт правильно a = min - p
.
Если p находится между min и max, то у нас есть min
(-,0,-).Итак, еще раз, функция max будет правильно возвращать b = 0
.
Наконец, если p находится справа от max, то мы имеем, min (-,0,+).Еще раз, Math.max корректно возвращает c = p - max
.
Таким образом, получается, что Math.max заботится обо всей логике кейса, что приводит к хорошей трехстрочной функции без контроля потока.