dolphin23
@dolphin23
Новичок в программировании

Нужно добавить масштаб для графика который отрисовывается врчную через QPainter, что посоветуете?

Оговорюсь сразу - я не изобретаю велосипед, мне приходиться самому отрисовывать график так как в этом и состоит задание. Сам график у меня отрисовывается, я пытался добавить некие параметры scale и scaleXY чтобы изменить масштаб графика при прокрутке колесика мыши, но эти попытки не особо удачны. В идеале я хочу не скейлить картинку (как я это делаю сейчас через "painter.scale(scaleXY, scaleXY)"), а именно менять масштаб графика, ну и было бы совсем идеально еще и добавить перемещение по графику при удержании лкм.

Chart
#include "chart.h"
#include "mainwindow.h"

Chart::Chart(long long x0, long long yx0, QWidget *parent) : QWidget(parent), x0(x0), yx0(yx0)
{
    y = 0;
    C = qExp(2*x0)*(2000-(qExp(2*x0)/4)+yx0);
    scale = 20; // масштаб клеток/отрезков
    scaleXY = 1; //масштаб графика

    setMouseTracking(true);

}

void Chart::paintEvent(QPaintEvent*){
    painter.begin(this);
    if(scaleXY <1) scaleXY = 1; // задаем минимальную границу масштаба
    painter.scale(scaleXY, scaleXY); 

    painter.setRenderHints(QPainter::Antialiasing, true);
    painter.setBackgroundMode(Qt::OpaqueMode);
    painter.setBackground(Qt::white);

    pen.setColor(Qt::gray);
    pen.setWidth(1);
    painter.setPen(pen);

    for(int i = 0; i < width(); i+=scale){
        painter.drawLine(i, 0, i, height()); //клетки
        painter.drawLine(0, i, width(), i);
    }

    pen.setColor(QColor(220, 20, 60));
    pen.setWidth(3);
    painter.setPen(pen);

    painter.drawLine((width()/2), 0,(width()/2), height()); // ось Y

    QPolygon arrowY;
    arrowY << QPoint(width()/2, 0) << QPoint((width()/2)-20, 20); //левая часть стрелки
    arrowY << QPoint(width()/2, 0) << QPoint((width()/2)+20, 20); //правая часть стрелки
    painter.drawPolygon(arrowY);

    painter.drawLine(0, (height()/2), width(), (height()/2)); // ось X

    QPolygon arrowX;
    arrowX << QPoint(width(), height()/2) << QPoint((width())-20, (height()/2)-20); //верхняя часть стрелки
    arrowX << QPoint(width(), height()/2) << QPoint((width())-20,(height()/2)+20); //нижняя часть стрелки
    painter.drawPolygon(arrowX);

    for(int i = 0; i < width(); i+=scale){
        painter.drawLine(i, (height()/2)-5, i, (height()/2)+5); // отрезки слева направо
    }

    for(int i = 0; i < height(); i+=scale){
        painter.drawLine((width()/2)-5, i, (width()/2)+5, i); // отрезки сверху вниз
    }

    pen.setColor(QColor(0, 128, 128));
    pen.setWidth(4);
    painter.setPen(pen);

   for(float x = -100; x <= 100; x+=0.001){
        y = ((qExp(2*x)/4) + (C/qExp(2*x)) - 2000)/1000; 
        painter.drawPoint(QPoint(((width()/2)+x), ((height()/2)-y))); // здесь отрисовка самого графика
    }
    painter.end();
}

void Chart::wheelEvent(QWheelEvent* e){
    if(e->angleDelta().y() > 0){
        scale+= 1;
        scaleXY+=0.1;
        update();
    }
    else if(e->angleDelta().y() < 0){
        scale-= 1;
        scaleXY-=0.1;
        update();
    }
}

void Chart::mouseMoveEvent(QMouseEvent *e){
    bool leftClick = e->buttons() & Qt::LeftButton;
    if(leftClick){
        mousePoint = e->pos();
        update();
    }
}


Mainwindow
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    resize(825, 800);
    setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);

    line_x0 = new QLineEdit(this); // x0
    line_yx0 = new QLineEdit(this); // y(x0)

    btnDraw = new QPushButton("Отрисовать график", this);

    lbl1 = new QLabel("y (");
    lbl2 = new QLabel(") = ");

    layoutMain = new QVBoxLayout(this);
    layoutInput = new QHBoxLayout;
    layoutChart = new QHBoxLayout;

    layoutInput->addWidget(lbl1);
    layoutInput->addWidget(line_x0);
    layoutInput->addWidget(lbl2);
    layoutInput->addWidget(line_yx0);
    layoutInput->addWidget(btnDraw);

    layoutMain->addLayout(layoutInput);
    layoutMain->addSpacing(100);

    connect(btnDraw, SIGNAL(clicked()), this, SLOT(drawChart()));
}

MainWindow::~MainWindow()
{
}

void MainWindow::drawChart(){
    Chart* chart = new Chart(line_x0->text().toFloat(), line_yx0->text().toFloat(), this);
    layoutChart->addWidget(chart);
    layoutMain->addLayout(layoutChart);
    chart->update();
}
  • Вопрос задан
  • 121 просмотр
Пригласить эксперта
Ответы на вопрос 1
PavelK
@PavelK
Приветствую.
Может стоит просто домножать значение по X и Y на некоторый коэффициент N, в зависимости от маштаба?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы