Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
1

Баг в коде Reaction Diffusion Gray-Scott model

11.12.2020, 02:04. Показов 3271. Ответов 47

Author24 — интернет-сервис помощи студентам
Изначально первоисточник формул https://www.karlsims.com/rd.html
Как сделать тоже самое в коде С++ получить значение цвета параметр “c” из кода javascript. Пытаюсь сделать этот код Reaction Diffusion Gray-Scott model
Баг в коде Reaction Diffusion Gray-Scott model

https://youtu.be/BV9ny785UNc?t=2315
что за
Javascript
1
2
floor((a-b)*255);  // это вроде округление и умножение на 255..
c=constrain (c, 0,255); // что это?
http://яваскрипт.укр/Constrain
это типа нормализация? А где поиск макс мин значения во всем массиве значений?
Как это вообще возможно. Или это обрезка значений?
https://www.arduino.cc/referen... constrain/
x: if x is between a and b.
a: if x is less than a.
b: if x is greater than b.
Тогда работать по идее не должно вообще.
Вроде что-то рисует но проблема с окрасом. Нужен окрас всем каналам float от 0 до 1.
Самое забавное что делал сам другой алгоритм с просто описания из
Cyclic_Symmetric_Multi-Scale_Turing_Patterns.pdf
Один паттерн Тьюринга,перевод гугла.
«В этой модели есть только одно« вещество », которое играет роль пигментации,
активатор и ингибитор. Он представлен одним числом с плавающей запятой для каждого элемента прямоугольный массив. Элементы массива можно рассматривать как эквивалентные ячейкам в дискретном модель, предложенная Тьюрингом в его статье. Число с плавающей запятой, представляющее концентрацию вещество становится значением пикселя в результирующем изображении шкалы серого. Распространение моделируется с помощью среднее значение определенной области вокруг каждого элемента, меньшей площади для активатора и большей область для ингибитора. Простое правило итеративно применяется ко всем элементам массива для (обычно) сотен временных шагов: если средняя концентрация в меньшей области больше, чем средняя концентрация в большей области, увеличьте значение на небольшую величину, в противном случае уменьшите значение на небольшую величину. В на каждом временном шаге полученные значения повторно нормализуются в несколько произвольный диапазон от -1,0 до 1,0, чтобы избежать "убегай". Чтобы избежать краевых эффектов, накладываются периодические граничные условия ».

Сделал две свертки там с ядрами 3х3 и 5х5
Что –то рисовало.
Название: ScreenShot00662.jpg
Просмотров: 379

Размер: 26.1 Кб
Название: ScreenShot00661.jpg
Просмотров: 379

Размер: 34.4 Кб
А этот код вроде намного проще и ядро всего 3х3, и на сайте большое разнообразие форм.Не знаю как исправить код.
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <gl/glut.h>
#include <iostream> 
using namespace std;
 
const int imSiz=300; // размер картинки
 
float grid[imSiz+2][imSiz+2][2]={0};  // основной массив
float next[imSiz+2][imSiz+2][2]={0}; // буферный массив
bool render_complete=0;
float
Da=1.0,
Db=0.5,
k=0.062,
f=0.085;
 
 
//==============================================
//==============================================
//рисуем пиксели с окрасом
void drawPixelArray() 
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);
    for(int i = 1; i < imSiz+1; i++)
    {
        for (int j = 1; j < imSiz+1; j++)
        {
            float a=grid[i][j][1];
            glColor3f(a, a, a);
            glVertex2i(i,j);
        }
    }
    glEnd();
    render_complete=1;
}
//рисуем пиксели с окрасом
//==============================================
//==============================================
 
 
 
 
//==============================================
//==============================================
//====расчет  новой концетрации 
void conectratCorrection()
{
 
//------------------------------------------
//очистка буфера next
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
    next[i][j][0]=0;
    next[i][j][1]=0;
    }
}
//очистка буфера next
//------------------------------------------
 
 
 
//------------------------------------------
//свертка массива greed с ядром 3 на 3, лапласиан    
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
    float sumA=
    grid[i][j][0]*-1.0+
    grid[i-1][j][0]*0.2+
    grid[i+1][j][0]*0.2+
    grid[i][j+1][0]*0.2+
    grid[i][j-1][0]*0.2+
    grid[i-1][j-1][0]*0.05+
    grid[i+1][j-1][0]*0.05+
    grid[i+1][j+1][0]*0.05+
    grid[i-1][j+1][0]*0.05;
 
    float sumB=
    grid[i][j][1]*-1.0+
    grid[i-1][j][1]*0.2+
    grid[i+1][j][1]*0.2+
    grid[i][j+1][1]*0.2+
    grid[i][j-1][1]*0.2+
    grid[i-1][j-1][1]*0.05+
    grid[i+1][j-1][1]*0.05+
    grid[i+1][j+1][1]*0.05+
    grid[i-1][j+1][1]*0.05; 
 
    float a=grid[i][j][0];
    float b=grid[i][j][1];
    //next[i][j][0]=a+(Da*sumA)-(a*b*b)+(f*(1.0-a));
    //next[i][j][1]=b+(Db*sumB)+(a*b*b)-((k+f)*b);
    next[i][j][0]=(Da*sumA)-(a*b*b)+(f*(1.0-a));
    next[i][j][1]=(Db*sumB)+(a*b*b)-((k+f)*b);
    }
}
//свертка массива greed с ядром 3 на 3, лапласиан
//------------------------------------------
 
 
//------------------------------------------
//сумма старых значений  grid и новых next.
for(int i = 1; i < imSiz+1; i++)
{
    for (int j = 1; j < imSiz+1; j++)
    {
        grid[i][j][0]+=next[i][j][0];
        grid[i][j][1]+=next[i][j][1];
    }
}
 
//сумма старых значений  grid и новых next.
//------------------------------------------
drawPixelArray(); 
}
//====расчет  новой концетрации
//==============================================
//==============================================
 
 
//==============================================
//==============================================
//нарисовать квадрат 10 пикселей веществом B
void genArr()
{
for(int i = 0; i < imSiz+2; i++)
{
    for (int j = 0; j < imSiz+2; j++)
    {
        if(i>120 && i<180 && j>120 && j<180)
        {
            grid[i][j][0]=1;
            grid[i][j][1]=1;
        }
        else
        {
            grid[i][j][0]=1;
            grid[i][j][1]=0;
        }
    }
}
//drawPixelArray();
conectratCorrection();
}
//нарисовать квадрат 10 пикселей веществом B
//==============================================
//==============================================
 
 
 
//==============================================
//==============================================
//проверяет готов ли рендер, если да то обновляет экран и запуск таймера
void TimerFunction(int value)
{
    if(render_complete) 
    {
        glutSwapBuffers();
        render_complete=0;
        glutTimerFunc(33, TimerFunction, 1);
        cout << "New frame"<<endl;
        conectratCorrection();
    }
    else
    {
        cout << "Frame lost!----------"<<endl;
    }
}
//проверяет готов ли рендер, если да то обновляет экран и запуск таймера
//==============================================
//==============================================
 
 
void setupGL() 
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, imSiz , imSiz, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0, 0, 0, 0);
    glPointSize(1);
    genArr();
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(imSiz, imSiz); 
    glutInitWindowPosition(500, 200);
    glutCreateWindow("Reaction Diffusion Gray-Scott model");
    setupGL();
    glutTimerFunc(33, TimerFunction, 1);
    glutMainLoop();
    return 0;
}
Рисует ерунду.

Название: ScreenShot00660.jpg
Просмотров: 376

Размер: 1.0 Кб
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.12.2020, 02:04
Ответы с готовыми решениями:

Heat equaton, thermal diffusion equation, теплопроводность
Не могу разобраться в чем проблема. Пожалуйста взгляните. Пытался 3d уравнение теплового...

Создание input с привязкой к ng-model программно(в коде функции)
Всем привет! Вопрос: возможно ли создать &lt;select&gt; программно- в функции(например когда нажал...

Баг в коде
ловит кекалочку после ввода функции Выбираю функцию ,не срабатывет , снова выдаёт результат...

баг в коде или уязвимостьо
подскажите пожалуйста дорогие форумчане, есть ли в коде баг или уязвимость if (isset($_GET) and...

47
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
16.12.2020, 03:32  [ТС] 41
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от zayats80888 Посмотреть сообщение
Ну и как производительность в реальном времени, быстрее чем на процессоре?
Намного быстрей. С шейдертоя то мандельбульб рендерит.
Цитата Сообщение от zayats80888 Посмотреть сообщение
Для ускорения расчетов можете попробовать пропускать кадры, как вы делали. Для этого запускайте программу из консоли с опцией --skip-frames.
Тут похоже баг, пролетает первые N кадров на старте. А не между фреймами…ну то такое.
Главное что пашет, осталось только разбираться с этим всем.
Скините проект где эти шейдеры? Есть vs2012 и vs2008.
0
6107 / 3461 / 1406
Регистрация: 07.02.2019
Сообщений: 8,794
16.12.2020, 09:24 42
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Тут похоже баг, пролетает первые N кадров на старте. А не между фреймами…ну то такое.
Быть такого не может...
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Скините проект где эти шейдеры?
Скину просто файлы, т.к. проект у меня CMake со специфичными настройками. Просто создадите свой пустой проект, присоедините к нему все файлы. От вас нужна только библиотека GLFW, слинковаться с ней(и её зависимостями) и с opengl32.lib.
Папка с шейдерами у вас уже есть.
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Есть vs2012 и vs2008.
Нужна поддержка С++11, переписывать я не буду, т.е. желательно vs2015(а вообще, скачайте себе VSCode + MinGW + CMake + CMake Tools for VSCode, это примерно 600Мб всё вместе и будет поддерживать даже С++20 частично)
Вложения
Тип файла: zip diffusion.zip (49.1 Кб, 4 просмотров)
0
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
16.12.2020, 12:44  [ТС] 43
Цитата Сообщение от zayats80888 Посмотреть сообщение
Быть такого не может...
Может неправильно вызываю? --skip-frames 10000 вообще не влияет.
Сделал 1.bat рядом с exe
main.exe --skip-frames 10000
На вашем компе меняется скорость роста визуально сильно? Может это новый баг? Может скобки нужны, а вообще зачем там принимать команды от строки? Хватит в шейдерах задать это.
0
6107 / 3461 / 1406
Регистрация: 07.02.2019
Сообщений: 8,794
16.12.2020, 14:06 44
Цитата Сообщение от Excalibur921 Посмотреть сообщение
На вашем компе меняется скорость роста визуально сильно?
Не сильно(у меня при пропуске ~20000 кадров экран обновляется раз в секунду, т.е. ~20000 проходов вычислений в секунду, разница не особо ощутима визуально, ну а конкретные замеры я не делал), для более слабых машин может повлиять. Суть простая:
Обычный режим (skipFrames = 1):
1 проход вычислений (feedbackPass)
1 проход отрисовки (renderPass)
1 свап экранныого буфера (glfwSwapBuffers, в зависимости от "политики" драйвера, это может быть затратное копирование)
Пропуск 1000 кадров (skipFrames = 1000):
1000 проходов вычислений (feedbackPass)
1 проход отрисовки (renderPass)
1 свап экранныого буфера (glfwSwapBuffers)
Т.е. грубо, на 1000 команд рисования, в первом случае - на высисление тратится только половина, а во втором - практически все команды это вычисления.

Цитата Сообщение от Excalibur921 Посмотреть сообщение
Хватит в шейдерах задать это.
В шейдерах на скорость вычислений вы никак не повлияете, кроме как уменьшением количества инструкций. Речь идёт именно о скорости вычислений, а не о "скорости" происходящего на экране(хотя оно и взаимосвязано).
0
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
16.12.2020, 14:38  [ТС] 45
Цитата Сообщение от zayats80888 Посмотреть сообщение
Не сильно(у меня при пропуске ~20000 кадров экран обновляется раз в секунду,
Если пропуск =0 то заполнение экрана например секунд 60.
Если пропуск =20000 то заполнение экрана должно быть мгновенно либо упираться в скорость железа.

Вот в этой проге
Баг в коде Reaction Diffusion Gray-Scott model
int iterNoRender=3;//сколько итераций без рендера пропускать,
//ускорение анимации
Означает пропуск N итераций без рендера. Между фреймами. Запустите и поменяйте iterNoRender =1 или iterNoRender =4. Разница видна визуально в анимации.

Добавлено через 8 минут
Может кто знает что это получилось за алгоритм?
Это эксперименты с самодельной реакцией диффузии по описанию в тексте
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Один паттерн Тьюринга,перевод гугла.
«В этой модели есть только одно« вещество », которое играет роль пигментации,
активатор и ингибитор. Он представлен одним числом с плавающей запятой для каждого элемента прямоугольный массив.
и получился странный код генерирующий очень сложное поведение неких клеточных автоматов через простое правило. В проге есть анимация это процедурное построение рисунка, обходит сложные участки плоскости которые нетривиально запрограммировать.
Баг в коде Reaction Diffusion Gray-Scott model
Сильно меняется форма рисунков от параметров.
C++
1
2
3
float smallConcentration=0.7f;  
float setConcentrationUp=1.0f; // концентрации растворов
float setConcentrationDn=0.7f; //
Может там некий алгоритмический баг? Похоже на процедурный генератор орнаментов вышивания крестиком. Есть ли название этому алгоритму или им подобным? Может кто-то делал подобное? Искал в гугле по разным вариантам и ничего похожего. Всюду только автоматы и моды “игра жизнь”.
0
6107 / 3461 / 1406
Регистрация: 07.02.2019
Сообщений: 8,794
16.12.2020, 14:38 46
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Если пропуск =0 то заполнение экрана например секунд 60.
Если вы вручную поставите 0, то рендерится вообще ничего не будет По умолчанию 1. В исходниках можете посмотреть, как работает.
Цитата Сообщение от Excalibur921 Посмотреть сообщение
Если пропуск =20000 то заполнение экрана должно быть мгновенно либо упираться в скорость железа.
Вот у меня именно так, первый кадр - квадратик в центре, через секунду смена кадра и поле уже заполнено, это всегда упирается в скорость железа.

Кстати об исходниках, если у вас трудности со сборокой и линковкой, то вот простой проект CMake, исходники GLFW внутри.
Там же "видео" инструкция, как собрать проект в пару кликов для студии вместе с библиотекой. Вам понадобится CMake Всё просто.
Вложения
Тип файла: zip diffusion.zip (2.99 Мб, 7 просмотров)
2
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
16.12.2020, 14:54  [ТС] 47
Вот в чем дело, в старой версии такой баг. В новой пашет. Причем пашет только скип 1000 странно.

Добавлено через 7 минут
Вот еще в чем дело, у меня указан пропуск между кадрами который 60 раз в сек идет, а у вас пропуск каждую секунду. Поэтому у меня плавно идет.
0
1471 / 826 / 140
Регистрация: 12.10.2013
Сообщений: 5,456
24.12.2020, 21:26  [ТС] 48
Похоже на диффузию только немного угловатая. Наверно это ее какой-то подвид. Может размыть и будет похоже.
Cделал вращение ядер свертки как функция от X строки и интерполяцию ближайшего соседа. Я думал если крутануть ядро то эти отростки линий будут под разными углами идти но не совсем так. Сильно мутирует форма.
Вот нет вращения ядер.
Название: x2_New_anim.gif
Просмотров: 60

Размер: 25.1 Кб
Вот крутит за проход строки из 200 значений до 0.05 от полного оборота.
Название: x3_New_new.gif
Просмотров: 60

Размер: 23.9 Кб
Слева направо угол поворота мал и округление не искажает ядро потому выглядит как вращения нет, дальше угол проходит некоторый порог и искажается форма ближе к правому участку. Похоже причина в самом методе интерполяции, ядро часто читает повторные ячейки массива и сильно искажается все из-за округления ближайшего соседа.
Вот тут наглядно видно, поворот ядра 5х5 на 360.
Название: x1_New.gif
Просмотров: 60

Размер: 94.9 Кб
Получается далеко не квадратное ядро + повторное чтение неправильных ячеек свертки. Отсюда сильная мутация формы. Вот полный оборот ядра.
Название: x4_New.gif
Просмотров: 60

Размер: 66.2 Кб
Сейчас как эксперимент доделываю билинейную интерполяцию. Она должна быть по идее намного лучше т.к. ядро должно быть стабильно по форме.

Не получается сделать утолщения линий в процессе рисования, единственно сильно влияет множитель суммы компонентов ядра t2=1.25. Если менять его в процессе итераций то срабатывает утолщение
t2=1.15
Баг в коде Reaction Diffusion Gray-Scott model

но потом когда ставлю норма t2=1.25 чтобы не залило все толстыми белыми кусками алгоритм пожирает все утолщения и снова превращает все в узкие полосы…Хз как можно сделать. На этапе дебага ошибочно плюсовал разные компоненты ядра повторно...это приводило к утолщению полос но не могу повторить теперь =)).

Рисует бывает наоборот утончая линии, какие-то разводки дорожек микросхем.
Баг в коде Reaction Diffusion Gray-Scott model

А хотелось бы плавные линии и колебания толщин линий. Может нужны опыты с реакцией диффузии.. хз. Мне тут понравилось что алгоритм быстрый и рисует сложные лабиринты. Может сделать вести типа кисть концентрации и алгоритм по идее будет расти за кистью.
Название: x5_New_an.gif
Просмотров: 60

Размер: 27.4 Кб
Название: x6_New_an.gif
Просмотров: 60

Размер: 27.4 Кб
Название: x7_New_an.gif
Просмотров: 60

Размер: 37.4 Кб
Название: x8_New_an.gif
Просмотров: 60

Размер: 34.9 Кб
Название: x9_New_an.gif
Просмотров: 60

Размер: 37.9 Кб
0
24.12.2020, 21:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.12.2020, 21:26
Помогаю со студенческими работами здесь

Непонятный баг в правильном коде
Есть ирк-бот на c#, раньше все работало нормально, но теперь стало игнорироваться условие if...

Баг в коде (статическая структура)
Задача: • Описать структуру с именем NOTE, содержащую следующие поля: • фамилия, имя; • номер...

Баг stm8s003 или ошибка в коде?
При написании программы под контроллер STM8S003 столкнулся с такой проблемой. Когда я работаю с...

Не могу найти баг в своем коде
Не работает скрипт или баг где-то? &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;utf-8&quot;&gt; &lt;script&gt; ...

Баг в коде(псевдо-рандомные числа)
Здраствуйте, суть программы в том чтобы в цикле выдавало определенное количество рандомных значений...

Баг в коде(псевдо-рандомные числа)
Здраствуйте, суть программы в том чтобы в цикле выдавало определенное количество рандомных значений...


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

Или воспользуйтесь поиском по форуму:
48
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru