crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Начало работы с 2D графикой, Разбор стандартного примера
Cergey
  опции профиля:
сообщение 8.7.2009, 18:36
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 62
Регистрация: 18.10.2008
Пользователь №: 395

Спасибо сказали: 3 раз(а)




Репутация:   1  


Здравствуйте!

Наверняка при изучении работы с 2D гдафикой видели следующий пример:
Раскрывающийся текст
void OvenTimer::draw(QPainter *painter) 
{
  static const QCOORD triangle[3][2] = {
      { -2, -49 }, { +2, -49 }, { 0, -47 }
  };
  QPen thickPen(colorGroup().foreground(), 2);
  QPen thinPen(colorGroup().foreground(), 1);
  
  painter->setPen(thinPen);
  painter->setBrush(colorGroup().foreground());
  painter->drawConvexPolygon(QPointArray(3, &triangle[0][0]));


Рисование виджета начинается с маленького треугольника, который обозначает нулевую позицию вверху. Треугольник задается тремя, жестко зашитыми парами координат. Собственно рисование производится функцией drawConvexPolygon(). Треугольник можно было бы нарисовать функцией drawPolygon(), но если заранее известно, что многоугольник выпуклый, то вы можете сэкономить несколько микросекунд, за счет использования функции drawConvexPolygon().

Одна из замечательных сторон механизма перехода от логических координат к физическим состоит в том, что мы можем жестко зашивать координаты точек в исходный код и при этом получать неплохие результаты, при изменении размеров виджета.
  painter->setPen(thickPen); 
  painter->setBrush(colorGroup().light());
  painter->drawEllipse(-46, -46, 92, 92);
  painter->setBrush(colorGroup().mid());
  painter->drawEllipse(-20, -20, 40, 40);
  painter->drawEllipse(-15, -15, 30, 30);


Далее рисуются внешний и два внутренних круга. Внешний круг заполняется цветом "light" (обычно -- белый), Внутренние круги заполняются цветом "mid" (обычно -- серый).
  int secs = duration(); 
  painter->rotate(secs * DegreesPerSecond);
  painter->drawRect(-8, -25, 16, 50);
  
  for (int i = 0; i <= MaxMinutes; ++i) {
    if (i % 5 == 0) {
      painter->setPen(thickPen);
      painter->drawLine(0, -41, 0, -44);
      painter->drawText(-15, -41, 30, 25,
                        AlignHCenter | AlignTop,
                        QString::number(i));
      } else {
        painter->setPen(thinPen);
        painter->drawLine(0, -42, 0, -44);
      }
      painter->rotate(-DegreesPerMinute);
  }
}


Затем рисуются рукоятка и риски на лимбе. Напротив каждой пятой риски рисуется число, обозначающее количество минут. Функция rotate() вызывается для того, чтобы повернуть систему координат. В начальный момент, риска с отметкой "0" находилась вверху, теперь же она переместилась в точку, координаты которой зависят от оставшегося до срабатывания времени. Рукоятка рисуется после выполнения поворота, поскольку ее ориентация зависит от угла поворота.

В цикле for, по краю внешнего круга рисуются риски, а под ними -- числа, обозначающие количество минут, с шагом 5. В конце каждой итерации выполняется поворот системы координат по часовой стрелке на 7 градусов, что соответствует одной минуте. Таким образом, каждая следующая риска будет рисоваться на своем месте, хотя координаты в drawLine() и drawText() задаются одни и те же.
Это про таймер электропечи.

Мне не понятно
  
int secs = duration();
  painter->rotate(secs * DegreesPerSecond);
  painter->drawRect(-8, -25, 16, 50);
  
  for (int i = 0; i <= MaxMinutes; ++i) {
    if (i % 5 == 0) {
      painter->setPen(thickPen);
      painter->drawLine(0, -41, 0, -44);
      painter->drawText(-15, -41, 30, 25,
                        AlignHCenter | AlignTop,
                        QString::number(i));
      } else {
        painter->setPen(thinPen);
        painter->drawLine(0, -42, 0, -44);
      }
      painter->rotate(-DegreesPerMinute);
  }
}

У Жасмин Бланшет написано про это:
Сначала там поворачивают систему координат рисовальщика против часовой стрелки, затем рисуют рукоятку, а затем поворачивают рисовальщик по часовой стрелке и поэтому в цикле не надо изменять координаты в drawLine.

Но ведь используется одна функция - rotate. Где не искал, везде ничего не исправлено.
Если это правильно, может кто нибудь пожалуйста это объяснить!!!

Сообщение отредактировал Litkevich Yuriy - 8.7.2009, 20:26
Причина редактирования: пользуйся тэгами code и expand
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 8.7.2009, 20:34
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Cergey @ 8.7.2009, 22:36) *
Сначала там поворачивают систему координат рисовальщика против часовой стрелки, затем рисуют рукоятку, а затем поворачивают рисовальщик по часовой стрелке и поэтому в цикле не надо изменять координаты в drawLine.
Я с этим примером не разбирался, но такого утверждения из приведённого тобой описания выше не вижу. А вижу только это:
Цитата(Cergey @ 8.7.2009, 22:36) *
Одна из замечательных сторон механизма перехода от логических координат к физическим состоит в том, что мы можем жестко зашивать координаты точек в исходный код
Цитата(Cergey @ 8.7.2009, 22:36) *
В конце каждой итерации выполняется поворот системы координат по часовой стрелке на 7 градусов, что соответствует одной минуте. Таким образом, каждая следующая риска будет рисоваться на своем месте, хотя координаты в drawLine() и drawText() задаются одни и те же.
Т.е. в функцию drawLine() передаются абсолютные координаты, затем рисовальщик поворачивается - поворот один.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Cergey
  опции профиля:
сообщение 8.7.2009, 21:23
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 62
Регистрация: 18.10.2008
Пользователь №: 395

Спасибо сказали: 3 раз(а)




Репутация:   1  


Если передаются абсолютные координаты, то первый поворот ничего не меняет, тогда всегда одинаковое изображение. Может тут все-таки ошибка???
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 8.7.2009, 21:53
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Cergey @ 9.7.2009, 1:23) *
Может тут все-таки ошибка???
ну это легко проверить, скомпилируй пример, будет ли он работать как описано?

Цитата(Cergey @ 9.7.2009, 1:23) *
то первый поворот ничего не меняет,
как так? картинка-то поворачивается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Cergey
  опции профиля:
сообщение 9.7.2009, 8:36
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 62
Регистрация: 18.10.2008
Пользователь №: 395

Спасибо сказали: 3 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 8.7.2009, 22:53) *
как так? картинка-то поворачивается.

Система координат если абсолютная???
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 9.7.2009, 14:24
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


это дело можно представить себе так:
Есть стол, на нём лист бумаги. когда рисуем штрихи и цифирки, то используются абсолютные координаты стола, а поворот осуществляем только листа, относительно его предыдущего положения.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 10:41