crossplatform.ru

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

> Масштабирование с помощью колесика мышки, ?
AD
  опции профиля:
сообщение 28.5.2008, 10:43
Сообщение #1


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

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

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




Репутация:   17  


На данный момент масштабирование графика реализовано также, как и в книжке Саммерфилда и Бланшета. Смысл метода заключается в том, что сохраняется предыдущий масштаб и идет при прокрутке колесика мышки на него. Меня не устраивает такая интерпретация изменения масштаба, хочется сделать обычную!. То есть, чтобы масштаб изменялся гладко и правильно.
Помогите, пожалуйста! Подскажите, пожалуйста, методы решения данной проблемы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Red Devil
  опции профиля:
сообщение 30.6.2008, 11:16
Сообщение #2


Студент
*

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

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




Репутация:   3  


Нарисуй все на бумаге, напиши формулы, выложи их здесь. Я именно так и делал, когда решал аналогичную задачу, но с использованием другой библиотеки.
Исходный код тут не поможет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 9.7.2008, 15:40
Сообщение #3


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

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

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




Репутация:   17  


Вот так вот :) Искал пример использования двоичных файлов, а натолкнулся на пример, который может помочь решить проблему масштабироваиия! :)
%QTDIR%examples\threads\mandelbrot
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 11.7.2008, 11:50
Сообщение #4


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

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

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




Репутация:   17  


Век живи, век учись! Вот так выглядит код, который заставляет правильно работать масштабирование: :)
class PlotSettings
{
public:
    double minX;
    double maxX;
    int numXTicks;
    double minY;
    double maxY;
    int numYTicks;

protected:
    static void adjustAxis(double& min, double& max, int& numTicks);

public:
    PlotSettings();
    void scroll(int dx, int dy);
    void scale(double delta_x, double delta_y);
    void adjust();
    double spanX() const { return fabs(maxX - minX); }
    double spanY() const { return fabs(maxY - minY); }
};


/// Увеличение/уменьшение значения minX, maxX, minY, maxY на интервал между 2-мя отметками
void PlotSettings::scale(double delta_x, double delta_y)
{
    if((minX == maxX || minY == maxY) && delta_x < 0 && delta_y < 0) return;

    double stepX = spanX() / numXTicks;
    minX -= delta_x * stepX;
    maxX += delta_x * stepX;

    double stepY = spanY() / numYTicks;
    minY -= delta_y * stepY;
    maxY += delta_y * stepY;
}



/// Класс для отображения параметров по времени или по расстоянию
class GraphicDisplay : public QDialog, public Ui::GraphicDisplayClass
{
    Q_OBJECT

private:
    QMap<int, QVector<QPointF>> curveMap;       ///< список всех изображаемых кривых
    ParamPlotSettings settings;                    ///< настройка для определения масштаба
    QRubberBand* rubber;                        ///< "резиновая лента"
    QPoint origin;                                ///< начальные координаты выделяемой области
    bool rubberBandIsShown;                        ///< флажок попадания курсора в "резиновую ленту"
    QPen myPen;                                    ///< карандаш для рисования линий определенной жирности и цвета
    enum { MARGIN = 10 };

    QPainter painter;                            ///< рисовальщик
    QVector<QPointF> data;                        ///< вектор загружаемой кривой

private:
    void drawGrid(QPainter* painter);
    void drawCurves(QPainter* painter);
    void drawLegend(QPainter* painter, QRect& rect, int& k, int id);
    QPointF initXY(double& sx, double& sy);

protected:
    void paintEvent(QPaintEvent* events);
    void keyPressEvent(QKeyEvent* events);
    void wheelEvent(QWheelEvent* events);
    void mousePressEvent(QMouseEvent* events);
    void mouseMoveEvent(QMouseEvent* events);
    void mouseReleaseEvent(QMouseEvent* events);
    void resizeEvent(QResizeEvent* events) { QDialog::resizeEvent(events); update(); }
    void closeEvent(QCloseEvent* events) { QDialog::closeEvent(events); }
    void showEvent(QShowEvent* events) { QDialog::showEvent(events); }

public:
    GraphicDisplay(QWidget *parent = 0);
    GraphicDisplay(QWidget *parent, ParamPlotSettings& st);
    ~GraphicDisplay();
    void zoom(double delta) { settings.scale(delta, delta); settings.adjust(); update(); }
    void setPlotSettings(const ParamPlotSettings& sts) { settings = sts; settings.adjust(); update(); }


/// Изменение масштаба при движении колесика
void GraphicDisplay::wheelEvent(QWheelEvent* events)
{
    int numDegrees = events -> delta() / 8;
    double numTicks = numDegrees / 15.0;

    zoom(numTicks);
    update();
}

/// Нажатие на кнопки клавиатуры
void GraphicDisplay::keyPressEvent(QKeyEvent* events)
{
    switch(events -> key())
    {
    case Qt::Key_Plus:
        zoom(1.0);
    break;
    case Qt::Key_Minus:
        zoom(-1.0);
    break;
    case Qt::Key_Left:
        settings.scroll(-1, 0);
        update();
    break;
    case Qt::Key_Right:
        settings.scroll(1, 0);
        update();
    break;
    case Qt::Key_Up:
        settings.scroll(0, 1);
        update();
    break;
    case Qt::Key_Down:
        settings.scroll(0, -1);
        update();
    break;
    default:
        QWidget::keyPressEvent(events);
    }
}

/// Отрисовка сетки
void GraphicDisplay::drawGrid(QPainter* painter)
{
    QRect rect(paramsDisplay -> rect());
    if(!rect.isValid()) return;
    
    QRect boundString;
    int _max = max(settings.numXTicks, settings.numYTicks);
    for(int i=0, j=0, k=0; i<=_max; ++i, ++j, ++k)
    {
        if(j <= settings.numXTicks)                ///< отрисовка по оси X
        {
            int x = rect.left() + (j * (rect.width() - 1) / settings.numXTicks);
            double label = settings.minX + (j * settings.spanX() / settings.numXTicks);
            QString s_label = round(label);

            painter -> setPen(Qt::black);
            painter -> drawLine(x, rect.top(), x, rect.bottom());
            if(j != settings.numXTicks)
            {
                int flags = Qt::AlignHCenter | Qt::AlignTop;
                boundString = painter -> boundingRect(boundString, flags, s_label);
                painter -> drawText(x - (boundString.width() + 5), rect.bottom() - (boundString.height() + 5),
                                    boundString.width(), boundString.height(), flags, s_label);
            }
        }
        if(k <= settings.numYTicks)                ///< отрисовка по оси Y
        {
            int y = rect.bottom() - (k * (rect.height() - 1) / settings.numYTicks);
            double label = settings.minY + (k * settings.spanY() / settings.numYTicks);
            QString s_label = round(label);

            painter -> setPen(Qt::black);
            painter -> drawLine(rect.left(), y, rect.right(), y);
            if(k != settings.numYTicks)
            {
                int flags = Qt::AlignRight | Qt::AlignTop;
                boundString = painter -> boundingRect(boundString, flags, s_label);
                painter -> drawText(rect.left() + 5, y - boundString.height(),
                            boundString.width(), boundString.height(), flags, s_label);
            }
        }
    }
    painter -> drawRect(rect.adjusted(0, 0, -1, -1));
}

/// Отрисовка легенды
void GraphicDisplay::drawLegend(QPainter* painter, QRect& rect, int& k, int id)
{
    QString pname = fact_prm[id].param_name;
    QString dimension = fact_prm[id].dimension;
    myPen.setWidth(1);
    painter -> drawLine(QLineF(QPointF(rect.right()  - 45, rect.top() + 25 * k),
                               QPointF(rect.right()  - 65, rect.top() + 25 * k)));
    painter -> setPen(Qt::black);
    int flags = Qt::AlignCenter;
    QRect boundString = painter -> boundingRect(boundString, flags, pname);
    painter -> drawText(QPointF(rect.right() - (boundString.width() + 7), rect.top() + 25 * k), pname);
    boundString = painter -> boundingRect(boundString, flags, dimension);
    painter -> drawText(QPointF(rect.right() - (boundString.width() + 7),
                        rect.bottom() - 2 * boundString.height()), dimension);
    ++k;
}

/// Инициализация координат
QPointF GraphicDisplay::initXY(double& sx, double& sy)
{
    QRect rect(paramsDisplay -> rect());
    double dx, dy;
    dx = sx - settings.minX;
    dy = sy - settings.minY;
    double x = rect.left() + (dx * (rect.width() - 1) / settings.spanX());;
    double y = rect.bottom() - (dy * (rect.height() - 1) / settings.spanY());

    return QPointF(x, y);
}

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

    painter -> setClipRect(rect.adjusted(1, 1, -1, -1));
    QMapIterator<int, QVector<QPointF>> iter(curveMap);
    int k = 1;
    while(iter.hasNext())
    {
        iter.next();

        int id = iter.key();
        TP_PARAM ty = fact_prm[id].type;
        if(settings.win_type != ty) continue;

        const QVector<QPointF> &data = iter.value();
        QPolygonF polyline(data.count());
        for(int j=0; j<data.count(); ++j)
        {
            double x = data[j].x();
            double y = data[j].y();
            polyline[j] = initXY(x, y);
        }
        QString color = fact_prm[id].param_color.name();
        QPen oldPen = painter -> pen();
        myPen.setColor(fact_prm[id].param_color);
        painter -> setPen(myPen);
        painter -> drawPolyline(polyline);
        int width = myPen.width();
        
        drawLegend(painter, rect, k, id);

        painter -> setPen(oldPen);
    }
}


Практически месяц я парился с этим - но в итоге решение проблемы есть! УРА, уряяяяяяяяяя...
Можете поздравить! :))))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- AD   Масштабирование с помощью колесика мышки   28.5.2008, 10:43
- - ViGOur   Цитата(AD @ 28.5.2008, 11:43) Меня не уст...   28.5.2008, 15:04
|- - AD   Цитата(ViGOur @ 28.5.2008, 16:04) Не совс...   28.5.2008, 15:32
- - Litkevich Yuriy   А в чем трудность, алгоритм вроде не сложный получ...   28.5.2008, 15:48
|- - AD   Цитата(Litkevich Yuriy @ 28.5.2008, 16:48...   29.5.2008, 14:25
- - Litkevich Yuriy   я бы так доработал: void GraphicDisplay::z...   29.5.2008, 15:39
|- - AD   Цитата(Litkevich Yuriy @ 29.5.2008, 16:39...   4.6.2008, 10:31
- - Litkevich Yuriy   Цитата(AD @ 4.6.2008, 14:31) Не понял отл...   4.6.2008, 10:37
|- - AD   Цитата(Litkevich Yuriy @ 4.6.2008, 11:37)...   4.6.2008, 10:50
- - Litkevich Yuriy   а в приведенном тобой коде вообще нет нистрочки о ...   4.6.2008, 10:58
|- - AD   Цитата(Litkevich Yuriy @ 4.6.2008, 11:58)...   4.6.2008, 15:51
|- - AD   Так что других алгоритмов нет? Кто-то может помочь...   9.6.2008, 10:13
- - Red Devil   Ну почему же нет. Берешь размеры изображения (шири...   9.6.2008, 11:07
|- - AD   Я дозрел до правильной формулировки задачи. Мне...   10.6.2008, 17:21
|- - AD   О_о кое какое просветление вот код, выполняющий ...   10.6.2008, 18:23
|- - AD   Блин совсем мозги плавятся от правильного определе...   17.6.2008, 11:09
- - ViGOur   Ты на бумаге попробуй все разрисуй, это помогает, ...   17.6.2008, 11:10
|- - AD   Можно задавать маленькие конкретные вопросы? Возмо...   18.6.2008, 10:12
|- - AD   Это опять я. Короче, проблема пока еще не решена. ...   30.6.2008, 10:22
- - Red Devil   Нарисуй все на бумаге, напиши формулы, выложи их з...   30.6.2008, 11:16
|- - AD   Вот так вот Искал пример использования двоичных ф...   9.7.2008, 15:40
|- - AD   Век живи, век учись! Вот так выглядит код, кот...   11.7.2008, 11:50
- - ViGOur   Молодец, осилил наконец. Упрямства тебе не заним...   11.7.2008, 11:54
|- - AD   Цитата(ViGOur @ 11.7.2008, 12:54) Молодец...   11.7.2008, 12:04
- - ViGOur   Цитата(AD @ 11.7.2008, 13:04) Может упорс...   11.7.2008, 13:06


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


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




RSS Текстовая версия Сейчас: 26.11.2024, 18:45