Название: Billboard Отправлено: Igors от Июль 31, 2012, 10:46 Добрый день
Есть прямоугольник заданный угловыми точками QVector3D p[4]. Дана точка цели QVeсtor3D target. Надо повернуть прямоугольник мордой на цель: центр прямоугольника остается на своем месте, а угловые точки пересчитываются так чтобы вектор центр-цель был перпедикулярен плоскости прямоугольника. Ну как бы "радар отслеживает цель" Спасибо Название: Re: Billboard Отправлено: sergey_ulyanov от Июль 31, 2012, 14:01 Код: //4 точки прямоугольника Название: Re: Billboard Отправлено: Igors от Июль 31, 2012, 16:05 Код: // Итоговая матрица поворота на цель Спасибо Название: Re: Billboard Отправлено: sergey_ulyanov от Август 01, 2012, 10:00 Код
Название: Re: Billboard Отправлено: Igors от Август 01, 2012, 20:19 Так все гуд, спасибо. Только нормаль надо взять наоборот (правая тройка, идем по часовой, должно быть (0, 0, -1)).
Я попробовал сделать по-другому (аттач), получается та же матрица. Но не могу понять почему надо transpose, наверное они как-то строки со столбцами замутили. Название: Re: Billboard Отправлено: sergey_ulyanov от Август 01, 2012, 20:57 Цитировать Так все гуд, спасибо. Только нормаль надо взять наоборот (правая тройка, идем по часовой, должно быть (0, 0, -1)). Вопрос правильности выбора нормали - условный. Все зависит в какой последовательности заданы точки контура и от априорных данных о "лицевой стороне".Цитировать Я попробовал сделать по-другому (аттач), получается та же матрица. Но не могу понять почему надо transpose, наверное они как-то строки со столбцами замутили. В предложенном мной варианте делается всего один поворот вокруг вектора нормального к плоскости нормаль-цель на угол между этими двумя векторами. В приведенном вами варианте выполняется 2 последовательных поворота. transpose вообще говоря неправильно, вернее было бы inverted, просто матрица поворота ортогональна и поэтому для нее это эквивалентно. Обращение же матрицы необходимо здесь т.к. повороты получены для вектора направления на цель, а не для нормали плоскости.Название: Re: Billboard Отправлено: Igors от Август 02, 2012, 13:05 В предложенном мной варианте делается всего один поворот вокруг вектора нормального к плоскости нормаль-цель на угол между этими двумя векторами. В приведенном вами варианте выполняется 2 последовательных поворота. Один зато какой. Вызываете acos, который rotate опять переводит в cos. Синус у Вас тоже пракически посчитан, но rotate его опять считает. Так что с точки зрения оптимальности - спорно. Однако я вовсе не хочу доказать что "мой вариант лучше" - просто хочется понять как это получается. Когда разберусь - возможно буду пользоваться тем же rotate. Обращение же матрицы необходимо здесь т.к. повороты получены для вектора направления на цель, а не для нормали плоскости. Конечно умножение на матрицу с нулевым смещением есть поворот, но в данном случае не видно что к чему поворачивается. Я думал так- умножение на матрицу M1 соответствует переводу точек из мировой системы координат в локальную, поэтому заполняем M1 по столбцам (обратная матрица) - умножение на матрицу M2 = перевод точек из локальной в мировую, заполняем M2 по строкам (прямая матрица) Если M2 получается из M1 вращением (а это так), то произведение M1 * M2 должно выполнить нужный поворот (без всяких transposed). Где ошибка? Название: Re: Billboard Отправлено: sergey_ulyanov от Август 02, 2012, 13:26 Цитировать Когда разберусь - возможно буду пользоваться тем же rotate. Rodrigues Rotation Formula (http://mathworld.wolfram.com/RodriguesRotationFormula.html)Цитировать Конечно умножение на матрицу с нулевым смещением есть поворот Неверно, у матрицы растяжения/сжатия тоже нулевое смещениеНазвание: Re: Billboard Отправлено: sergey_ulyanov от Август 02, 2012, 14:30 Цитировать Если M2 получается из M1 вращением (а это так), то произведение M1 * M2 должно выполнить нужный поворот (без всяких transposed). Где ошибка? Ну наверное нужно понять, что собой представляют матрицы M1 и M2 в вашем примере. M1 - базис системы координат прямоугольника. Базисные вектора (записываются по столбцам матрицы): ortX - нормаль к плоскости образованной вектором нормали прямоугольника и направлением из его центра на цель ortZ1*ortX - дополнение до тройки векторов ortZ1 - нормаль прямоугольника M2 - базис системы требуемой системы ortX - нормаль к плоскости образованной вектором нормали прямоугольника и направлением из его центра на цель ortZ2*ortX - дополнение до тройки векторов ortZ2 - направление из центра прямоугольника на цель Первая ошибка - в матрице M2 вместо того, чтобы поставить базисные вектора по столбцам, вы ставите их по строкам (транспонируете). Вторая ошибка - это порядок преобразования. Здесь была такая идея: - перенести центр координат прямоугольника в начало мировых координат (матрица translateToOrigin) - перейти к СК прямоугольника (матрица M1) - выполнить переход к требуемому базису (матрица M2) - вернуться обратно к исходному центру прямоугольника (матрица translateToCenter) Итого T= translateToCenter * M2 * M1 * translateToOrigin; Название: Re: Billboard Отправлено: Igors от Август 02, 2012, 14:53 Здесь была такая идея: Совершенно верно, именно так я и хотел. Наверно если аккуратно расписать матричное произведение то и получится формула товарища Родригеса. Предлагаю не тратить время на упоминания о том что надо отнять/добавить смещение, это очевидно- перенести центр координат прямоугольника в начало мировых координат (матрица translateToOrigin) - перейти к СК прямоугольника (матрица M1) - выполнить переход к требуемому базису (матрица M2) - вернуться обратно к исходному центру прямоугольника (матрица translateToCenter) Первая ошибка - в матрице M2 вместо того, чтобы поставить базисные вектора по столбцам, вы ставите их по строкам (транспонируете). Почему же ошибка? Ведь я хочу перейти из мировой в локальную, значит должен создать обратную (в данном случае транспонированную).Итого T= translateToCenter * M2 * M1 * translateToOrigin; Чего же это мы сразу (из мира) множимся на M2, которая есть новая (требуемая) СК? Мы должны сначала соскочить в локальную (помножить на M1)Подозреваю что QMatrix4x4 преобразует не так как я полагаю. Я рассчитываю что "матрица справа", и матрица записанная по строкам соответствует "из локальной в мир" Название: Re: Billboard Отправлено: sergey_ulyanov от Август 02, 2012, 15:04 Цитировать Чего же это мы сразу (из мира) множимся на M2, которая есть новая (требуемая) СК? Мы должны сначала соскочить в локальную (помножить на M1) ??? Я же писал порядок преобразования: Цитировать Здесь была такая идея: - перенести центр координат прямоугольника в начало мировых координат (матрица translateToOrigin) - перейти к СК прямоугольника (матрица M1) - выполнить переход к требуемому базису (матрица M2) - вернуться обратно к исходному центру прямоугольника (матрица translateToCenter) Порядок выполнения операций: Цитировать Итого T= translateToCenter * M2 * M1 * translateToOrigin; 1. translateToOrigin 2. M1 3. M2 4. translateToCenter Множимся на M2 мы не из мира а из M1 Название: Re: Billboard Отправлено: Igors от Август 02, 2012, 16:34 Цитировать Итого T= translateToCenter * M2 * M1 * translateToOrigin; 1. translateToOrigin 2. M1 3. M2 4. translateToCenter Множимся на M2 мы не из мира а из M1 Название: Re: Billboard Отправлено: sergey_ulyanov от Август 02, 2012, 16:38 Цитировать А как же Вы заставите операторы выполняться справа налево ???Зачем справа-налево? u = T*v T= translateToCenter * M2 * M1 * translateToOrigin u = translateToCenter * M2 * M1 * translateToOrigin * v что эквивалентно u = (translateToCenter * (M2 * (M1 * (translateToOrigin * v)))) В линейной алгебре уж так принято) Название: Re: Billboard Отправлено: Igors от Август 02, 2012, 17:08 Зачем справа-налево? Насколько мне известноu = T*v T= translateToCenter * M2 * M1 * translateToOrigin u = translateToCenter * M2 * M1 * translateToOrigin * v что эквивалентно u = (translateToCenter * (M2 * (M1 * (translateToOrigin * v)))) В линейной алгебре уж так принято) M = M1 * M2 Элементы новой матрицы M получаются как суммы произведений строк M1 на столбцы M2. О др правилах векторной алгебры я не слышал. То что Вы говорите понятно если бы матрица применялась "слева". Но ведь судя по исходникам не так Код Я так вижу что вектор-строка множится на столбцы матрицы ??? |