Russian Qt Forum
Сентябрь 25, 2024, 20:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Правила трансформации  (Прочитано 6151 раз)
Lostinnet
Гость
« : Сентябрь 23, 2009, 14:02 »

Подскажите кто знает, как правильно трансформировать item

Изначально есть item который повернут относительно некоторой точки, масштабирован по оси X и Y и сдвинут.
Далее необходимо этот итем повернуть еще на некоторый угол.
При использовании команды setTransform(transform().translate(x, y).rotate(a).translate(-x, -y));
item поворачивается, но и искажается.

как правильно повернуть итем, чтоб сама геометрия итема не менялась ??
Записан
BaltikS
Гость
« Ответ #1 : Сентябрь 23, 2009, 14:07 »

Цитировать
Далее необходимо этот итем повернуть еще на некоторый угол.
При использовании команды setTransform(transform().translate(x, y).rotate(a).translate(-x, -y));
item поворачивается, но и искажается.
Не совсем понятно что вы хотите. Что вы понимаете под искажением и геометрией итема?
Записан
Lostinnet
Гость
« Ответ #2 : Сентябрь 23, 2009, 14:22 »

ПРИМЕР:

имеем item в форме квадрата, масшабируем его по оси Y (увеличили в 2 раза)
далее этот прямоугольник поворачиваем на 90 гр. и имеем что наш прямоугольник остался растянутым по оси Y, а не по оси X.
Записан
BaltikS
Гость
« Ответ #3 : Сентябрь 23, 2009, 16:50 »

Вам вращать надо относительно центра квадрата и всё будет в шоколаде...
Записан
motodrug
Гость
« Ответ #4 : Сентябрь 27, 2009, 14:46 »

void ITEM::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*)
{
    setTransform(QTransform()
        .translate(ITEM_SIZE / 2, ITEM_SIZE / 2)
        .rotate(x_angle, Qt::XAxis)
        .rotate(y_angle, Qt::YAxis)
        .translate(-ITEM_SIZE / 2, -ITEM_SIZE / 2));

    // drawing...
}

Это работающий код. x_angle и y_angle : qreal, задающие угол поворота в градусах. Квардратный ITEM вращается вокруг центральной точки. Правда сегодня нарыл один косяк в Qt: если угол будет = 90, то Qt считает ITEM невидимым и все вызовы update() складывает в очереди. после отклонения от 90 + некоторая дельта, он пачкой вызывает метод рисования.
Вот ведь какой умный!
Пробовал я разное и qApp->processEvents() и flush() и чего только еще не пробовал. Но вылечило только это:
if (x_angle == 90) { x_angle = 89.9; }
тогда все пучком.

Удачи!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Сентябрь 27, 2009, 15:31 »

void ITEM::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*)
{
    setTransform(QTransform()
        .translate(ITEM_SIZE / 2, ITEM_SIZE / 2)
        .rotate(x_angle, Qt::XAxis)
        .rotate(y_angle, Qt::YAxis)
        .translate(-ITEM_SIZE / 2, -ITEM_SIZE / 2));

    // drawing...
}

Это работающий код. x_angle и y_angle : qreal, задающие угол поворота в градусах. Квардратный ITEM вращается вокруг центральной точки. Правда сегодня нарыл один косяк в Qt: если угол будет = 90, то Qt считает ITEM невидимым и все вызовы update() складывает в очереди. после отклонения от 90 + некоторая дельта, он пачкой вызывает метод рисования.
Вот ведь какой умный!
Пробовал я разное и qApp->processEvents() и flush() и чего только еще не пробовал. Но вылечило только это:
if (x_angle == 90) { x_angle = 89.9; }
тогда все пучком.
Как я понял, Вы вращаете не квадрат а "рамку" в 3D пространстве (поворот вокруг осей X и Y). Тогда для изначального квадрата лежащего в плоскости XY "исчезновение" естественно (площадь проекции = 0, а wireframe никто не обещал). Для вращения в плоскости XY нужен только rotate(z_angle, Qt::ZAxis);
« Последнее редактирование: Сентябрь 27, 2009, 15:35 от Igors » Записан
motodrug
Гость
« Ответ #6 : Сентябрь 27, 2009, 18:39 »


[/quote]Как я понял, Вы вращаете не квадрат а "рамку" в 3D пространстве (поворот вокруг осей X и Y). Тогда для изначального квадрата лежащего в плоскости XY "исчезновение" естественно (площадь проекции = 0, а wireframe никто не обещал). Для вращения в плоскости XY нужен только rotate(z_angle, Qt::ZAxis);
[/quote]

Я вращаю QPixmap. Далее код такой: painter.drawPixmap(0, 0, my_pixmap);
Да, это имитация поворота в 3D, хотя, конечно, при параллельной проекции фигня получается, но все-таки интересно. Улыбающийся
Я описывал другой "баг". Я понимаю, что если повернуть плоскость на 90 градусов (oX || oY), то она "исчезнет", но фишка в том, что если его после значения 90, ее вращать обратно (анимация так работает), то на значении 89 он обратно не появляется. Круто, да?
Попробуйте подставить такие углы (именно в такой последовательности): 0, 10, .. 80, 90, 80, .. 10, 0. Несколько кадров после 90 - не отрисуются. Версия Qt 4.5.2. Одинаково проявляется на Windows (XP & Vista) и Linux (Ubuntu).
IMHO, QGraphicsItem "помнит какое-то время", что он был невидим (именно из-за значения угла!) и понижает приоритет update(), т.е. код virtual QGraphicsItem::paint() не выполняется сразу. Зато когда угол до нуля дойдет - выкинет сразу пачку апдейтов. Этакая оптимизация у них - надо бы их код посмотреть...
Как я уже говорил, пробовал всякие там processEvents(), таймеры, синки и вообще у меня программка простейшая. Я понимаю, была бы нагрузка в аппликации серьезная, но ведь нет!
Да ладно, уже понесло меня. Улыбающийся Короче проще не поворачивать в точное значение 90. Сделал 89.9 и все заработало идеально плавно и глаз разницы не замечает. И безо всяких ухищрений. Как оно и должно быть.

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.157 секунд. Запросов: 23.