Непонятно, что вы имеете в виду под «нормализацией» точки попадания, поскольку в опубликованном вами коде нет ничего, что нормализует ее, но вы упомянули, что ваша точка попадания находится в мировом пространстве.
Кроме того, вы не сказали, какое отображение текстуры вы пытаетесь реализовать, но я предполагаю, что вы хотите, чтобы координаты текстуры U и V отображали широту и долготу на поверхности сферы.
Ваша первая проблема заключается в том, что преобразование декартовых координат в сферические требует, чтобы сфера была центрирована в начале координат в декартовом пространстве, что неверно в мировом пространстве. Если точка попадания находится в мировом пространстве, вы должны вычесть центральную точку сферы в пространстве мира, чтобы получить эффективную точку попадания в локальных координатах. (Вы уже поняли эту часть и обновили вопрос новым изображением.)
Вторая проблема заключается в том, что способ вычисления theta
требует, чтобы сфера имела радиус 1, что неверно даже после того, как вы переместите центр сферы в начало координат. Помните свою тригонометрию: аргумент acos
- это отношение стороны треугольника к его гипотенузе, и он всегда находится в диапазоне (-1, +1). В этом случае ваша координата Y - это сторона, а радиус сферы - гипотенуза. Таким образом, вы должны разделить на радиус сферы при вызове acos
. Также рекомендуется ограничить значение диапазоном (-1, +1) на тот случай, если ошибка округления с плавающей запятой выводит его немного за пределы.
(В принципе, вам также придется разделить координаты X и Z на радиус, но вы используете их только для обратной касательной, и деление их обоих на радиус не изменит их частное и, следовательно, не изменится phi
.)
Прямо сейчас ваши функции пересечения сфер и координат текстуры работают в мировом пространстве, но вы, вероятно, сочтете полезным позже реализовать матрицы преобразования, которые позволяют преобразовывать объекты из одного координатного пространства в другое. Затем вы можете изменить свои сферические функции для работы в локальном координатном пространстве, где центр является началом, а радиус равен 1, и дать каждому объекту связанную матрицу преобразования, которая отображает локальное координатное пространство в мировое координатное пространство. Это упростит ваш код пересечения луча / сферы и позволит вам удалить вычитание начала координат и деление радиуса из GetTextureCoord
(поскольку они всегда (0, 0, 0) и 1 соответственно).
Чтобы пересечь луч с объектом, вы должны использовать матрицу преобразования объекта, чтобы преобразовать луч в локальное координатное пространство объекта, выполнить пересечение (и вычислить координаты текстуры) там, а затем преобразовать результат (например, точку попадания и нормаль поверхности ) обратно в мировое пространство.
person
Wyzard
schedule
17.04.2015
hitPoint
вычисляется так, как если бы сфера находилась в начале координат (а затем преобразовывалась в другом месте), или вы напрямую поддерживаете сферы, не центрированные в начале координат, в вашем тесте на пересечение? Вычисление phi и theta с использованием косинуса и тангенса дает вам значения, соответствующие сфере с центром в начале координат, поэтому, если сфера на самом деле нет, отображение координат текстуры не будет тем, что вы, вероятно, планировали. - person Wyzard   schedule 17.04.2015u
иv
- координаты текстуры, и функция для вычисления координат текстуры обычно просто возвращает их. Сопоставление их с целочисленными индексами текселей не является специфическим для сфер и должно выполняться где-то еще. - person Wyzard   schedule 17.04.2015