Вычисление нормали точки в поле высоты

#algorithm #geometry

#алгоритм #геометрия

Вопрос:

У меня есть сферическое поле высот, определяемое функцией f(x, y, z) , которая возвращает расстояние от начала координат поверхности поля высот линии, которая проходит от начала координат до (x,y,z) конца .

(Другими словами, изоповерхность для моего поля высоты равна |x,y,z| = f(x,y,z) .)

(Кроме того, для обсуждения ниже я собираюсь предположить, что surface(x,y,z) это местоположение точки на поверхности непосредственно под (x,y,z) ней .)

При рендеринге этого мне нужно вычислить нормаль для любой точки в поле высоты. Какой самый дешевый способ сделать это?

Чтобы вычислить нормаль к точке в прямоугольном поле высот, обычный трюк заключается в (x,y,z) небольшом смещении в двух направлениях, параллельных номинальной поверхности, вычислении трех точек на поле высот для образования треугольника, а затем использовании перекрестного произведения для вычисления нормали треугольника. Это просто, поскольку три точки могут быть просто surface(x,y,z) surface(x 1,y,z) и surface(x,y 1,z) (или аналогичными). Но для сферического поля высоты это немного сложнее, потому что нормаль может указывать в любом направлении. Простое смещение на x и y не подойдет, потому что, если две мои точки попадают на радиус, то surface() из них вернутся в одно и то же местоположение, и я не получу треугольник.

В прошлом я использовал вектор <x,y,z> как радиус от начала координат сферы; затем вычислял вектор, перпендикулярный ему; затем поворачивал этот вектор вокруг <x,y,z> , чтобы получить мои три точки. Но это неудобно и дорого, и в этом не должно быть необходимости. Должен быть более дешевый способ. Что это?

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

1. Можете ли вы выделить случаи, когда «трюк» не сработает, так что вам нужно использовать дорогостоящую технику только в этих случаях? Это предполагает, конечно, что 1) определение того, когда трюк не срабатывает, обходится дешево, и 2) трюк работает большую часть времени.

2. У меня будут проблемы только тогда, когда радиус моей сферы совпадает с осью X, Y или Z (при условии, что я перемещаюсь в этих направлениях). Я мог бы протестировать их, но есть неприятные крайние случаи — радиус, который почти вдоль оси, в конечном итоге приведет к двум surface() точкам, которые находятся очень близко друг к другу, и это даст мне странные проблемы с округлением / точностью.

Ответ №1:

Вычислите surface() точки и, если они достаточно близки, чтобы вызвать проблемы, выполните более дорогостоящий (но точный) расчет; в противном случае используйте дешевый / простой расчет.