Как строить графики в с
Перейти к содержимому

Как строить графики в с

  • автор:

Рисование графиков в С++

Еще

Если использовать Code::Blocks и mingw, то нужно подключить библиотеку freeglut или freeglut_static (во втором случае нужно также установить макрос FREEGLUT_STATIC), а также opengl32, winmm, gdi32. Подключить в проекте заголовочный файл include/easy_plot.hpp, указать С++11 или выше.

Пример того, что может рисовать эта библиотека:

Рисование графиков в С++
Рисование графиков в С++

Рисование графиков в С++Рисование графиков в С++

Пример кода

Рисование тепловой карты

Особенности библиотеки:

  • Функция plot может принимать такие параметры, как имя окна, стиль окна (различные настройки цвета и пр., см. WindowSpec), данные графиков и стиль линий.
  • Функция draw_heatmap может принимать такие параметры, как имя окна, стиль окна (различные настройки цвета и пр., см. WindowSpec), данные массива тепловой карты типа float и размер тепловой карты.
  • Если графиков несколько, изначально они будут расположены по всему экрану равномерно.
  • Если навести курсор мыши на график, можно узнать номер линии и данные по осям X и Y.
  • Рисование графиков и тепловой карты происходит в отдельном потоке.
  • При повторном вызове функции с уже существующим именем окна график будет перерисован.
  • Можно сохранить график
  • Ключевые слова: , , , , , , , , , ,
  • хорошо
  • 27
  • 06 декабря 2019, 13:30

Еще

И зачем такие сложности. Встроенных возможностей вполне хватает и без OpenGL.

  • 06 декабря 2019, 13:34

Еще

  • 06 декабря 2019, 13:54

Еще

  • 06 декабря 2019, 16:17

Еще

  • 06 декабря 2019, 16:19

Еще

  • 06 декабря 2019, 18:06

Еще

  • 06 декабря 2019, 18:19

Еще

  • 06 декабря 2019, 14:00

Еще

  • 06 декабря 2019, 14:12

Еще

  • 06 декабря 2019, 16:59

Еще

  • 06 декабря 2019, 14:14

Еще

  • 06 декабря 2019, 14:14

Еще

  • 06 декабря 2019, 14:43

Еще

  • 06 декабря 2019, 17:00

Еще

  • 06 декабря 2019, 22:33

Еще

  • 06 декабря 2019, 15:21

Еще

  • 06 декабря 2019, 16:00

Еще

Как всё сложно у С++’ников. серьёзный подход. даже сказал бы профессиональный. На пайтон такие вещи попроще делаются.

последний раз графику использовал на c++ когда учился и писал в borland C. там это было примерно также просто как и на turbo pascal/qbasic. цикл по X, вычисление координат из функции (y) с масштабированием, постановка точки через point (ну или можно и lineto, если точек недостаточно).

  • 06 декабря 2019, 18:48

Еще

Gregori, C++ только для профессионалов.

  • 07 декабря 2019, 03:56

Еще

  • 07 декабря 2019, 12:53

Еще

elektroyar, первая жесть — это потенциально «размножающиеся» static-переменные в заголовочном файле, особенно mutex. Если я разобью свою программу на несколько модулей (файлов), каждый из которых включит заголовочный файл библиотеки, то у меня появится несколько mutex’ов, по одному на каждый модуль. Всё, защита от race condition сломана.

Добиться того, чтобы mutex все равно был только один, можно, вот пример с несколькими модулями, где показано, что из разных модулей в вашем коде получается разный адрес mutex’а, то есть, их там много.

А также дана правильная реализация, чтобы адрес был один на программу, то есть, чтобы mutex был единственным.

Вторая жесть — это то, что код не является exception-safe там, где это жизненно необходимо.

Вы защищаете mutex’ом изменения drawings. Перед изменением drawings соответствующий mutex lock’чится, после изменения — раз’lock’чивается назад. Как бы, всё хорошо. Но между этими двумя моментами вызываются функции push_back и make_shared, каждая из которых может выбросить исключение. Я, в коде своей программы, могу отловить исключения и продолжить работу дальше. Но, вот, только библиотечный код при этом не раз’lock’чит mutex, и при попытке повторно его за’lock’чить всё повиснет. Для избегания таких вещей в стандартной библиотеке специально имеется lock_guard, который раз’lock’чит mutex при любом развитии событий.

Третья жесть — вы вообще прогоняли свой же тест?
Он не падает где-то на 33-35 строке?

В функцию с переменным числом аргументов передаёте сами объекты, а в самой функции вычитываете их адреса. Но передали-то объекты, а не их адреса. Естественно, всё падает.

В функцию с переменным числом аргументов можно передавать только POD-типы, а вы аж вектор туда запихиваете. И LineSpec не является POD-типом. Чтобы он им стал, требуется оттуда выкинуть всё, что мешает скомпилировать его в pure C. Вам хочется использовать значения по умолчанию, но это можно сделать и с POD-типом, применив вспомогательную функцию. Вот набросок на эту тему. Значение последнего параметра берётся по умолчанию.

Вот здесь рекомендуют вместо функции с переменным числом аргументов использовать variadic templates или initializer_list. Но для этого, конечно, нужно владеть «шаблонной магией» хотя бы на среднем уровне.

Набросок решения с использованием variadic templates — здесь (общее количество пар заранее неизвестно).

Набросок решения с использованием initializer_list — здесь (общее количество пар в данном случае будет заранее известно).

В целом, остальное, навскидку, жестью не является, но очень много особенностей построения кода говорят о непонимании множества вещей.

Для написания библиотек, кстати, требуется более высокая квалификация, чем для написания обычных программ, потому что требуется учитывать множество вариантов, как пользователи библиотеки могут использовать её.

C++ для начинающих Рисование графика функции

Итак. Я с этим не сталкивался, но наверное в Универах могут давать лабораторные построения графиков по разным формулам. По большому счету неважно как выглядит формула, все сводится к однообразному построению и у начинающих не такие уж сложные задачи.

Я выбрал простой график y=x*x Короткая формула, всем известная кривая (всем кто хоть чуть-чуть учился в школе)

Код C++ Рисование графика
============
#include <graphics.h> // включить описание графических функций С/С++ Borland’a
#include <conio.h>
// описание функций ввода-вывода с консоли (для getch())

int main ()
<
float x , y ;
/* Автоматическое определение графических параметров */
int gdriver = DETECT , gmode ;
initgraph (& gdriver , & gmode , “” ); // Инициализация графического режима

x =- 10 ; //Инициализируем x
moveto ( x , x * x );
//Устанавливаем курсор

do
<
y = x * x ; //Наша формула для построения графика
lineto ( x * 50 + getmaxx ()/ 2 , getmaxy ()/ 2
-( y * 20 )); // ..откуда рисуем график
x = x + 0.02 ;
> while( x < 10 );
getch ();
// ожидание нажатия пользователем любой клавиши
closegraph ();
// выход из графического режима
return 0 ;
>

============

Что ж. Сразу скажу – Я не знаю почему x увеличивается на дробное число. При моих попытках увеличивать его на единицу график получался очень даже не гладким и это было плохо, поэтому оставил так как отыскал в просторах интернета. Чтобы начать рисовать линию из какой-то точки имеет смысл определить первоначальную точку, для чего была использована функция moveto Сам график строится с помощью циклического вычисления, ведь для каждого значения x нужно получить соответствующий ему y, значит, чтобы не писать все эти выражения вручную нужно использовать цикл.

Внутри цикла вызывается функция lineto, внутри которой написаны такие параметры, которые могут сбить с толку бедного новичка, но пугаться не стоит. lineto чертит линию от текущей позиции до, но не включая в нее, указанной точки. Другими словами при вычислении значения y мы будем получать некоторые точки, а чтобы получить график, нужно эти точки соединять линиями.
x * 50 + getmaxx ()/ 2 Обозначает, что первоначальная точка x смещена к центру экрана по оси x. Цифра 50 здесь нужна только для того чтобы расширить рисуемый график. Нетрудно попробовать её изменить или убрать, чтобы увидеть эффект. Когда я пытался убрать эту 50 и прибавлять к x единицу вместо 0.02 график рисовался ужасно, хотя если подумать, то то что написано здесь или то что хотел написать я сводится к тому что x прибавляется на единицу, но что-то вот в этом есть чего я понять пока что увы не могу. Точнее понимаю, но понимаю как-то туманно, не полностью и сложно для разъяснений

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

Программа на си для построения графика функции

В этой статье мы разберем программу на языке программирования си для построения графиков функций. В нашей программе будут отражаться система координат с делениями и подписями на них и будут строиться графики двух функций, который может сам задать пользователь.
В программе на си для построения графика функции вводятся следующие константы
X0 , Y0 — координаты центра координат
k – масштаб одного деления на осях (сколько пикселов в одном делении)
Опишем все функции и процедуры используемые в программе для построения графиков функций
Подробно о задании функций и процедур в си
int osx (float x) переводит реальную координату на оси ox в координату экрана
int osy (float y) переводит реальную координату на оси oy в координату экрана
float F1 ( float x ) и float F2 ( float x ) задают функции , графики которых мы будем строить
void Point ( float x, float y, int color ) рисует точку графика функции на экране
Перед построением графиков функций необходимо построить систему координат. Для построения системы координат используется процедура
void Axes()
В этой процедуре в цикле for рисуются линии меток делений на равном расстоянии друг от друга, который определяется масштабом одного деления k и выводятся значения делений с помощью двух операторов
sprintf ( s, "%d", i ); // записываем в строковую переменную число деления
outtextxy ( xe-10, Y0+4, s ); // вывод числа
Процедура grafik1() и grafik2() строят графики функций f1 и f2
В этих процедурах в цикле for для всех доступных значений x определяется координата y и точка графика строится с помощью процедуры point()

Пример работы программы построения графиков на си, функции пользователь может менять

графики функций на си

Программа на си для построения графиков функций
#include <stdio.h>
#include <graphics.h> //графический режим
#include <math.h> // математические функции

//————————————————
const int X0 = 100, Y0 = 400;// координаты центра координат
const float k = 15;// масштаб в точках одного деления на графике
//——————————————
// перевод y в координаты экрана
//——————————————
int osx (float x)
<
return X0+k*x;
>
//——————————————
//перевод y в координаты экрана
//——————————————
int osy (float y)
<
return Y0-k*y;
>
// первая функция
float F1 ( float x )
<
return sqrt(2*x);
>
// вторая функция
float F2 ( float x )
<
return x*x/2;
>
// построение осей
void Axes()
<
int i, xe,ye,y1;
char s[10];
line ( X0, 0, X0, 599 ); // ось ox
line ( 0, Y0, 799, Y0 ); // ось oy
// метки на оси ox
for ( i = 1; i <= (800-X0)/k; i ++ )
<
xe = osx ( i );
line ( xe, Y0-2, xe, Y0+2 ); // рисуем деление разметки
sprintf ( s, "%d", i ); // записываем в строковую переменную число деления
outtextxy ( xe-10, Y0+4, s ); // вывод числа
>
// метки на оси oy
for ( i = 1; i <= (Y0)/k; i ++ )
<
ye = osy( i+1 );
line ( X0-2, ye, X0+2, ye ); // рисуем деление
sprintf ( s, "%d",i ); // записываем в строковую переменную число деления
outtextxy ( X0+10, ye+4, s ); // вывод числа
>
>
// построение точки графика функции
void Point ( float x, float y, int color )
<
int xe, ye;
xe = osx(x);
ye = osy(y);
if ( xe >= 0 && xe < 800 && ye >= 0 && ye < 600 )
putpixel(xe, ye, color);
>
// построение графика первой функции
void grafik1()
<
float x, h, xmin, xmax;
h = 1 / k;
xmin = (-X0)/ k;
xmax=(800-X0)/k;
for ( x = xmin; x <= xmax; x += h )
<
Point(x, F1(x), WHITE);
>
>
// построение графика второй функции
void grafik2()
<
float x, h, xmin, xmax;
h = 1 / k;
xmin = (-X0)/ k;
xmax=(800-X0)/k;
for ( x = xmin; x <= xmax; x += h )
<
Point(x, F2(x), WHITE);
>
>
// главная программа
main ()
<
initwindow ( 800, 600 ); // создать окно для графики
Axes(); // построение и разметка осей координат
grafik1(); // строим график первой функции
grafik2(); // строим график второй функции
getch(); // ждать нажатия на клавишу
closegraph(); // закрыть окно для графики
>
Полезно почитать по теме построение графиков функций в программа си
Графика в си
Процедуры и функции в си

С++ как начертить график в консольном приложении?

У меня есть код, находящий значения конхоиды Никомеда, и я хотел бы реализовать отрисовку графика по точкам(параллельно с вычислением значений). Я пытался сделать отрисовку прямо в консоли, но в моей реализации график отрисовывается моментально и пропадает при первой перерисовке окна. Есть ли какие-то другие варианты отрисовать график? Я думаю о варианте открыть еще одно окно (WinForm) и отрисовать уже в нем, но не могу найти примера чего-то подобного.

MSDN.WhiteKnight's user avatar

Zoom's user avatar

То, что вы рисуете напрямую в окне консоли, затирается стандартным обработчиком отрисовки conhost при следующем обновлении окна (как при выводе нового текста в консоль, так и при изменении, например, размеров ее окна). Переопределить этот обработчик нельзя, но можно отобразить свое окно поверх консоли, как показано в примере ниже. Кроме того, код рисования графика в вопросе рисует график по отдельным точкам, я переделал его с SetPixel на MoveTo/LineTo, чтобы он выглядел непрерывным.

console graph

MSDN.WhiteKnight's user avatar

Используйте SetConsoleCursorPosition(..) для установки курсора в консоли на необходимые координаты. Затем выводите символ, обозначающий линию, например ‘*’.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *