Название: Правила трансформации Отправлено: Lostinnet от Сентябрь 23, 2009, 14:02 Подскажите кто знает, как правильно трансформировать item
Изначально есть item который повернут относительно некоторой точки, масштабирован по оси X и Y и сдвинут. Далее необходимо этот итем повернуть еще на некоторый угол. При использовании команды setTransform(transform().translate(x, y).rotate(a).translate(-x, -y)); item поворачивается, но и искажается. как правильно повернуть итем, чтоб сама геометрия итема не менялась ?? Название: Re: Правила трансформации Отправлено: BaltikS от Сентябрь 23, 2009, 14:07 Цитировать Далее необходимо этот итем повернуть еще на некоторый угол. Не совсем понятно что вы хотите. Что вы понимаете под искажением и геометрией итема?При использовании команды setTransform(transform().translate(x, y).rotate(a).translate(-x, -y)); item поворачивается, но и искажается. Название: Re: Правила трансформации Отправлено: Lostinnet от Сентябрь 23, 2009, 14:22 ПРИМЕР:
имеем item в форме квадрата, масшабируем его по оси Y (увеличили в 2 раза) далее этот прямоугольник поворачиваем на 90 гр. и имеем что наш прямоугольник остался растянутым по оси Y, а не по оси X. Название: Re: Правила трансформации Отправлено: BaltikS от Сентябрь 23, 2009, 16:50 Вам вращать надо относительно центра квадрата и всё будет в шоколаде...
Название: Re: Правила трансформации Отправлено: motodrug от Сентябрь 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; } тогда все пучком. Удачи! Название: Re: Правила трансформации Отправлено: Igors от Сентябрь 27, 2009, 15:31 void ITEM::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) Как я понял, Вы вращаете не квадрат а "рамку" в 3D пространстве (поворот вокруг осей X и Y). Тогда для изначального квадрата лежащего в плоскости XY "исчезновение" естественно (площадь проекции = 0, а wireframe никто не обещал). Для вращения в плоскости XY нужен только rotate(z_angle, Qt::ZAxis);{ 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; } тогда все пучком. Название: Re: Правила трансформации Отправлено: motodrug от Сентябрь 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 и все заработало идеально плавно и глаз разницы не замечает. И безо всяких ухищрений. Как оно и должно быть. |