crossplatform.ru

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

2 страниц V  < 1 2  
Ответить в данную темуНачать новую тему
> Вопрос по функции drawText
kwisp
  опции профиля:
сообщение 31.7.2009, 12:25
Сообщение #11


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

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




Репутация:   23  


AD,
как бы всё для этого есть.
всякие там
QRect QRect::intersected ( const QRect & rectangle ) const
и проч.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 31.7.2009, 18:12
Сообщение #12


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

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

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




Репутация:   94  


Тему разделил: Вращение текста в графическом представлении
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 5.8.2009, 15:00
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

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




Репутация:   17  


Получилось сделать корректное отображение пересечение графика с визиром.
Вот что получилось.

График кривой без сглаживания:
[attachment=725:graphic_...moothing.JPG]

График кривой со сглаживанием:
[attachment=726:graphic_...moothing.JPG]

Выложу код, вдруг, все-таки пригодится кому-нибудь. Если что, смогу и объяснить, где что в коде делается!
Пересечение с визиром

/// Получение размерностей заданной по id кривой
QPointF GraphicDisplay::dimensions(int id)
{
    QString x_dimension(fact_prm[id].dimension[language_flag].toLower());
    double x_dim = (metric_map[x_dimension]) ? metric_map[x_dimension] : 1.0;
    QString y_dimension(fact_prm[id].y_dim[language_flag].toLower());
    double y_dim = (metric_map[y_dimension]) ? metric_map[y_dimension] : 1.0;
    return QPointF(x_dim, y_dim);
}

/// Поиск точки пересечения визира с графиком (в реальных координатах - следует переводить в экранные)
QPointF GraphicDisplay::findCrossPoint(const QPointF& pnt, const QPointF& prev_pnt, const QPointF& pnt_vf)
{
    double    curr_x = pnt.x(), curr_y = pnt.y(), prev_x = prev_pnt.x(), prev_y = prev_pnt.y(), y_vf = pnt_vf.y(),
            x_vf = pnt_vf.x();
    double    y = prev_y + (curr_y - prev_y) * (x_vf - prev_x) / (curr_x - prev_x),
            x = prev_x + (curr_x - prev_x) * (y_vf - prev_y) / (curr_y - prev_y);
    if(curr_y - prev_y == 0.) x = curr_x;
    if(curr_x - prev_x == 0.) y = curr_y;

    return QPointF(x, y);
}

/// Отображение текста точки пересечения визира с графиком
void GraphicDisplay::drawViewfinderText(QPainter* painter, const QPointF& coord, const QPen& pen,
                                        double coordinate)
{
    QBrush oldBrush(pen.color());
    QPen oldPen(pen.color());
    painter -> setBrush(pen.color());
    QColor color((pen.color() == QColor(Qt::blue)) ? Qt::darkGreen : Qt::blue);
    painter -> setPen(color);
    painter -> drawText(coord, QString::number(coordinate));
    painter -> setPen(oldPen);
    painter -> setBrush(oldBrush);
}

/// Отображение координат пересечения с визиром
void GraphicDisplay::viewCoordViewfinder(QPainter* painter, int id, const QVector<SpecPointF>& data, int index)
{
    if(!v_viewfinderAction -> isChecked() && !h_viewfinderAction -> isChecked()) return;
    QPointF dim(dimensions(id));
    double    real_y = data[index].y(), prev_ry = data[index - 1].y(),
            real_x = (settings.win_type != COUNTPARAM) ? data[index].x() * dim.x() : data[index].x(),
            prev_rx = (settings.win_type != COUNTPARAM) ? data[index - 1].x() * dim.x() : data[index - 1].x();
    QPointF pnt(initXY(real_x, real_y)), prev_pnt(initXY(prev_rx, prev_ry)), rl_pnt(real_x, real_y),
            prev_rl_pnt(prev_rx, prev_ry);
    foreach(VFFrame* pf, viewfinderList)
    {
        QPoint screen_pnt_vf(pf -> x(), pf -> y());
        QPointF pnt_vf(initXY(&screen_pnt_vf));
        double prev_x = prev_rl_pnt.x(), prev_y = prev_rl_pnt.y(), curr_x = rl_pnt.x(), curr_y = rl_pnt.y();
        double x_vf = pnt_vf.x(), y_vf = pnt_vf.y();
        QPointF res_point(findCrossPoint(rl_pnt, prev_rl_pnt, pnt_vf));
        double result_x = res_point.x(), result_y = res_point.y();
        QPointF crd_scr(initXY(result_x, result_y));
        if(pf -> frameShape() == QFrame::VLine && v_viewfinderAction -> isChecked() &&
            prev_x <= x_vf && curr_x > x_vf)
        {
            QPointF coord(pf -> x() + 15, crd_scr.y() - 1.);
            drawViewfinderText(painter, coord, painter -> pen(), res_point.y());
        }
        else if(pf -> frameShape() == QFrame::HLine && h_viewfinderAction -> isChecked() &&
            prev_y <= y_vf && curr_y > y_vf)
        {
            QPointF coord(crd_scr.x() - 1., pf -> y() - 15.);
            drawViewfinderText(painter, coord, painter -> pen(), res_point.x());
        }
    }
}

/// Отрисовка графика
void GraphicDisplay::drawCurves(QPainter* painter)
{
    if(!paramsDisplay -> rect().isValid()) return;
    painter -> setClipRect(paramsDisplay -> rect().adjusted(1, 1, -1, -1));

    QMapIterator<int, QVector<SpecPointF>> iter(curveMap);
    int k = 1;
    bool smoothing = valueElement("diagramSmooth", false).toBool();
    while(iter.hasNext())
    {
        iter.next();        int id = iter.key();
        if(fact_prm.size() == 0 || id >= fact_prm.size()) break;
        if(settings.win_type != fact_prm[id].type) continue;
        QPointF dim(dimensions(id));
        setColorPen(painter, id);

        const QVector<SpecPointF>& data = iter.value();
        QPolygonF polyline(0);
        for(int j=0; j<data.size(); ++j)
        {
            if(!isExistPhase(data[j])) continue;

            double x = (settings.win_type != COUNTPARAM) ? data[j].x() * dim.x() : data[j].x();
            double y = data[j].y() * dim.y();
            QPointF pnt(initXY(x, y));
            if(!polyline.isEmpty())
            {
                if(smoothing && pnt.x() <= polyline.last().x()) continue;
                setPenForLine(j);
                painter -> setPen(myPen);
                if(j > 0 && isExistPhase(data[j - 1]))
                    painter -> drawLine(polyline.last(), pnt),
                    viewCoordViewfinder(painter, id, data, j);
                polyline.append(pnt);
            }
            else polyline.append(pnt);
        }
        drawLegend(painter, paramsDisplay -> rect(), k, id);
    }
}



Сообщение отредактировал AD - 5.8.2009, 15:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 18.1.2025, 15:21