Russian Qt Forum
Сентябрь 30, 2024, 16:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: y = cos (x)  (Прочитано 7264 раз)
ann-joker
Гость
« : Май 20, 2012, 07:32 »

задание: нарисовать косинусоиду.
пытаюсь сделать таким образом, но ничего не отображается.
x, y - double;
prevX, prevY, curX, curY - int.

Код:
#include "mainwindow.h"
#include <cmath>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    widget=new QWidget;
    QVBoxLayout *vb=new QVBoxLayout;
    widget->setLayout(vb);
    widget->setStyleSheet("background-color::white");
    this->setCentralWidget(widget);
    this->setFixedSize(500,500);
    x = (- (3 * 3.14)) + 100;
    y = cos (x) + 100;

}

MainWindow::~MainWindow()
{

}


void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter *painter = new QPainter(this);
    QPen pen(QColor(Qt::darkGreen));

    painter->drawPixmap(this->width(), this->height(), QPixmap());
    pen.setWidth(2);
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->setPen(pen);
    painter->setBrush(Qt::darkGreen);

    while (x < 3 * 3.14 + 100){

        prevX = x;
        prevY = y;

        x = x + 1;
        y = cos(x);

        curX = x;
        curY = y;
       
        painter->drawLine(prevX, prevY, curX, curY);
    }
    this->update();
}

Записан
ann-joker
Гость
« Ответ #1 : Май 20, 2012, 07:39 »

и как еще в MessageBox'е вывести точки соприкосновения с осью абсцисс?
как найти - знаю, а как в бокс записать эти числа?
Записан
V1KT0P
Гость
« Ответ #2 : Май 20, 2012, 11:18 »

и как еще в MessageBox'е вывести точки соприкосновения с осью абсцисс?
как найти - знаю, а как в бокс записать эти числа?
Незнание программирования, незнание геометрии...
Вот твой адаптированный код:
Код
C++ (Qt)
void MainWindow::on_pushButton_clicked()
{
   QPixmap pix(500, 500);
   QPainter painter(&pix);
   QPen pen(QColor(Qt::darkGreen));
 
   painter.fillRect(QRect(0, 0, 500, 500), Qt::white);
   pen.setWidth(2);
   painter.setRenderHint(QPainter::Antialiasing, true);
   painter.setPen(pen);
   painter.setBrush(Qt::darkGreen);
   double prevX = 0/180.0*M_PI;
   double prevY = cos(prevX)*10+100;
   double curX;
   double curY;
   for (double i=1; i<720; i+=1) {
       curX = i/180.0*M_PI;
       curY = cos(curX);
 
       painter.drawLine(prevX, prevY, i, curY*10+100);
       prevX = i;
       prevY = curY*10+100;
   }
   ui->label->setPixmap(pix);
}
В аттаче картинка.
Это ты что лабу делаешь?
Записан
ann-joker
Гость
« Ответ #3 : Май 20, 2012, 11:24 »


уоу. спасибо!

да, видимо, геометрия вообще страдает.. а программирование учу, как могу.
можете объяснить, почему так?
только без упреков, если можно..
Записан
V1KT0P
Гость
« Ответ #4 : Май 20, 2012, 11:40 »

уоу. спасибо!

да, видимо, геометрия вообще страдает.. а программирование учу, как могу.
можете объяснить, почему так?
только без упреков, если можно..
1) Ты через-жопно начал строить график на форме, это плохо. Я для примера привел как в картинку нарисовать и ее отобразить в QLabel.
2) Попробуй посчитать минимальные и максимальные значения получаемых x и y в твоем примере. x: от 90.58 до 109.42, y: от -1 до 1. Вот и получается фигня шириной 20 пикселей и высотой 3 пикселя, при чем видна будет полоска высотой 2 пикселя(Там где положительное y).
3) paintEvent срабатывает каждый раз при необходимости отрисовки, а у тебя после первой отрисовки значение x не сбрасывается к изначальному. Поэтому после второго срабатывания paintEvent уже не отрисовывает твой график и тебе кажется что функция не работает.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Май 20, 2012, 12:22 »

Вот твой адаптированный код:
Конечно для лабы "более чем достаточно", но вбивание 10, 100, 720 все-таки не есть хорошо  Улыбающийся
И было бы интересно написать ф-цию которая рисует любой график принимая функтор в качестве одного из аргументов  (такие штучки любит m_ax)
Записан
V1KT0P
Гость
« Ответ #6 : Май 20, 2012, 12:28 »

Вот твой адаптированный код:
Конечно для лабы "более чем достаточно", но вбивание 10, 100, 720 все-таки не есть хорошо  Улыбающийся
И было бы интересно написать ф-цию которая рисует любой график принимая функтор в качестве одного из аргументов  (такие штучки любит m_ax)
Я же для примера привел. Да легко можно сделать так что график рисовался по формуле введенной пользователем, но моя цель была только указать на ошибки а не реализовывать полный функционал =).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Май 20, 2012, 12:34 »

Я же для примера привел. Да легко можно сделать так что график рисовался по формуле введенной пользователем, но моя цель была только указать на ошибки а не реализовывать полный функционал =).
Все мы немного умеем читать между строк, интересно было бы составить "словарь", напр

выражение                значение
----------------------------------
"да легко.."                сразу в кусты
"меня улыбнуло"        человек разярен
"учи матчасть"            да хз как

и.т.д.  Улыбающийся
Записан
V1KT0P
Гость
« Ответ #8 : Май 20, 2012, 12:44 »

"да легко.."                сразу в кусты
Хочешь поспорить что я легко смогу реализовать такой функционал? Например в случае выигрыша ты должен будешь написать кукую-нибудь программу на Qt без сторонних библиотек. Какую я выберу сам =). Хочешь поспорить?
Там реально просто:
1) Парсинг функции в древовидный вид.
2) Преобразовывание древовидного вида что-нибудь попроще, например в QScript. Либо же написать функцию которая сама будет по дереву вычислять(тут скорость побольше будет).
3) Ну и отрисовка графика на плоскости.

У меня алгоритм как это сделать уже полтора года в голове крутится. Все никак времени не найду реализовать.
Я просто хочу себе сделать продвинутый калькулятор(именно как я это вижу, ибо те что видел меня бесят просто) на Android телефон =).
Записан
iroln
Гость
« Ответ #9 : Май 20, 2012, 13:28 »

У меня алгоритм как это сделать уже полтора года в голове крутится. Все никак времени не найду реализовать.
Я просто хочу себе сделать продвинутый калькулятор(именно как я это вижу, ибо те что видел меня бесят просто) на Android телефон =).
Алгоритм "как это сделать" можно в каком-нибудь open-source проекте посмотреть, наверняка кто-нибудь уже сделал хорошую реализацию. Те же gnuplot, matplotlib.mathtext.Parser.

Я python + IPython использую в качестве продвинутого калькулятора. Правда не знаю, портированы ли всякие matplotlib и numpy на андройд, но интерпретатор питона там точно есть. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Май 20, 2012, 13:32 »

Хочешь поспорить что я легко смогу =).
..
Хочешь поспорить?
Да не хочу я с Вами спорить Улыбающийся Просто это интересно. Ну вот допустим понадобился тангенс вместо косинуса, или синус или др. Что изменится в Вашем коде? Почти ничего кроме вызова самой расчетной ф-ции. Нехорошо делать N копий кода если оно явно обобщается

Там реально просто:
1) Парсинг функции в древовидный вид.
Наверное все-таки "парсинг строки" (введенной пользователем). И задача звучит как "мини-интерпретатор". Неск раз у меня подобные потребности возникали, и ничего путного я не нашел, реализовывал сам. По существу дело сводится к разбору строки "токен за токеном". Обсуждать это здесь я пытался, но без успеха, свелось к тому что я не знаю RegExp, должен/обязан его учить и.т.п.  Улыбающийся
Записан
iroln
Гость
« Ответ #11 : Май 20, 2012, 13:35 »

Вот статья в тему: http://habrahabr.ru/post/50158/

На счёт "реально просто", я стараюсь избегать таких выражений, потому что везде есть свои подводные камни и обычное "реально просто" может оказаться совсем не просто.
Записан
V1KT0P
Гость
« Ответ #12 : Май 20, 2012, 13:57 »

Да не хочу я с Вами спорить Улыбающийся Просто это интересно. Ну вот допустим понадобился тангенс вместо косинуса, или синус или др. Что изменится в Вашем коде? Почти ничего кроме вызова самой расчетной ф-ции. Нехорошо делать N копий кода если оно явно обобщается
Где я говорил про копии кода?

Наверное все-таки "парсинг строки" (введенной пользователем). И задача звучит как "мини-интерпретатор". Неск раз у меня подобные потребности возникали, и ничего путного я не нашел, реализовывал сам. По существу дело сводится к разбору строки "токен за токеном". Обсуждать это здесь я пытался, но без успеха, свелось к тому что я не знаю RegExp, должен/обязан его учить и.т.п.  Улыбающийся
Правильно, я решил что мини-интерпрератор будит рулить по скорости. Вообще он там банальный:
1) Парсинг реализуется просто в древовидную структуру.
2) Вычисление структуры начинается он низа дерева к верху, то-есть на каждом этапе имеем два числа и одну операцию. Сразу скажу что если например интеграл не интегрируется, то он преобразовывается во вложенное дерево. Это позволит не усложняя алгоритма численно интегрировать интегралы.
3) Собственно построение графика, тоже ничего сложного. Можно даже сделать так, чтоб алгоритм просчитывал точки без разрывов(скорее все такой алгоритм уже создан).

На счёт "реально просто", я стараюсь избегать таких выражений, потому что везде есть свои подводные камни и обычное "реально просто" может оказаться совсем не просто.
Там где я не уверен в простоте реализации я такого и не говорю. Тут же все довольно просто, да времени на реализацию уйдет много. Но то что для реализации требуется много времени не делает ее сложной, просто кода многовато надо будет написать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 20, 2012, 14:16 »

1) Парсинг реализуется просто в древовидную структуру.
2) Вычисление структуры начинается он низа дерева к верху, то-есть на каждом этапе имеем два числа и одну операцию.
Так часто пишут, но у меня почему-то получалось все наоборот Улыбающийся Примерно так

5 + sin(0.5 + cos(1.0)) * 4  // исходная строка, преобразуем ее в контейнер выражений


+
sin(0.5 + cos(1.0))  // это вложенный контейнер выражений { sin,  "0.5 + cos(1.0)" }
*


В контейнере находим операцию с наивысшим приоритетом, здесь это *. Разматываем операнды и.т.д до победного конца
Записан
daimon
Гость
« Ответ #14 : Май 21, 2012, 09:26 »

вот парсер хороший
http://svn.code.sf.net/p/phyxcalc/code/trunk
но он требует boost 1.47, qwt6.0
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.104 секунд. Запросов: 23.