Salamander 2 21 февраля, 2021 Опубликовано 21 февраля, 2021 · Жалоба Добрый день, друзья. Есть у меня 3D библиотека, настроил я ее, нарисовал кубик. Теперь хочу его покрутить (при помощи сенсорного экрана). Вначале я крутил сам кубик, но не получил желаемого результата - стоит его горизонтальным движением пальца повернуть вокруг вертикальной оси, вместе с ним поворачивается и горизонтальная (что естественно), а когда после этого начинаешь водить пальцем вверх-вниз, он не заваливается взад-вперед относительно наблюдателя, а крутится вокруг изменившей свое пространственное положение горизонтальной оси (что, опять-таки, естественно). Я решил поступить по другому - вращать не объект, а перемещать камеру вокруг кубика. То есть точка прицела камеры всегда в координатах 0,0,0, а сама камера гуляет по поверхности сферы радиусом 10. Иными словами - ведешь по экрану вверх-вниз - меняется зенитный угол, ведешь вправо-влево - меняется азимут. Высчитываю по вот такой формуле В коде это выглядит так: azimuthal+=(float32_t)d_evt.getDeltaX()/495; // Преобразуем горизонтальный пробег пальца по экрану в приращение азимута zenital+=(float32_t)d_evt.getDeltaY()/445; // Преобразуем вертикальные пробег пальца по экрану в приращение зенитного угла dsp3D_setCameraPosition(10*arm_sin_f32(zenital)*arm_cos_f32(azimuthal), 10*arm_sin_f32(zenital)*arm_sin_f32(azimuthal), 10*arm_cos_f32(zenital)); // Перемещаем камеру (при этом сама камера всегда смотрит в точку 0,0,0) Вращение камеры почему-то неадекватное. Даже трудно описать в чем, но чем дальше поворачивается кубик, тем неадекватнее его реакция на движение. проверял отладкой преобразование пробега пальца по экрану в параметры azimuthal и zenital - оно адекватное. Саму камеру перемещал вверх-вниз, вправо-влево - тоже адекватно. Но она при этом движется во фронтальное плоскости перед объектом, что не соответствует желаемому. А желаемое - двигаться в пределах сферы, окружающей объект. В упор не вижу ошибки, в чем она может быть? взглянем, к примеру на формулу расчета Z - из нее вытекает, что Z зависит только от зенитного угла, но ведь это не так! Если камера, не меняя зенита, будет "водить хоровод" вокруг объекта, Z ведь должен меняться... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 21 февраля, 2021 Опубликовано 21 февраля, 2021 · Жалоба 5 часов назад, Salamander сказал: В упор не вижу ошибки, в чем она может быть? Как отсчитываете зенитный угол: - угол между осью Z и вектором r - угол между плоскостью XY и вектором r У вас формулы для первого случая. Он соответствует всей прочей логике вашей программы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 8 hours ago, Darth Vader said: Как отсчитываете зенитный угол: - угол между осью Z и вектором r - угол между плоскостью XY и вектором r Плоскость XY смотрит на меня Из нее же на меня направлена ось Z. В этом случае отличие способа отсчета должно сказаться лишь на том, куда будет смотреть камера при угле, скажем, 0 градусов - на "фасад" или на "крышу". Но на вращение то это не должно влиять. Вот видео поведения куба. Посмотрите как меняется его вращение при изменении азимута, вначале он наклоняется вокруг горизонтальной оси, а потом почему-то вращается вокруг вертикальной. https://cloud.mail.ru/public/whtu/BXQvRUxSV Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба Ага.... разница в том, что в моей библиотеке ось Z смотрит на экран, а в формуле - вверх. Переставил оси - вроде заработало почти как надо. Только вот зенит почему-то работает только в пределах 0-180 градусов.... пытаешься заглянуть под объект, при пересечении 0 или 180 градусов начинается вращение в обратную сторону. Это как побороть? dsp3D_setCameraPosition(10*arm_sin_f32(zenital)*arm_sin_f32(azimuthal), 10*arm_cos_f32(zenital), 10*arm_sin_f32(zenital)*arm_cos_f32(azimuthal)); Вот такая на данный момент формула Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 22 февраля, 2021 Опубликовано 22 февраля, 2021 (изменено) · Жалоба 3 часа назад, Salamander сказал: пытаешься заглянуть под объект, при пересечении 0 или 180 градусов начинается вращение в обратную сторону. Это как побороть? Не понятно, что значит в обратную сторону? При переходе через 0 и 180 градусов у вас множитель 3 часа назад, Salamander сказал: arm_sin_f32(zenital) также переходит через 0 и меняет знак на противоположный. Может это и воспринимается визуально, как вращение в обратную сторону. Сделайте картинку с расположением осей и углов. Особо обратите внимание на зенитный угол - как он отсчитывается. Проверьте, чтобы везде, где он используется в программе его отсчет был одинаков - это угол между вектором r и осью Z. Функция dsp3D_setCameraPosition(х,y,z) - подразумевает, что плоскость экрана монитора совпадает с плоскостью XY, а ось Z перпендикулярна ему и смотрит НА наблюдателя. Вы же считаете, что экран расположен в плоскости XZ, а ось Y перпендикулярна экрану и направлена ОТ наблюдателя. В этом случае формула преобразования координат будет такой: x=x1; y=z1; z=-y1; Здесь (x1,y1,z1) - координаты в вашей системе, а (x,y,z) - координаты для функции dsp3D_setCameraPosition. У вас же для координаты z в формуле пропущен минус. Изменено 22 февраля, 2021 пользователем Darth Vader Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 (изменено) · Жалоба 2 hours ago, Darth Vader said: В этом случае формула преобразования координат будет такой: x=x1; y=z1; z=-y1; Здесь (x1,y1,z1) - координаты в вашей системе, а (x,y,z) - координаты для функции dsp3D_setCameraPosition. У вас же для координаты z в формуле пропущен минус. Сделал, работает. Не совсем так как думалось изначально - если камеру поднять высоко, то она по азимуту описывает воронку - но так даже лучше. Но все равно с зенитом фигня - не хочет камера подныривать по горизонтальную плоскость. То есть угол в -1 градус воспринимается как угол в 1 градус и так далее. Угол в 181 градус воспинимается как угол в 179 градусов Изменено 22 февраля, 2021 пользователем Salamander Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 15 минут назад, Salamander сказал: То есть угол в -1 градус воспринимается как угол в 1 градус и так далее. Угол в 181 градус воспинимается как угол в 179 градусов Вы определитесь, какой угол вы сейчас описываете. Чему он равен в сферической системе координат? Ваш -1 градус соответствует зенитному углу 91 градус, а 181 - это -91 градус (или 269 градусов). Т.е. здесь вы считаете угол между вектором r и вашей горизонтальной плоскостью XY. Может из-за этого у вас такие проблемы? Я специально обращал ваше внимание на зенитный угол - чтобы он везде во всех частях программы отсчитывался единообразно. Проверьте это. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 5 часов назад, Darth Vader сказал: сферической системе координат? Что за система такая? "Полярную" - знаю ещё со школы, про "сферическую" - впервые слышу. Это случайно не та, в которой вакуумный конь расположен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 5 hours ago, Darth Vader said: Ваш -1 градус соответствует зенитному углу 91 градус, а 181 - это -91 градус (или 269 градусов). Т.е. здесь вы считаете угол между вектором r и вашей горизонтальной плоскостью XY. Может из-за этого у вас такие проблемы? Вы уверены, что в этом случае будут какие-то проблемы помимо неправильного положения объекта перед камерой? Точнее в ошибке поворота, составляющей 90 градусов? Смотрите, я отклоняю камеру в зените на некий угол - отклоняю бесконечно, и неважно, что у меня идет после 360 - 361 или 1 - камера должна идти по кругу. У меня же почему то движение только в пределах полупериода, в следующем полупериоде направление движения меняется. 2 minutes ago, jcxz said: Это случайно не та, в которой вакуумный конь расположен? Она самая http://900igr.net/up/datas/183262/021.jpg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 13 минут назад, jcxz сказал: "Полярную" - знаю ещё со школы, про "сферическую" - впервые слышу. Полярная - это двумерная, на плоскости. А сферическая - трехмерная, в пространстве. 15 минут назад, Salamander сказал: отклоняю бесконечно, и неважно, что у меня идет после 360 - 361 или 1 - камера должна идти по кругу. У меня же почему то движение только в пределах полупериода, в следующем полупериоде направление движения меняется. Такое впечатление, что какая-то из функций приводит значение входного аргумента к какому-то диапазону, например от 0 до 180 градусов. И это приведение преобразует угол -1 градус в 1, 181 в 1 и т.д. Надо смотреть отладчиком такие случаи. Не видя входных и выходных данных расчетов не разберешься. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 10 minutes ago, Darth Vader said: Такое впечатление, что какая-то из функций приводит значение входного аргумента к какому-то диапазону, например от 0 до 180 градусов. А вот и нет. Входной параметр у меня в норме. Смотрю его отладчиком Вот окончательный вариант dsp3D_setCameraPosition(10*arm_sin_f32(zenital)*arm_cos_f32(azimuthal), 10*arm_cos_f32(zenital), -10*arm_sin_f32(zenital)*arm_sin_f32(azimuthal)); // Перемещаем камеру (при этом сама камера всегда смотрит в точку 0,0,0) dsp3D_setLightPosition(10*arm_sin_f32(zenital)*arm_cos_f32(azimuthal), 10*arm_cos_f32(zenital), -10*arm_sin_f32(zenital)*arm_sin_f32(azimuthal)); // Перемещаем камеру (при этом сама камера всегда смотрит в точку 0,0,0) Смена направления у меня происходит как раз, когда значение zenital переходит через ноль. Блин.... так все правильно - Z у меня рассчитывается по формуле sin*sin, при отрицательном угле зенита оба синуса отрицательные, в произведении это дает плюс. Я понял.... надо в зависимости от полярности зенитного угла менять полярность Z Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 22 февраля, 2021 Опубликовано 22 февраля, 2021 · Жалоба 2 минуты назад, Salamander сказал: Входной параметр у меня в норме. Смотрю его отладчиком Имеется ввиду как его внутри обрабатывают функции dsp3D_setCameraPosition, dsp3D_setLightPosition. Надо посмотреть, какие они дают результаты для ваших характерных "подгоризонтных" сферических координат (zenital более 90 градусов). Для отладки сделайте 3 структуры: - сферические координаты камеры исходные - прямоугольные координаты в СК исходного объекта (на который смотрит камера) - прямоугольные координаты в СК функции dsp3D_setCameraPosition Задавайте значения сферических координат в первой структуре, меняя только zenital, и смотрите, что будет в двух других при переходе через 90 и минус 90 градусов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 22 февраля, 2021 Опубликовано 22 февраля, 2021 (изменено) · Жалоба 1 hour ago, Darth Vader said: Задавайте значения сферических координат в первой структуре, меняя только zenital, и смотрите, что будет в двух других при переходе через 90 и минус 90 градусов. Ахахах, уписаться можно)))) Сделал я как вы сказали - с численными значениями координат все нормально. Они меняются как надо. А смена направления вращения - это ИЛЛЮЗИЯ! Камера при переходе через горизонт почему-то переворачивается на 180 градусов вокруг оси, соответствующей направлению взгляда. И кубик, который только что "падал" от нас, начинает на нас "заваливаться". Да.... с этой то проблемой я разобрался, теперь нужно лезть в библиотеку и искать где там настройки поворота камеры. Изменено 22 февраля, 2021 пользователем Salamander Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться