Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.01.2011, 18:12   #1
lecume
Пользователь
 
Аватар для lecume
 
Регистрация: 17.12.2009
Сообщений: 11
Лампочка Система координат в Qt

Здравствуйте!
Не подскажете, как лучше отрисовать двухмерную систему координат в QGraphicsView? Оси (x, y) и сеточка.

Последний раз редактировалось lecume; 12.01.2011 в 18:27.
lecume вне форума Ответить с цитированием
Старый 20.01.2011, 10:06   #2
Obey-Kun
Линуксоид
Участник клуба
 
Аватар для Obey-Kun
 
Регистрация: 31.07.2009
Сообщений: 1,403
По умолчанию

Рисование надо делать в drawForeground и drawBackground. Там всё рисование идёт в координатах сцены (!), что естественно упомянуто в документации.

Из моего проекта. Подразумевается, что бэкграунд чёрный (просто сделайте setBackgroundBrush(QColor(Qt::black )) в конструкторе)
Оси:
Код:
void View::drawAxes(QPainter *painter, const QRectF &rect)
{
    Q_UNUSED(rect)
    
    QVector<QLineF> axe_lines;
    axe_lines << QLineF(-60, 0, 60, 0)                //x axe
              << QLineF(0, -60, 0, 60);               //y axe
    QVector<QLineF> cosmetic_lines;
    cosmetic_lines
            << QLineF(60 - 12, 0 - 4, 60, 0)        //x arrow
            << QLineF(60 - 12, 0 + 4, 60, 0)
            << QLineF(60 + 20 - 5, 0 - 8, 60 + 20 + 5, 0 + 8)      //"x"
            << QLineF(60 + 20 + 5, 0 - 8, 60 + 20 - 5, 0 + 8)
            
            << QLineF(0 - 4, 60 - 12, 0, 60)        //y arrow
            << QLineF(0 + 4, 60 - 12, 0, 60)
            << QLineF(0, 60 + 20, 0 - 5, 60 + 20 - 8)          //"y"
            << QLineF(0, 60 + 20, 0 + 5, 60 + 20 - 8)
            << QLineF(0, 60 + 20, 0, 60 + 20 + 8);
    //FIXME: рисовать arrows полилиниями
    QPen pen;
    pen.setColor(QColor(255, 255, 255, 100));
    pen.setWidth(3);
    painter->setPen(pen);
    QTransform oldTransform(painter->transform());
    painter->setTransform(QTransform(1, 0, 0, 1, oldTransform.dx(), oldTransform.dy()));
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->drawLines(cosmetic_lines);
    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->drawLines(axe_lines);
    
    pen.setColor(Qt::black);
    pen.setColor(QColor(0, 0, 0, 255));
    pen.setWidth(0);
    painter->setPen(pen);
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->drawLines(cosmetic_lines);
    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->drawLines(axe_lines);

    painter->setTransform(oldTransform);
}
Причём благодаря колдовству в painter->setTransform оси рисуются вне масштаба, то есть будут выглядеть одинаково при любом масштабе. Если ты не знал, m11() соответствует масштабу. Больше можешь прочитать в QTransform.

Сеточка (у меня это не сетка, а точки в узлах сетки, как в автокаде):
Код:
void View::drawGrid(QPainter *painter, const QRectF &rect)
{
    // находим границы для рисования (через rect с запасом)
    int x1 = m_grid_span * int(std::floor(rect.left()  / m_grid_span));
    int y1 = m_grid_span * int(std::floor(rect.top()   / m_grid_span));
    int x2 = m_grid_span * int(std::ceil(rect.right()  / m_grid_span));
    int y2 = m_grid_span * int(std::ceil(rect.bottom() / m_grid_span));
    
    // заполняем массивы точек
    QVector<QPoint> tenth_points;
    QVector<QPoint> other_points;
    for(int x = x1; x < x2; x += m_grid_span) {
        for(int y = y1; y < y2; y += m_grid_span) {
            if(x % (10 * m_grid_span) == 0 || y % (10 * m_grid_span) == 0) {
                tenth_points << QPoint(x, y);
            } else {
                other_points << QPoint(x, y);
            }
        }
    }
    
    // рисуем точки
    painter->setPen(QColor(Qt::white)); //black для белой сцены
    painter->drawPoints(tenth_points);
    painter->setPen(QColor(Qt::darkGray));  //gray для белой сцены
    painter->drawPoints(other_points);
}
Где m_grid_span — шаг сетки в пикселах в координатах вью. Он у меня динамически изменяется при масштабировании. У себя попробуй 10 для начала.

Применяется вот так:
Код:
void View::drawBackground(QPainter *painter, const QRectF &rect)
{
    //дефолтный метод заполняет всё backgroundBrush
    QGraphicsView::drawBackground(painter, rect);
    
    drawGrid(painter, rect);
}

void View::drawForeground(QPainter *painter, const QRectF &rect)
{
    drawAxes(painter, rect);
}
Результат:

P.S. если у тебя будет масштабирование, то лучше изменять шаг сетки динамически. Он должен быть кратен 10, ессно. Вот так у меня сделано (вызывать после масштабирования):
Код:
void View::setGridSpan()
{
    /**
     * Коэффициент, влияющий на максимальную "скученность" (количество на
     * единицу длины вида) точек сетки.
     * Чем он меньше, тем они могут быть скученней.
     */
    static const double max_grid_density = 6.5;
    m_grid_span = 10;
    int i = 1;
    while(transform().m11() * 10 * i < max_grid_density) {
        m_grid_span *= 10;
        i *= QFrost::unitsInGridStep;
    }
}
Я схожу с ума или это глючит реальность?
Jabber ID: obey@obey.su

Последний раз редактировалось Obey-Kun; 20.01.2011 в 10:51.
Obey-Kun вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Система координат (JavaScript) IliaGT Помощь студентам 1 04.05.2010 17:03
Система координат устройств AJlxuMuk Win Api 1 08.10.2009 22:19
Система координат в OpenGl. Вадим Буренков Gamedev - cоздание игр: Unity, OpenGL, DirectX 14 02.06.2009 09:12
квадрат и система координат=) kolduev Помощь студентам 8 11.03.2008 19:11
Система координат SunKnight Общие вопросы Delphi 2 05.02.2008 19:42