Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.77/35: Рейтинг темы: голосов - 35, средняя оценка - 4.77
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638

Нарисовать графики функций

08.07.2023, 04:44. Показов 8750. Ответов 105
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Нужно вывести(нарисовать) графики функций, но пока что не могу разобраться с параметрами, вот функции:
https://www.cyberforum.ru/cgi-bin/latex.cgi?2\ast a\ast \cos (k\ast t)\ast \exp (-n\ast t) \\0.5\ast a \ast \sin  (k \ast t)\ast \exp (-n \ast t)
Для начала, хочется понять, что означают координаты:

a - угол?
k - не знаю, что это. Возможно, это коэффициент, обозначающий принадлежность числа к определённому числовому диапазону...
n - тоже самое.
t - точность или время?

Пояснений к этим параметрам нет, какими должны быть диапазоны заданных значений... Если предположить, что 'a' - это угол, то тут ясно [0, 360], а вот с другими аргументами проблема.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.07.2023, 04:44
Ответы с готовыми решениями:

Нарисовать графики линейных функций
Добрый день. Пришла в голову мысль реализовать программу, которая рисует графики линейных функции - f(x)=kx+b, где k, b - вводятся с...

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

Как нарисовать графики ?
#include <iostream> #include <conio.h> using namespace std; void main() { const int X=4,Y=12; const...

105
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
18.07.2023, 07:51  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Но на графиках у вас ось OY посередине.
Ну да, я так задал изначально, а где ось OY должна быть?! Если нужно могу задать там где нужно, но разве в этом проблема.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Можете привести полный код, чтобы его сразу скомпилировать и проверить?
Могу, но дело то не во всём коде, а в цикле, точнее, в диапазоне цикла, возможно в установке изначальных значений. Но, если так нужно то.
Ex6_22.rar
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
18.07.2023, 09:07
Цитата Сообщение от Liss29 Посмотреть сообщение
а где ось OY должна быть?!
Ну, обычно оси в нуле пересекаются.
Цитата Сообщение от Liss29 Посмотреть сообщение
Но, если так нужно то.
И тут же приводите красивый график с затуханием
Что еще стоит улучшить, так это правильный ноль графика и, возможно, риски отдельных чисел на осях.
Если эта тема вам интересна, а не просто сдать и забыть, то стоит добавить автомасштаб по Y.
А если совсем интересна, могу предложить практическую задачу
которую я решал года три назад: проводится физический эксперимент, в ходе которого записываются какие-то данные (напряжения, температуры, магнитные поля, все что угодно), их надо отобразить на графике. Сложность в том, что данные могут быть как сверхбольшими (1е+5), так и сверхмалыми (1е-9), соответственно график нужно масштабировать. Плюс красиво рисовать сетку и значения. Чтобы физик, который на это смотрит, понимал порядок величин.
https://www.cyberforum.ru/atta... 1591113051
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
18.07.2023, 09:33  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну, обычно оси в нуле пересекаются.
Ну, обычно рисуют Декартову систему координат так, как она у меня нарисована.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что еще стоит улучшить, так это правильный ноль графика
В смысле ось Y перенести к левому краю?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
риски отдельных чисел на осях.
Метки прорисовать? Но какой масштаб...

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Сложность в том, что данные могут быть как сверхбольшими (1е+5), так и сверхмалыми (1е-9), соответственно график нужно масштабировать. Плюс красиво рисовать сетку и значения.
Я такого никогда не делал, попробовать можно, для начал автомасштабирование как это...

По X у меня масштабируется, в принципе можно установить не MM_ISOTROPIC, а MM_ANISOTROPIC тогда масштабирование по оси Y тоже не составит особого труда. А вот как рассчитывать значения для меток, пожалуй, тут нужна помощь.

Не по теме:

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
а не просто сдать и забыть
Мне никому сдавать не нужно.

0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
18.07.2023, 09:59
Цитата Сообщение от Liss29 Посмотреть сообщение
Ну, обычно рисуют Декартову систему координат так, как она у меня нарисована.
В декартовой системе координат ноль находится на пересечении осей.
Цитата Сообщение от Liss29 Посмотреть сообщение
В смысле ось Y перенести к левому краю?
Или начинать рисование из отрицательной области.
Цитата Сообщение от Liss29 Посмотреть сообщение
Метки прорисовать? Но какой масштаб...
Пока у вас размеры графика константные, можно хоть руками вбить. А вот с усложнением начнется веселье.
Цитата Сообщение от Liss29 Посмотреть сообщение
Я такого никогда не делал, попробовать можно
Еще раз. Только если это интересно вам. Задача-то решена, исходный код выложен на github.
Цитата Сообщение от Liss29 Посмотреть сообщение
установить не MM_ISOTROPIC, а MM_ANISOTROPIC
Мне эти константы ни о чем не говорят. Да и вам бы посоветовал уйти от примитивного рисования на winapi в сторону чего-то более современного. OpenGL того же.
Цитата Сообщение от Liss29 Посмотреть сообщение
А вот как рассчитывать значения для меток, пожалуй, тут нужна помощь.
Да, это интересный момент, который у меня тоже не до конца решен.
Идея в том, что количество меток на экране должно быть ограниченным. Если у вас 10000 точек, но область вывода 100х100, придется оставить всего 10 меток, каждые 1000 точек. В простейшем случае, если экран размером WxH, то W/10 точек.
Вот только W может быть не целым числом, тогда ширину графика придется сделать больше, чем его реальный разброс по X. Округлить вверх до ближайшего круглого числа.
Потом промежуточные точки. Я остановился на трех вариантах: риски каждую единицу (или каждый десяток, сотню, ...) 0, 1, 2, 3, 4,... Потом риски каждые две единицы: 0, 2, 4, 8. Потом каждые 5 единиц: 0, 5. Выбирается по масштабу.
Отдельное развлечение если все точки лежат далеко от нуля. Скажем, от 100500,0 до 100500,4.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
19.07.2023, 05:46  [ТС]

Не по теме:

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В декартовой системе координат ноль находится на пересечении осей.
Я в курсе, уж это точно знаю;)



Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Или начинать рисование из отрицательной области.
Так и делал. Так как у меня точка [0,0] находится в середине окна.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Пока у вас размеры графика константные, можно хоть руками вбить. А вот с усложнением начнется весель
Для меня и это не очень просто т.к. никогда такого не делал, сам не делал.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Еще раз. Только если это интересно вам.
Почему бы и нет, в конце концов, это может понадобиться. Попробую, в лоб же не дадут за это.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Мне эти константы ни о чем не говорят. Да и вам бы посоветовал уйти от примитивного рисования на winapi в сторону чего-то более современного. OpenGL того же.
Мне бы с GDI до конца разобраться меня на данный момент это устраивает я ничего сверхсложного не рисую, и сейчас речь не о библиотеках GUI или инструментарии для рисования, там тоже придётся заниматься вычислениями для отрисовки графика, осей, меток на этом графике и.т.д так что ориентируюсь на это на данный момент.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если у вас 10000 точек, но область вывода 100х100, придется оставить всего 10 меток, каждые 1000 точек. В простейшем случае, если экран размером WxH, то W/10 точек.
Но как обозначить этот факт, что промежуток между метками 1000 точек(единиц), скажем, первая метка 2000, вторая 4000, а между ними сколько засечек оставлять пять каждая по 500 единиц...
Тогда получается 10 меток должны отражать как положительные величины так и отрицательные т.е. пять в положительном направлении и 5 в отрицательном, это я про ось Y.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В простейшем случае, если экран размером WxH, то W/10 точек.
Экран или рабочая область окна?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Я остановился на трех вариантах: риски каждую единицу (или каждый десяток, сотню, ...) 0, 1, 2, 3, 4,... Потом риски каждые две единицы: 0, 2, 4, 8. Потом каждые 5 единиц: 0, 5. Выбирается по масштабу.
Если честно, то не понял этот момент, можно его как-то прояснить?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Отдельное развлечение если все точки лежат далеко от нуля. Скажем, от 100500,0 до 100500,4.
Короче говоря достигают некоего максимума или минимума...
0
Заблокирован
19.07.2023, 06:12
чекбокс - "[0;0] не обязана быть на графике"
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
19.07.2023, 09:35
Цитата Сообщение от Liss29 Посмотреть сообщение
Так и делал. Так как у меня точка [0,0] находится в середине окна.
То есть раньше считали от 0 до T, а теперь... от -T до T что ли?
Цитата Сообщение от Liss29 Посмотреть сообщение
Но как обозначить этот факт, что промежуток между метками 1000 точек(единиц), скажем, первая метка 2000, вторая 4000, а между ними сколько засечек оставлять пять каждая по 500 единиц...
Тогда получается 10 меток должны отражать как положительные величины так и отрицательные т.е. пять в положительном направлении и 5 в отрицательном, это я про ось Y.
Не понял.
Если вы про то, сколько засечек на осях ставить, это только экспериментально. Какой вариант покажется достаточно читаемым, чтобы числа друг на друга не наползали. Ну в смысле сначала для фиксированного размера графика подберете экспериментально, а потом можно будет изобретать алгоритм масштабирования.
Цитата Сообщение от Liss29 Посмотреть сообщение
Экран или рабочая область окна?
Область построения графика, естественно.
Цитата Сообщение от Liss29 Посмотреть сообщение
Если честно, то не понял этот момент, можно его как-то прояснить?
Ну смотрите, если у вас функция меняется от 0 до 1, можно нарисовать на оси 10 меток: 0,0; ,1; 0,2; 0,3; 0,4; 0,5; 0,6; 0,7; 0,8; 0,9; 1,0. Допустим, на графике это смотрится красиво, метки не слипаются.
Но потом мы хотим построить функцию от 0 до 2. Если продолжать ставить метки с шагом 0,1, их получится уже 20 штук. При том же размере поля для рисования мы уже получим месиво. Поэтому стоит сделать шаг 0.2, и меток снова будет 10.
А потом от 0 до 3. И вот тут делать шаг по 0.3 уже плохая идея, потому что метки будут 0,0; 0,3; 0,6; 0,9; 1,2; 1,5; 1,8; 2,1; 2,4; 2,7; 3,0. То есть метки 1.0 и 2.0 вообще не нарисуются, а это неудобно. Поэтому можно сделать шаг 0,5 и получить метки 0,0; 0,5; 1,0; 1,5; 2,0; 2,5; 3,0, что уже удобно для чтения человеком.
А поскольку система счисления у нас десятичная, то промежуток между 0 и 10 мы можем разделить только на 1, 2, 5 и 10. Если сильно хочется, можно добавить еще промежуточную сетку вроде 0; 0,25; 0,5; 0,75; 1.
---
Если хотите, можете посмотреть как это у меня получилось.
Цитата Сообщение от Liss29 Посмотреть сообщение
Короче говоря достигают некоего максимума или минимума...
Нет, я имел в виду, что ноль на график не попадает.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
20.07.2023, 06:58  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
То есть раньше считали от 0 до T, а теперь... от -T до T что ли?
Я изначально установил начало координат рабочей области на центр. SetMapMode(); ... SetViewportOrgEx().

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если вы про то, сколько засечек на осях ставить, это только экспериментально.
Ну как-то я сделал, но, что будет, если окно масштабировать вся конструкция посыплется. Я всё же думал, что есть более универсальные способы.

У меня вот какая поделка получилась.


Нужно что-то вывести в качестве числовых значений, только что из четырёх параметров выводить...
Вместо X и Y нужно подставить какие то поясняющие величины, допустим, по X время t, а по Y, видимо, значение N...
А если предположить, что значения будут очень большие или очень маленькие, то тут нужно корректировать график динамически так что бы было читаемо цифровые значения не налезали на график или не уходили за границы окна, но как-то ничего стоящего в голову не идёт из того, что можно применять в данном случае.
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
20.07.2023, 11:33
Цитата Сообщение от Liss29 Посмотреть сообщение
Я изначально установил начало координат рабочей области на центр. SetMapMode(); ... SetViewportOrgEx().
Я не знаю и знать не хочу что это за функции. Это тонкости реализации на том инструменте, что вы выбрали, они не должны мешать получить правильный график.
Цитата Сообщение от Liss29 Посмотреть сообщение
У меня вот какая поделка получилась.
А чего они теперь ось OX не пересекают?
Цитата Сообщение от Liss29 Посмотреть сообщение
Ну как-то я сделал, но, что будет, если окно масштабировать вся конструкция посыплется. Я всё же думал, что есть более универсальные способы.
Что может быть универсальнее ручного масштабирования?
Допустим, у вас функция меняется от -3 до 8 по Х и от 25 до 25.1 по Y, а размеры области графика 600х400 (чтобы влезло в "стандартный экран" 640х480). Значит, чтобы пересчитать X графика в координату пикселя, надо x = (X+3)/(8-3)*600. Аналогично для Y: y = (Y-25)/(25.1-25)*400.
Какая-нибудь OpenGL умеет масштабировать и сама (в моем примере это, кстати было), но даже там вам придется рисовать оси, рисовать отметки на них, чиселки и т.д., что все равно потребует пересчета.
Цитата Сообщение от Liss29 Посмотреть сообщение
Нужно что-то вывести в качестве числовых значений, только что из четырёх параметров выводить...
Ну по X у вас, очевидно, t, его значения и рисовать в отметках оси. А по Y не менее очевидно, значение функции. Вы же от балды оси градуировали?!
Цитата Сообщение от Liss29 Посмотреть сообщение
Вместо X и Y нужно подставить какие то поясняющие величины, допустим, по X время t, а по Y, видимо, значение N...
Это как раз не обязательно. В существующих графикопостроителях подписи осей задаются вручную. Вдруг вы, скажем, размерность указать захотите, а программе-то откуда знать что за чиселки ей подсунули.
Впрочем, само по себе это тоже интересное упражнение: принять от пользователя строку и нарисовать ее на экране, чтобы и подстрочные индексы были, и надстрочные, и буквы латинские, русские, греческие. Ну мало ли, я пытаюсь удельное сопротивление измерить ρ, Ом*м/мм².
Цитата Сообщение от Liss29 Посмотреть сообщение
А если предположить, что значения будут очень большие или очень маленькие, то тут нужно корректировать график динамически так что бы было читаемо цифровые значения не налезали на график или не уходили за границы окна
Да! Вот это самое интересное.
Цитата Сообщение от Liss29 Посмотреть сообщение
как-то ничего стоящего в голову не идёт из того, что можно применять в данном случае.
Ну так давайте пойдем от простого к сложному. Просто автомасштабирование графика, без отметок на осях, вы сделать можете?
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
20.07.2023, 13:32
Тут и думать нечего. Достаточно умножить каждую точку графика на матрицу масштабирования.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
21.07.2023, 10:29  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А чего они теперь ось OX не пересекают?
Ну, как заказывали, первоначальный график не нравился....

Не по теме:

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что может быть универсальнее ручного масштабирования?
Автоматическое масштабирование, когда всё работает, как Швейцарские часы часы, не важно что за график, как ты меняешь окно в котором этот график прорисовывается.:)



Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Допустим, у вас функция меняется от -3 до 8 по Х и от 25 до 25.1 по Y, а размеры области графика 600х400 (чтобы влезло в "стандартный экран" 640х480). Значит, чтобы пересчитать X графика в координату пикселя, надо x = (X+3)/(8-3)*600. Аналогично для Y: y = (Y-25)/(25.1-25)*400.
Т.е. X, Y - это прежние длины осей, которую нужно пересчитать, так? (X+3), (Y-25) - это опечатка?
Ну вот, какие то формулы уже появились, осталось только разобраться.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну по X у вас, очевидно, t, его значения и рисовать в отметках оси. А по Y не менее очевидно, значение функции. Вы же от балды оси градуировали?!
Я бы не сказал, что очевидно, если было бы очевидно не стал бы задавать подобные вопросы.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В существующих графикопостроителях подписи осей задаются вручную. Вдруг вы, скажем, размерность указать захотите, а программе-то откуда знать что за чиселки ей подсунули.
Параметром передавать в функцию, в простейшем случае можно указать X, Y.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Да! Вот это самое интересное.
Т.е. это нетривиальная задача, если ответа нет.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Просто автомасштабирование графика, без отметок на осях, вы сделать можете?
Как ни странно ничего пока не получается, пока что создал обычное окно куда перенёс отрисовку графика(осей, без меток) при увеличении окна ось X как бы ломается, а, если окно уменьшаю, то график уходит за границу окна Решаю.
0
Заблокирован
21.07.2023, 10:49
Цитата Сообщение от Liss29 Посмотреть сообщение
Я бы не сказал, что очевидно,
что же тогда откладывается по горизонту? и какой у "этого" диапазон на последнем скрине?
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
21.07.2023, 11:12
Цитата Сообщение от Liss29 Посмотреть сообщение
Ну, как заказывали, первоначальный график не нравился....
И вы пытались угадать как же нарисовать график правильно?!
Цитата Сообщение от Liss29 Посмотреть сообщение
Т.е. X, Y - это прежние длины осей, которую нужно пересчитать, так?
Нет. X,Y - координаты на графике, x,y - на экране.
Цитата Сообщение от Liss29 Посмотреть сообщение
(X+3), (Y-25) - это опечатка?
Ну вот, какие то формулы уже появились, осталось только разобраться.
Нет, это не опечатка. Точнее, опечатка в другом месте: x = (X+3)/(8[B]+[/B]3)*600. И да, будет лучше если вы сами разберетесь с линейным преобразованием. В данном примере нам надо каждую точку из диапазона (-3 ... 8) перевести в диапазон (0...600), а каждую точку из (25...25.1) - в диапазон (0...400). Естественно, X и Y переводятся независимо. Для начала разберемся с X. Точке -3 соответствует 0, точке 8 соответствует 600. Точке 5 соответствует что?
Цитата Сообщение от Liss29 Посмотреть сообщение
Я бы не сказал, что очевидно, если было бы очевидно не стал бы задавать подобные вопросы.
Ну вы же сами его в качестве иксовой координаты использовали!
Цитата Сообщение от Liss29 Посмотреть сообщение
подписи осей
Параметром передавать в функцию, в простейшем случае можно указать X, Y.
Давайте не все сразу. В смысле, выберите на какой подзадаче хотите остановиться сейчас, на рисовании графиков или на рисовании текста. Иначе общение на форуме вообще в кашу превратится.
Цитата Сообщение от Liss29 Посмотреть сообщение
Т.е. это нетривиальная задача, если ответа нет.
Ну почему же, в существующих-то программах она решена. Она даже у меня в той или иной степени решена. Но чему же вы научитесь, если будете только готовые решения использовать?
Цитата Сообщение от Liss29 Посмотреть сообщение
Как ни странно ничего пока не получается, пока что создал обычное окно куда перенёс отрисовку графика(осей, без меток) при увеличении окна ось X как бы ломается, а, если окно уменьшаю, то график уходит за границу окна Решаю.
Отлично! Вы точно знаете, что задача имеет решение, и что оно не слишком сложное. Немного настойчивости, и вы его придумаете.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
21.07.2023, 23:40  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
И вы пытались угадать как же нарисовать график правильно?!
Я пытаюсь понять как правильно, если хотите, то это эксперименты, а как правильно, ну, я, думаю, что т.к. отрицательных значений я не задаю, то первоначальный график не верен, 0X не будет отрицательной, а вот по 0Y вполне может получиться отрицательный результат. Если угодно, то да, пытаюсь.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Для начала разберемся с X. Точке -3 соответствует 0, точке 8 соответствует 600. Точке 5 соответствует что?
Точки 5 соответствует 436.36...., следуя предложенной формуле: (5+3)/(8+3)*600. По идее, можно это вычислить и без формулы, так как точек всего 11 и при этом -3 = 0, а 8 = 600 и при этом 600 - это ширина области вывода, тогда 5 это по сути 8-ая точка, если брать во внимание тот факт, что есть ещё три точки -3, -2, -1, 600 / 11 = 54.545...., 54.545 * 8 = 436,3636. Хотя, возможно, этот вариант не рабочий.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну вы же сами его в качестве иксовой координаты использовали!
В смысле T-время, ну, это скорее вы меня на это надоумили) А что делать с двумя остальными параметрами они ведь в построении тоже играют не последнюю роль.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Давайте не все сразу. В смысле, выберите на какой подзадаче хотите остановиться сейчас, на рисовании графиков или на рисовании текста.
График нарисовал, осталось только сделать его более универсальным, более гибким, думаю, так будет вернее. Более красочным, но это дело вкуса.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну почему же, в существующих-то программах она решена. Она даже у меня в той или иной степени решена.
Думаю здесь нужен вывод результата в научном формате, он позволяет задавать любое число в фиксированном виде (1-e^n), значит можно рассчитать сколько понадобиться места для вывода числовых значений, хотя это и не так наглядно, но это на мой вкус.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы точно знаете, что задача имеет решение, и что оно не слишком сложное. Немного настойчивости, и вы его придумаете.
Установил параметры стиля класса окна CS_HREDRAW | CS_VREDRAW теперь перерисовывается, но если быстро изменять размер окна, то видны подёргивания графика. Возможно, решение, это двойная буферизация?
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
22.07.2023, 08:24
Цитата Сообщение от Liss29 Посмотреть сообщение
но если быстро изменять размер окна, то видны подёргивания графика. Возможно, решение, это двойная буферизация?
Всё верно. Копировать уже готовые пиксели из картинки на экран — это гораздо быстрее, чем рисовать прямо на экране.
Ещё можете убрать множественный вызов LineTo в цикле. Лучше заранее вычислите массив точек и отправьте его в функцию PolylineTo. Это быстрее.
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
22.07.2023, 09:31
Цитата Сообщение от Liss29 Посмотреть сообщение
Точки 5 соответствует 436.36...., следуя предложенной формуле:
Так откуда эта формула взялась? Как она изменится, если диапазон графика не числом задается, а переменной?
Цитата Сообщение от Liss29 Посмотреть сообщение
По идее, можно это вычислить и без формулы, так как точек всего 11
Точек может быть сколько угодно. Если речь о функции, то чтобы она выглядела гладкой, их нужно столько, сколько пикселей у вас по горизонтали. А если экспериментальные данные, то сколько намерили, столько и будет. Не забывайте, когда мы говорим о функции, у нее и вход, и выход - дробные числа.
Цитата Сообщение от Liss29 Посмотреть сообщение
В смысле T-время, ну, это скорее вы меня на это надоумили)
Это всего лишь возможная интерпретация, какой процесс из реального мира могла бы описывать такая функция. Для рисования графика это не нужно.
Цитата Сообщение от Liss29 Посмотреть сообщение
А что делать с двумя остальными параметрами они ведь в построении тоже играют не последнюю роль.
С какими еще двумя остальными? Если вы про коэффициенты a, n, k, то это могут быть, например, амплитуда, частота и затухание. Попробуйте их немного поменять, и убедитесь, что чем больше a, тем больше размах по вертикали. Чем больше n, тем выше частота, больше периодов колебаний. Чем больше k, тем быстрее график стремится к нулю. Но это опять физика, а не математика или программирование. Вы ведь хотите уметь строить любой график.
Цитата Сообщение от Liss29 Посмотреть сообщение
Думаю здесь нужен вывод результата в научном формате, он позволяет задавать любое число в фиксированном виде (1-e^n),
Только не 1-e^n а 1.234e+5 или, если совсем красиво, 1.234*105. В том смысле, что ученые тоже люди, и степень 10 им привычнее, чем степень е. Но, полагаю, вы это и имели в виду.
Цитата Сообщение от Liss29 Посмотреть сообщение
хотя это и не так наглядно, но это на мой вкус
Если хочется более наглядно, можно использовать десятичные приставки из системы Си: милли, микро, кило и т.д. Или хотя бы ограничить степени числами, кратными трем. То есть не 1.234e+5, а 123.4e+3 или 0.1234e+6 или 123.4к.
Неплохая задача на украшательство, которую я в свое время решать не стал. Для практического применения достаточно простейшего экспоненциального формата.
Кстати, с ним был один фейл

Писал программу для управления мощным источником питания, надо было напряжение на нем от нуля увеличить до 100 В, потом снизить до нуля, переключить полярность, снова поднять до 100 В и снова снизить до нуля. Напряжение там задается строкой вроде "VOLT 12.3\r\n" - это выставит 12.3 вольта. А потом смотрю, а прибор с ума сходит: до максимума напряжение поднял, до нуля опустил - и все. Вроде бы должен снова вверх идти, ан нет, застыл на нуле. А при следующем запуске все нормально. Нестабильная какая-то штука получилась. В общем, в итоге выяснилось, что я-то по привычке задаю дробные числа в адаптивном формате "%g", то есть пока их удобнее представить без экспоненты, система и представляет их без экспоненты, и для источника питания это нормально. А вот когда число становится слишком большим или слишком маленьким, переходит на экспоненциальную форму. И вблизи нуля получалась строка вроде VOLT 1.23e-18\r\n", на которую источник питания изумлялся и продолжал это делать до перезагрузки.
Заменил формат на sprintf(buf, "VOLT %.3f\r\n", U); и пока сбоев не было.
Это так, поделился историей из жизни.

Цитата Сообщение от Liss29 Посмотреть сообщение
теперь перерисовывается, но если быстро изменять размер окна, то видны подёргивания графика. Возможно, решение, это двойная буферизация?
Теоретически да, но в реальности окно не будут ресайзить часто. Вот сам график часто меняться может. Например, каждую секунду добавляться новая точка.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Копировать уже готовые пиксели из картинки на экран — это гораздо быстрее, чем рисовать прямо на экране.
Это не так. При рисовании прямо на экране вы меняете только небольшое число пикселей в памяти компьютера, а при буферизации - то же небольшое число, но потом весь огромный буфер копируете в другую область памяти.
Есть, конечно, системы вроде того же OpenGL, где просто меняются указатели, но даже так это отдельная операция.
В общем, двойная буферизация медленнее прямого рисования, но зато лишена артефактов и мерцания, потому ее и применяют.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Ещё можете убрать множественный вызов LineTo в цикле. Лучше заранее вычислите массив точек и отправьте его в функцию PolylineTo. Это быстрее.
Без разницы. У ТСа не так много точек, чтобы стоило этим заморачиваться.
А если уж гоняться за скоростью, то первое, что нужно сделать - выкинуть winAPI и использовать графическое ускорение вроде того же OpenGL.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
22.07.2023, 10:19
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
При рисовании прямо на экране вы меняете только небольшое число пикселей в памяти компьютера
Каждый вызов «рисования прямо на экране» требует растеризации векторной операции + отправку этой картинки в видеокарту + ожидание «сигнала синхронизации от видеокарты». И так на каждый вычисленный отрезок графика.
Это намного медленнее, чем отправить в видеокарту уже готовую картинку.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Есть, конечно, системы вроде того же OpenGL, где просто меняются указатели, но даже так это отдельная операция.
Функция BitBlt из GDI именно так и делает.
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
22.07.2023, 22:46
Цитата Сообщение от Замабувараев Посмотреть сообщение
Это намного медленнее, чем отправить в видеокарту уже готовую картинку.
Мы про GDI говорим, какая видеокарта.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Функция BitBlt из GDI именно так и делает.
Нет. Она ведь не трогает исходную картинку, она ее накладывает на "фоновую", причем возможно со смещением и лишь частичным перекрытием.
0
 Аватар для Liss29
225 / 39 / 4
Регистрация: 18.11.2012
Сообщений: 1,638
23.07.2023, 00:17  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Так откуда эта формула взялась? Как она изменится, если диапазон графика не числом задается, а переменной?
Какая, вы сами её предложили. Как изменится, ну как-то точно изменится, а как, сказать не могу.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Точек может быть сколько угодно. Если речь о функции, то чтобы она выглядела гладкой, их нужно столько, сколько пикселей у вас по горизонтали. А если экспериментальные данные, то сколько намерили, столько и будет. Не забывайте, когда мы говорим о функции, у нее и вход, и выход - дробные числа.
Может быть для начала ограничимся теми функциями, что уже присутствуют, так должно быть нагляднее, а то для меня ваши рассуждения слишком абстрактны. Что если я задам значение T больше, много больше, чем ширина области вывода окна в котором я рисую график?
Условимся, что ширина области вывода 600, высота 400. Для начала, как рассчитать сколько меток нужно по оси X и сколько по оси Y?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Попробуйте их немного поменять,
Пробовал, как это поможет мне в построении графика.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы ведь хотите уметь строить любой график.
Хотеть не вредно, вредно не хотеть) Да, хочу, но ответ я не получил, что с остальными величинами делать... если брать T и N, то получается, что A, K, T не важны, а это не так, значит их нужно как-то "прикрутить" к графику) В идеале, как бы мне хотелось или как мне видится, если я меняю какую-то величину, то график должен перестраивать согласно новым значениям. Или это дичь полная?

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В том смысле, что ученые тоже люди, и степень 10 им привычнее, чем степень е. Но, полагаю, вы это и имели в виду.
Меня такая запись числа приводит в ужас так что мне хоть https://www.cyberforum.ru/cgi-bin/latex.cgi?e хоть https://www.cyberforum.ru/cgi-bin/latex.cgi?10 всё едино. Видимо я угадал с этим, хоть что-то)

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Теоретически да, но в реальности окно не будут ресайзить часто. Вот сам график часто меняться может. Например, каждую секунду добавляться новая точка.
Будет не будет, это бабушка на двое сказала, но такого быть не должно и точка. Пусть график будет обновляться очень часто, значит проблема всё же присутствует.

Не по теме:

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
выкинуть winAPI и использовать графическое ускорение вроде того же OpenGL.
А на чём основываются OpenGL. Всё бы вам выкинуть, да какую-нибудь приблуду прикрутить.



Цитата Сообщение от Замабувараев Посмотреть сообщение
Лучше заранее вычислите массив точек и отправьте его в функцию PolylineTo.
Если с основной проблематикой разберусь, то попробую прорисовать таким образом. А двойная буферизация, как это реализовать, в смысле эффективности...
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HDC hMemDC;
    
    switch(msg)
    {
        case WM_CREATE:
        {
            cxScreen = GetSystemMetrics(SM_CXSCREEN);
            cyScreen = GetSystemMetrics(SM_CYSCREEN);
            HDC hdc = GetDC(hwnd);
            
            hMemDC = CreateCompatibleDC(hdc);
            HBITMAP hBitmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);
            
            SelectObject(hMemDC, hBitmap);
            SelectObject(hMemDC, GetStockObject(WHITE_BRUSH));
            
            DeleteObject(hBitmap);
            
            ReleaseDC(hwnd, hdc);
            return 1;
        }
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            
            AxisX(hMemDC....);
            
            BitBlt(....);
            EndPaint(hwnd, &ps);
            return 0;
        }
    }
}
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
23.07.2023, 08:45
Цитата Сообщение от Liss29 Посмотреть сообщение
Какая, вы сами её предложили. Как изменится, ну как-то точно изменится, а как, сказать не могу.
Ну вы же должны понимать что это за формула, откуда она взялась и какой у нее математический смысл.
Цитата Сообщение от Liss29 Посмотреть сообщение
Что если я задам значение T больше, много больше, чем ширина области вывода окна в котором я рисую график?
Условимся, что ширина области вывода 600, высота 400. Для начала, как рассчитать сколько меток нужно по оси X и сколько по оси Y?
Хорошо. Допустим, у вас T задано от 500 до 2500 - как будет выглядеть формула пересчета координат графика в координаты окна?
На счет количества меток - а ваше предположение каково?
Цитата Сообщение от Liss29 Посмотреть сообщение
если брать T и N, то получается, что A, K, T не важны
Ну как это не важны. Попробую еще больше уточнить физический смысл, возможно станет нагляднее. Пример затухающего колебания - маятник. Изначально (t=0) вы подняли грузик на высоту A, отпустили и строите график его высоты (Y) от времени. В таком случае K - частота колебаний, которая задается длиной подвеса и силой притяжения. N - затухание, сила трения, насколько скоро маятник остановится. Иначе говоря, величины K и N определяются конструкцией маятника. Если вы возьмете стержень подлиннее, K уменьшится. Если смажете подшипник получше, N уменьшится. То есть это константы, зависящие от самого маятника. Их не надо рисовать на графике, максимум можно записать в численном виде. А вот T - время наблюдения, оно зависит от вас.
Цитата Сообщение от Liss29 Посмотреть сообщение
В идеале, как бы мне хотелось или как мне видится, если я меняю какую-то величину, то график должен перестраивать согласно новым значениям.
А у вас разве не так сделано? Вроде ж поля ввода есть, если значения в них поменять, он не перестроится?
Цитата Сообщение от Liss29 Посмотреть сообщение
А на чём основываются OpenGL.
Напрямую на драйвере видеокарты. Но в чем-то вы правы, сам по себе он работать не будет, окно для него кто-то должен создать.
Цитата Сообщение от Liss29 Посмотреть сообщение
в смысле эффективности...
В смысле эффективности это с одной стороны, НЕ GDI. А с другой - сама задача не та, где эффективность требуется. У вас всего-то пара сотен точек, чтобы не успеть их отрисовывать, надо очень постараться. В моей реализации я использую cairo (в чем-то аналог GDI, но не winapi'шное, а из gtk). По правде, я бы предпочел тот же GopenGL, но когда писал эту штуку, виндовая реализация gtk его не поддерживала. Впрочем, практика показала, что скорость рисования графиков - далеко не самое узкое место.
Цитата Сообщение от Liss29 Посмотреть сообщение
А двойная буферизация, как это реализовать
Рисовать на какой-то буфер в памяти, а потом копировать его на экран.
Возможно, так будет нагляднее

Развлекался тут с расчетом трехмерной графики на ассемблере. И случайно оказалось, что виртуальный экран можно сделать побольше, тогда он захватывает не только свою память, но и задний буфер. Соответственно можно разглядеть как сначала на заднем буфере по одному рисуются треугольники, а потом копируются на передний буфер и тут же стирается с заднего буфера.
https://www.youtube.com/watch?v=d-nPmGgqwOE
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.07.2023, 08:45

Графики функций
Помогите пожалуйста исправить программу. Она неправильно рисует функцию FunS() и в компоненте Image график не такой получается. Написать...

Графики функций в с++
Подскажите пожалуйста, правильно ли создавать графики в с++ с помощью библиотеки OPenGL? Может существуют другие, более удобные библиотеки...

графики функций
привет. мне дана функция вида Y=kX+b где k=0;k=1; k=1.5 помогите пожалуйста построить график функции

Графики функций
Привет. Написал программу, которая строит график функции, заданной в Edit. Но возникла некоторая проблема: графики с большой степенью...

Использование графики. Нарисовать точку.
Задал этот вопрос в Delphi, разобрался. А как в С++ Builder пишется? Господа, только не смейтесь. Не найду как нарисовать точку. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru