Дискуссионный математический форумМатематический форум
Математический форум Math Help Planet

Обсуждение и решение задач по математике, физике, химии, экономике

Теоретический раздел
Часовой пояс: UTC + 3 часа [ Летнее время ]
новый онлайн-сервис
число, сумма и дата прописью

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Точечная модель газов и жидкостей
СообщениеДобавлено: 06 дек 2022, 23:36 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

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

Далее выложена заготовка для простейших программ моделирования газов и жидкостей
на основе движения отдельных молекул-точек. Написано на языке С без использования
характерных для С++ объектных особенностей. Не рассматриваются вопросы
ввода-вывода информации, в том числе изображения точек на экране,
представлено лишь основное ядро вычислений. При необходимости возможна
дополнительная коррекция облака молекул: изменить кинетическую энергию
системы (изначально не нулевую) можно путём умножения всех скоростей точек
на квадратный корень из соотношения желаемой энергии и фактической.
Для обнуления суммарного импульса по какой-то координате необходимо
от соответствующих скоростей каждой молекулы отнять сумму импульсов
по данной координате делённую на сумму масс (кинетическая энергия
или температура при этом тоже изменится). Более-менее локально точное
сохранение энергии с учётом потенциальной при дискретном моделировании
практически невозможно. При высоких требованиях к постоянству температуры
и импульса системы поправки приходится вводить с каждым шагом времени.

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

Структура molecule содержит координаты и скорости точек в трёх измерениях.
Также массу, которая может различаться (например, смесь азота с кислородом).
Если используются не условные "игровые" или "экранные" единицы, лучше использовать
атомные вместо единиц системы СИ, избегая слишком больших или малых по модулю величин
в арифметических операциях. Для физического моделирования подходят как минимум
64-битные числа с плавающей точкой, точности 32-битных недостаточно.
Следует учитывать, что 64 бита (double) обрабатываются процессором как единое целое,
что значительно быстрее, чем при использовании составных чисел повышенной точности.

Глобальные данные:

xmin,xmax,ymin,ymax,zmin,zmax определяют минимальные и максимальные пределы "ёмкости",
в которой происходят перемещения молекул. Если пределы должны отсутствовать,
следует задать эти величины очень малыми (для минимальных пределов) и очень большими
(для максимальных пределов) по отношению к центру происходящих событий.

Шаг времени dt должен быть >= 0, программа не рассчитана на обратный ход времени.

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

При сближении точек на расстояние colldist или меньшее осуществляется расчёт
отталкивания между молекулами. Если colldist > 0, используется схема упругих
столкновений, реалистичная при моделировании газов. Если colldist <= 0,
используется схема потенциальных энергий и сил на основе симметричных
кубических сплайнов, применимая к жидкостям. Формулы для расчётов следующие:
epot = потенциальная энергия, fpot = сила, обе величины положительные
для отталкивания, отрицательные для притяжения.
fpot = - производная от epot по расстоянию, расстояние s варьирует
от 0 до максимального smax, используется симметричный кубический сплайн
со свойствами: epot(0) = epot0, epot(smax) = 0, fpot(0) = 0, fpot(smax) = 0
epot = epot0 + e2 * s^2 + e3 * s^3
fpot = 2 * e2 * s + 3 * e3 * s^2
epot0 + e2 * smax^2 + e3 * smax^3 = 0
2 * e2 * smax + 3 * e3 * smax^2 = 0
e2 = - 3 * epot0 / smax^2
e3 = 2 * epot0 / smax^3
epot = epot0 * (1 - 3 / smax^2 * s^2 + 2 / smax^3 * s^3)
fpot = epot0 * (6 / smax^2 * s - 6 / smax^3 * s^2)
Величина repepot0 >= 0 обозначает потенциальную энергию отталкивания молекул
при нулевом расстоянии. Величина attrepot0 <= 0 обозначает потенциальную энергию
притяжения двух молекул при нулевом расстоянии.
Величина repdist обозначает smax для отталкивания, attrdist аналог для притяжения.
Рекомендуется делать repepot0 в разы большей по модулю, чем attrepot0,
а repdist в разы меньшей, чем attrdist.

Параметр direction показывает, вдоль какой оси координат будут принудительно
разнесены на расстояние около 2 * mindist точки, оказавшиеся слишком близко.
Используется как примитивная замена более сложных генераторов случайных чисел.

Внешние силы fx,fy,fz (например, гравитационные) действуют на все точки
в одном направлении.

Постоянная gconstant (по умолчанию нулевая) используется в случаях,
когда облако молекул обладает собственной гравитацией.
Проводится упрощённый расчёт с воздействием сил, направленных к центру масс.
Для притяжения gconstant < 0, при > 0 можно моделировать отталкивание.

В массиве molarray находятся молекулы, участвующие во взаимодействиях.

Глобальные функции:

void interact(molecule* p1,molecule* p2)
рассчитывает взаимодействие между двумя молекулами

void process()
запускается через каждый шаг времени, рассчитывает скорости и расположение точек

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 06 дек 2022, 23:37 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
////// gas and liquid simple simulation
#define molecules 1000

struct molecule
{
double sx,sy,sz;//positions
double vx,vy,vz;//velocities
double mass;
};

double xmin,xmax,ymin,ymax,zmin,zmax;//minimal and maximal positions
double dt;//time step, >= 0
double mindist = 0.000001;//minimal valid distance, > 0
double colldist;//collision maximal distance, for gas > 0, for liquid = 0
double repepot0 = 0.0;//repulsion energy at zero distance, >= 0
double repdist;//repulsion maximal distance, > 0
double attrepot0 = 0.0;//attraction energy at zero distance, <= 0
double attrdist;//attraction maximal distance, > 0
unsigned char direction = 0;
double fx = 0.0,fy = 0.0,fz = 0.0;//external forces (like gravitation)
double gconstant = 0.0;//cloud internal gravitation constant, for attraction < 0
molecule molarray[molecules];

void interact(molecule* p1,molecule* p2)
{
double cosx,cosy,cosz;
double dist,dist2;
double dx,dy,dz;
double smax2;
double v1,v2;
double vfactor;
dx = p2->sx - p1->sx; dy = p2->sy - p1->sy; dz = p2->sz - p1->sz;
dist2 = dx * dx + dy * dy + dz * dz;
dist = sqrt(dist2);
if(dist <= mindist)
{
//set positions to different valid values
if(direction == 0) { p1->sx -= mindist; p2->sx += mindist; }
else
{
if(direction == 1) { p1->sy -= mindist; p2->sy += mindist; }
else { p1->sz -= mindist; p2->sz += mindist; }
}
direction = (direction + 1) % 3;
dx = p2->sx - p1->sx; dy = p2->sy - p1->sy; dz = p2->sz - p1->sz;
dist2 = dx * dx + dy * dy + dz * dz;
dist = sqrt(dist2);
}
if(colldist > 0.0)
{
//collision of two gas molecules
if(dist > colldist)
return;
//interaction axis is drawen from first molecule to second
cosx = dx / dist; cosy = dy / dist; cosz = dz / dist;
v1 = p1->vx * cosx + p1->vy * cosy + p1->vz * cosz;
v2 = p2->vx * cosx + p2->vy * cosy + p2->vz * cosz;
if(v1 <= v2)
return;
vfactor = (2.0 * (v1 - v2)) / (p1->mass + p2->mass);
//v1 - v2 always > 0, collision force F > 0
//v1'(new) = v1(old) - dt * F / m1, v2'(new) = v2(old) + dt * F / m2
//kinetic energy (/2): m1 * v1'^2 + m2 * v2'^2 = m1 * v1^2 + m2 * v2^2
//F * dt = m1 * m2 * 2 * (v1 - v2) / (m1 + m2)
v1 -= p2->mass * vfactor; v2 += p1->mass * vfactor;
p1->vx += v1 * cosx; p1->vy += v1 * cosy; p1->vz += v1 * cosz;
p2->vx += v2 * cosx; p2->vy += v2 * cosy; p2->vz += v2 * cosz;
return;
}
//interaction between two liquid molecules
smax2 = repdist * repdist;
vfactor = (repepot0 * 6.0) * (dist / smax2 - dist2 / (smax2 * repdist));
smax2 = attrdist * attrdist;
vfactor += (attrepot0 * 6.0) * (dist / smax2 - dist2 / (smax2 * attrdist));
vfactor *= dt;
v1 = - (vfactor / p1->mass); v2 = vfactor / p2->mass;
cosx = dx / dist; cosy = dy / dist; cosz = dz / dist;
p1->vx += v1 * cosx; p1->vy += v1 * cosy; p1->vz += v1 * cosz;
p2->vx += v2 * cosx; p2->vy += v2 * cosy; p2->vz += v2 * cosz;
return;
}

void process()
{
double centerx,centery,centerz;
double dist;
double dx,dy,dz;
double gfactor,gsize;
signed long index1,index2;
double mass;
double vfactor;
molecule* pmol;
for(index1 = 0;index1 < molecules;index1++)
{
//external forces
pmol = &molarray[index1];
vfactor = dt / pmol->mass;
pmol->vx += fx * vfactor;
pmol->vy += fy * vfactor;
pmol->vz += fz * vfactor;
}
if(gconstant != 0.0)
{
//internal gravitation
centerx = 0.0; centery = 0.0; centerz = 0.0; mass = 0.0;
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
centerx += pmol->sx * pmol->mass;
centery += pmol->sy * pmol->mass;
centerz += pmol->sz * pmol->mass;
mass += pmol->mass;
}
centerx /= mass; centery /= mass; centerz /= mass;
gfactor = gconstant * mass;
gsize = 0.0;
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
dx = pmol->sx - centerx;
dy = pmol->sy - centery;
dz = pmol->sz - centerz;
gsize += sqrt(dx * dx + dy * dy + dz * dz) * pmol->mass;
}
if(gsize < mindist) gsize = mindist;
gsize *= gsize;
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
dx = pmol->sx - centerx;
dy = pmol->sy - centery;
dz = pmol->sz - centerz;
dist = sqrt(gsize + dx * dx + dy * dy + dz * dz);
vfactor = (gfactor / ((dist * dist) * dist)) * (dt / pmol->mass);
pmol->vx += dx * vfactor;
pmol->vy += dy * vfactor;
pmol->vz += dz * vfactor;
}
}
//interactions between molecules
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
//no interaction twice
for(index2 = index1 + 1;index2 < molecules;index2++) interact(pmol,&molarray[index2]);
}
//direct motions
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
pmol->sx += pmol->vx * dt;
pmol->sy += pmol->vy * dt;
pmol->sz += pmol->vz * dt;
}
//repulsions from walls
for(index1 = 0;index1 < molecules;index1++)
{
pmol = &molarray[index1];
if(pmol->sx < xmin) { pmol->vx = - pmol->vx; pmol->sx = xmin; }
else
{
if(pmol->sx > xmax) { pmol->vx = - pmol->vx; pmol->sx = xmax; }
}
if(pmol->sy < ymin) { pmol->vy = - pmol->vy; pmol->sy = ymin; }
else
{
if(pmol->sy > ymax) { pmol->vy = - pmol->vy; pmol->sy = ymax; }
}
if(pmol->sz < zmin) { pmol->vz = - pmol->vz; pmol->sz = zmin; }
else
{
if(pmol->sz > zmax) { pmol->vz = - pmol->vz; pmol->sz = zmax; }
}
}
return;
}

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 29 дек 2022, 14:11 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
Выкладываю программу на Javascript для моделирования небольшого объёма идеального газа.
Предполагаемые алгоритмы из первых постов темы пришлось существенно пересмотреть.
Почти все возможности скрипта мной протестированы, но если обнаружите баги, прошу
сообщать об этом. Прямые рудименты HTML и CSS были минимизированы до небольшой "заглушки",
через которую запускается скрипт, можно её оформить как файл gasideal.htm или gasideal.html

<HTML>
<HEAD>
<script src="gasideal.txt"></script>
</HEAD>
<BODY>
<noscript style="text-align: center; font-size: 50;">JAVASCRIPT MUST BE TURNED ON</noscript>
<script type="text/javascript">
document.body.style.backgroundColor = "WhiteSmoke";
f_create();
</script>
</BODY>
</HTML>

Остальной код содержится в файле gasideal.txt (также можно использовать расширение .js),
который должен находиться в той же папке.
Как оказалось, консервативный Яваскрипт, без использования Canvas, вполне успевает
обрабатывать движение сотен точек. Главное замедление происходит потому, что это
всё же сложные объекты, и взаимодействует каждый с каждым без использования методов
отсечения заведомо далёких участов от данной точки (вычисления растут квдратично).
Проблема не в компьютерной графике.

Пояснения по поводу интерфейса:
Целочисленные width и height определяют ширину и высоту модельного поля в пикселах.
Поля x,y,z minimum и maximum задают границы реального объёма.
Отмеченные чекбоксы x,y,z closed показывают замкнутость пространства отдельно
по каждому измерению, в замкнутом вместо отталкивания от "стенок" точка
переходит на другую сторону модельного объёма.
Радио переключатели view along показывают, вдоль какой оси пользователем наблюдается
модельный объём, по умолчанию вдоль z, остальные оси всегда направлены вправо и вниз
(используется правая система координат).
Поле min positive обозначает минимальную положительную величину, допустимую в расчётах,
в частности, для деления, чтобы знаменатель не был равным нулю.
Поле min distance (требует осторожности) показывает на каком расстоянии (или меньшем)
начинают взаимодействовать точки между собой.
Величина point size обозначает размеры точки (квадратика) в пикселах.
Целочисленные red, green, blue points показывают количество точек каждого вида,
всего возможно три вида: красные, зелёные и синие.
Далее идут массы точки (mass) по каждому виду, и дополнительные силы,
действующие вдоль каждого измерения, если например, задать небольшую
положительную (скажем, 0.1) вдоль y, то видно как "атмосфера" оседает вниз,
при этом не происходит особенного разделения на цветам, видимо вымывание
водорода и гелия из реальной земной атмосферы процесс длительный.
Поле velocity mul это множитель для скоростей, задаваемых при создании рандомной модели.
Поле kinetic mul используется при нажатии кнопки mul Ekin, чтобы умножить
кинетическую энергию системы на заданное число, то есть фактически уменьшить
или увеличить скорость движения точек и условную "температуру".
Поле step msecs показывает как часто (в миллисекундах) вызывается шаг симуляции.
Поле time step это шаг времени, величина для использования в расчётах обновления
реальных скоростей и положений точек в системе координат.
Кнопка one step делает один шаг в симуляции.
Кнопка run model запускает регулярно повторяемую симуляцию.
Кнопка pause останавливает исполнение.
Кнопка create создаёт рандомную модель с заданными выше настройками.
Кнопки load и save нужны для загрузки и сохранения модели через текстовое поле
внизу панели управления, в формате "буква цвета" + 3 числа для положений x,y,z
+ 3 числа для скоростей x,y,z, числа разделяются одним или многоми white-space
символами, к которым относится пробел, табуляция (горизонтальная), перевод
на новую строку и возврат каретки.
Кнопка 0 impulse обнуляет суммарный импульс системы по всем измерениям,
чтобы не было общего дрейфа точек в какую-то сторону.
Кнопка mul Ekin, как написано выше, использует множитель для кинетической энергии
системы точек, изменяет "температуру".

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

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 29 дек 2022, 14:14 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
////// global data
var d_field;
var d_panel;
var d_xspace = 5,d_xsize = 200,d_yspace = 5,d_ysize = 20;
var d_width = 600,d_height = 600;
var d_xmin = -1,d_xmax = 1,d_ymin = -1,d_ymax = 1,d_zmin = 0,d_zmax = 0;
var d_xclose = 0,d_yclose = 0,d_zclose = 0;
var d_viewdir = 2;
var d_minpos = 0.000001;
var d_mindist = 0.03;
var d_pointsize = 3;
var d_reds = 50,d_greens = 50,d_blues = 50;
var d_redmass = 1,d_greenmass = 3,d_bluemass = 9;
var d_velmul = 0.1;
var d_kinmul = 0.5;
var d_timer;
var d_msecs = 100;
var d_timestep = 0.1;
var d_xforce = 0,d_yforce = 0,d_zforce = 0;
var d_colldir= 0;
////// cleanpoints
function f_cleanpoints()
{
var d_nextpoint;
var d_point = d_field.firstChild;
if(d_point == null)
return;
for(;;)
{
d_nextpoint = d_point.nextSibling;
d_field.removeChild(d_point);//after remove no nextSibling
if(d_nextpoint == null)
break;
d_point = d_nextpoint;
}
return;
}
////// createpoints
function f_createpoints()
{
var d_index,d_limit;
var d_point;
var d_x,d_y,d_z;
var d_w,d_h
var d_left,d_top;
f_cleanpoints();
var d_dx = d_xmax - d_xmin;
var d_dy = d_ymax - d_ymin;
var d_dz = d_zmax - d_zmin;
d_limit = d_reds;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = document.createElement("div");
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.setAttribute("d_sx",d_xmin + (d_x * d_dx));
d_point.setAttribute("d_sy",d_ymin + (d_y * d_dy));
d_point.setAttribute("d_sz",d_zmin + (d_z * d_dz));
d_point.setAttribute("d_vx",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vy",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vz",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_mass",d_redmass);
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
d_point.style.width = d_pointsize + "px";
d_point.style.height = d_pointsize + "px";
d_point.style.backgroundColor = "red";
d_point.style.position = "absolute";
d_field.appendChild(d_point);
}//1
d_limit = d_greens;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = document.createElement("div");
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.setAttribute("d_sx",d_xmin + (d_x * d_dx));
d_point.setAttribute("d_sy",d_ymin + (d_y * d_dy));
d_point.setAttribute("d_sz",d_zmin + (d_z * d_dz));
d_point.setAttribute("d_vx",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vy",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vz",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_mass",d_greenmass);
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
d_point.style.width = d_pointsize + "px";
d_point.style.height = d_pointsize + "px";
d_point.style.backgroundColor = "green";
d_point.style.position = "absolute";
d_field.appendChild(d_point);
}//1
d_limit = d_blues;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = document.createElement("div");
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.setAttribute("d_sx",d_xmin + (d_x * d_dx));
d_point.setAttribute("d_sy",d_ymin + (d_y * d_dy));
d_point.setAttribute("d_sz",d_zmin + (d_z * d_dz));
d_point.setAttribute("d_vx",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vy",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_vz",((Math.random() * 2) - 1) * d_velmul);
d_point.setAttribute("d_mass",d_bluemass);
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
d_point.style.width = d_pointsize + "px";
d_point.style.height = d_pointsize + "px";
d_point.style.backgroundColor = "blue";
d_point.style.position = "absolute";
d_field.appendChild(d_point);
}//1
return;
}
////// adjustpointx
function f_adjustpointx(d_point)
{
var d_dx,d_vx;
var d_left,d_top;
var d_extent = d_xmax - d_xmin;
if(d_extent <= d_minpos)
{//1
d_point.setAttribute("d_sx",(d_xmin + d_xmax) / 2);
if(d_viewdir == 0)//y right,z down
return;
if(d_viewdir == 1)//z right,x down
{
d_top = Math.round((d_height / 2) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}
//d_viewdir = 2,x right,y down
d_left = Math.round((d_width / 2) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
return;
}//1
var d_sx = Number(d_point.getAttribute("d_sx"));
if(d_sx < d_xmin)
{//1
d_dx = d_xmin - d_sx;
d_dx -= Math.floor(d_dx / d_extent) * d_extent;
if(d_xclose != 0) d_sx = d_xmax - d_dx;
else
{
d_sx = d_xmin + d_dx;
d_vx = Number(d_point.getAttribute("d_vx"));
if(d_vx < 0) d_point.setAttribute("d_vx",- d_vx);
}
d_point.setAttribute("d_sx",d_sx);
}//1
else
{//1
if(d_sx > d_xmax)
{//2
d_dx = d_sx - d_xmax;
d_dx -= Math.floor(d_dx / d_extent) * d_extent;
if(d_xclose != 0) d_sx = d_xmin + d_dx;
else
{
d_sx = d_xmax - d_dx;
d_vx = Number(d_point.getAttribute("d_vx"));
if(d_vx > 0) d_point.setAttribute("d_vx",- d_vx);
}
d_point.setAttribute("d_sx",d_sx);
}//2
}//1
if(d_viewdir == 0)//y right,z down
return;
if(d_viewdir == 1)//z right,x down
{
d_top = Math.round((((d_sx - d_xmin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}
//d_viewdir = 2,x right,y down
d_left = Math.round((((d_sx - d_xmin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
return;
}
////// adjustpointy
function f_adjustpointy(d_point)
{
var d_dy,d_vy;
var d_left,d_top;
var d_extent = d_ymax - d_ymin;
if(d_extent <= d_minpos)
{//1
d_point.setAttribute("d_sy",(d_ymin + d_ymax) / 2);
if(d_viewdir == 0)//y right,z down
{
d_left = Math.round((d_width / 2) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
return;
}
if(d_viewdir == 1)//z right,x down
return;
//d_viewdir = 2,x right,y down
d_top = Math.round((d_height / 2) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}//1
var d_sy = Number(d_point.getAttribute("d_sy"));
if(d_sy < d_ymin)
{//1
d_dy = d_ymin - d_sy;
d_dy -= Math.floor(d_dy / d_extent) * d_extent;
if(d_yclose != 0) d_sy = d_ymax - d_dy;
else
{
d_sy = d_ymin + d_dy;
d_vy = Number(d_point.getAttribute("d_vy"));
if(d_vy < 0) d_point.setAttribute("d_vy",- d_vy);
}
d_point.setAttribute("d_sy",d_sy);
}//1
else
{//1
if(d_sy > d_ymax)
{//2
d_dy = d_sy - d_ymax;
d_dy -= Math.floor(d_dy / d_extent) * d_extent;
if(d_yclose != 0) d_sy = d_ymin + d_dy;
else
{
d_sy = d_ymax - d_dy;
d_vy = Number(d_point.getAttribute("d_vy"));
if(d_vy > 0) d_point.setAttribute("d_vy",- d_vy);
}
d_point.setAttribute("d_sy",d_sy);
}//2
}//1
if(d_viewdir == 0)//y right,z down
{
d_left = Math.round((((d_sy - d_ymin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_offset = 0;
d_point.style.left = d_left + "px";
return;
}
if(d_viewdir == 1)//z right,x down
return;
//d_viewdir = 2,x right,y down
d_top = Math.round((((d_sy - d_ymin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}
////// adjustpointz
function f_adjustpointz(d_point)
{
var d_dz,d_vz;
var d_left,d_top;
var d_extent = d_zmax - d_zmin;
if(d_extent <= d_minpos)
{//1
d_point.setAttribute("d_sz",(d_zmin + d_zmax) / 2);
if(d_viewdir == 0)//y right,z down
{
d_top = Math.round((d_height / 2) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}
if(d_viewdir == 2)//x right,y down
return;
//d_viewdir = 1,z right,x down
d_left = Math.round((d_width / 2) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
return;
}//1
var d_sz = Number(d_point.getAttribute("d_sz"));
if(d_sz < d_zmin)
{//1
d_dz = d_zmin - d_sz;
d_dz -= Math.floor(d_dz / d_extent) * d_extent;
if(d_zclose != 0) d_zy = d_zmax - d_dz;
else
{
d_sz = d_zmin + d_dz;
d_vz = Number(d_point.getAttribute("d_vz"));
if(d_vz < 0) d_point.setAttribute("d_vz",- d_vz);
}
d_point.setAttribute("d_sz",d_sz);
}//1
else
{//1
if(d_sz > d_zmax)
{//2
d_dz = d_sz - d_zmax;
d_dz -= Math.floor(d_dz / d_extent) * d_extent;
if(d_zclose != 0) d_sz = d_zmin + d_dz;
else
{
d_sz = d_zmax - d_dz;
d_vz = Number(d_point.getAttribute("d_vz"));
if(d_vz > 0) d_point.setAttribute("d_vz",- d_vz);
}
d_point.setAttribute("d_sz",d_sz);
}//2
}//1
if(d_viewdir == 0)//y right,z down
{
d_top = Math.round((((d_sz - d_zmin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
return;
}
if(d_viewdir == 2)//x right,y down
return;
//d_viewdir = 1,z right,x down
d_left = Math.round((((d_sz - d_zmin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
return;
}
////// interact
//interaction axis is drawen from first point to second
//v1 - v2 always > 0, collision force F > 0
//v1'(new) = v1(old) - dt * F / m1, v2'(new) = v2(old) + dt * F / m2
//kinetic energy (/2): m1 * v1'^2 + m2 * v2'^2 = m1 * v1^2 + m2 * v2^2
//F * dt = m1 * m2 * 2 * (v1 - v2) / (m1 + m2)
function f_interact(d_point1,d_point2)
{
var d_cosx,d_cosy,d_cosz;
var d_sx1 = Number(d_point1.getAttribute("d_sx"));
var d_sy1 = Number(d_point1.getAttribute("d_sy"));
var d_sz1 = Number(d_point1.getAttribute("d_sz"));
var d_sx2 = Number(d_point2.getAttribute("d_sx"));
var d_sy2 = Number(d_point2.getAttribute("d_sy"));
var d_sz2 = Number(d_point2.getAttribute("d_sz"));
var d_dx = d_sx2 - d_sx1;
var d_dy = d_sy2 - d_sy1;
var d_dz = d_sz2 - d_sz1;
var d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist > d_mindist)
return;
if(d_dist < d_minpos)
{//1
if(d_colldir == 0)
{
d_cosx = 1;
d_cosy = 0;
d_cosz = 0;
}
else
{//2
if(d_colldir == 1)
{
d_cosx = 0;
d_cosy = 1;
d_cosz = 0;
}
else
{
d_cosx = 0;
d_cosy = 0;
d_cosz = 1;
}
}//2
d_colldir++;
if(d_colldir > 2) d_colldir = 0;
}//1
else
{
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosz = d_dz / d_dist;
}
var d_vx1 = Number(d_point1.getAttribute("d_vx"));
var d_vy1 = Number(d_point1.getAttribute("d_vy"));
var d_vz1 = Number(d_point1.getAttribute("d_vz"));
var d_vx2 = Number(d_point2.getAttribute("d_vx"));
var d_vy2 = Number(d_point2.getAttribute("d_vy"));
var d_vz2 = Number(d_point2.getAttribute("d_vz"));
var d_v1 = (d_vx1 * d_cosx) + ((d_vy1 * d_cosy) + (d_vz1 * d_cosz));
var d_v2 = (d_vx2 * d_cosx) + ((d_vy2 * d_cosy) + (d_vz2 * d_cosz));
if(d_v1 <= d_v2)
return;
var d_m1 = Number(d_point1.getAttribute("d_mass"));
var d_m2 = Number(d_point2.getAttribute("d_mass"));
var d_vmul = (2 * (d_v1 - d_v2)) / (d_m1 + d_m2);
var d_vmul1 = d_m2 * d_vmul;
var d_vmul2 = d_m1 * d_vmul;
d_point1.setAttribute("d_vx",d_vx1 - (d_vmul1 * d_cosx));
d_point1.setAttribute("d_vy",d_vy1 - (d_vmul1 * d_cosy));
d_point1.setAttribute("d_vz",d_vz1 - (d_vmul1 * d_cosz));
d_point2.setAttribute("d_vx",d_vx2 + (d_vmul2 * d_cosx));
d_point2.setAttribute("d_vy",d_vy2 + (d_vmul2 * d_cosy));
d_point2.setAttribute("d_vz",d_vz2 + (d_vmul2 * d_cosz));
return;
}
////// process
function f_process()
{
var d_mass,d_vmul;
var d_point2;
var d_firstpoint = d_field.firstChild;
if(d_firstpoint == null)
return;
var d_point1 = d_firstpoint;
for(;;)
{//1
d_mass = Number(d_point1.getAttribute("d_mass"));
//external forces
if(d_mass > d_minpos)
{
d_vmul = d_timestep / d_mass;
d_point1.setAttribute("d_vx",Number(d_point1.getAttribute("d_vx")) + (d_xforce * d_vmul));
d_point1.setAttribute("d_vy",Number(d_point1.getAttribute("d_vy")) + (d_yforce * d_vmul));
d_point1.setAttribute("d_vz",Number(d_point1.getAttribute("d_vz")) + (d_zforce * d_vmul));
}
d_point1 = d_point1.nextSibling;
if(d_point1 == null)
break;
}//1
//interactions between points
d_point1 = d_firstpoint;
for(;;)
{
//no interaction twice
for(d_point2 = d_point1.nextSibling;d_point2 != null;d_point2 = d_point2.nextSibling) f_interact(d_point1,d_point2);
d_point1 = d_point1.nextSibling;
if(d_point1 == null)
break;
}
d_point1 = d_firstpoint;
for(;;)
{
//direct motions
d_point1.setAttribute("d_sx",Number(d_point1.getAttribute("d_sx")) + (Number(d_point1.getAttribute("d_vx")) * d_timestep));
d_point1.setAttribute("d_sy",Number(d_point1.getAttribute("d_sy")) + (Number(d_point1.getAttribute("d_vy")) * d_timestep));
d_point1.setAttribute("d_sz",Number(d_point1.getAttribute("d_sz")) + (Number(d_point1.getAttribute("d_vz")) * d_timestep));
f_adjustpointx(d_point1);
f_adjustpointy(d_point1);
f_adjustpointz(d_point1);
d_point1 = d_point1.nextSibling;
if(d_point1 == null)
break;
}
return;
}
////// label
function f_label(d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = d_xsize + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_panel.appendChild(d_label);
return;
}
////// halflabel
function f_halflabel(d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = (d_xsize / 2) + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_panel.appendChild(d_label);
return;
}
////// area
function f_area(d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = d_xsize + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_panel.appendChild(d_area);
return d_area;
}
////// halfarea
function f_halfarea(d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = (d_xsize / 2) + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_panel.appendChild(d_area);
return d_area;
}
////// button
function f_button(d_id,d_text,d_left,d_top)
{
d_button = document.createElement("button");
d_button.id = "d_id";
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = d_xsize + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_panel.appendChild(d_button);
return d_button;
}
////// halfbutton
function f_halfbutton(d_id,d_text,d_left,d_top)
{
d_button = document.createElement("button");
d_button.id = "d_id";
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = (d_xsize / 2) + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_panel.appendChild(d_button);
return d_button;
}
////// width
function f_width()
{
var d_extent,d_left;
var d_newwidth = Number(this.value);
if(Number.isFinite(d_newwidth) != 0)
{//1
if(d_newwidth > 0)
{//2
if(d_newwidth == Math.round(d_newwidth))
{//3
if(d_newwidth == d_width)
return;
d_width = d_newwidth;
d_field.style.width = d_width + "px";
d_panel.style.left = d_width + "px";
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
if(d_viewdir == 0)//y right,z down
{//4
d_extent = d_ymax - d_ymin;
for(;;)
{
if(d_extent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sy")) - d_ymin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//4
if(d_viewdir == 1)//z right,x down
{//4
d_extent = d_zmax - d_zmin;
for(;;)
{
if(d_extent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sz")) - d_zmin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//4
//d_viewdir = 2,x right,y down
d_extent = d_xmax - d_xmin;
for(;;)
{
if(d_extent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sx")) - d_xmin) / d_extent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//3
}//2
}//1
this.value = d_width;
return;
}
////// height
function f_height()
{
var d_extent,d_top;
var d_newheight = Number(this.value);
if(Number.isFinite(d_newheight) != 0)
{//1
if(d_newheight > 0)
{//2
if(d_newheight == Math.round(d_newheight))
{//3
if(d_newheight == d_height)
return;
d_height = d_newheight;
d_field.style.height = d_height + "px";
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
if(d_viewdir == 0)//y right,z down
{//4
d_extent = d_zmax - d_zmin;
for(;;)
{
if(d_extent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sz")) - d_zmin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//4
if(d_viewdir == 1)//z right,x down
{//4
d_extent = d_xmax - d_xmin;
for(;;)
{
if(d_extent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sx")) - d_xmin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//4
//d_viewdir = 2,x right,y down
d_extent = d_ymax - d_ymin;
for(;;)
{
if(d_extent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sy")) - d_ymin) / d_extent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//3
}//2
}//1
this.value = d_height;
return;
}
////// xmin
function f_xmin()
{
var d_newxmin = Number(this.value);
if(Number.isFinite(d_newxmin) != 0)
{//1
if(d_newxmin <= d_xmax)
{
if(d_newxmin == d_xmin)
return;
d_xmin = d_newxmin;
f_cleanpoints();
return;
}
}//1
this.value = d_xmin;
return;
}
////// xmax
function f_xmax()
{
var d_newxmax = Number(this.value);
if(Number.isFinite(d_newxmax) != 0)
{//1
if(d_newxmax >= d_xmin)
{
if(d_newxmax == d_xmax)
return;
d_xmax = d_newxmax;
f_cleanpoints();
return;
}
}//1
this.value = d_xmax;
return;
}
////// ymin
function f_ymin()
{
var d_newymin = Number(this.value);
if(Number.isFinite(d_newymin) != 0)
{//1
if(d_newymin <= d_ymax)
{
if(d_newymin == d_ymin)
return;
d_ymin = d_newymin;
f_cleanpoints();
return;
}
}//1
this.value = d_ymin;
return;
}
////// ymax
function f_ymax()
{
var d_newymax = Number(this.value);
if(Number.isFinite(d_newymax) != 0)
{//1
if(d_newymax >= d_ymin)
{
if(d_newymax == d_ymax)
return;
d_ymax = d_newymax;
f_cleanpoints();
return;
}
}//1
this.value = d_ymax;
return;
}
////// zmin
function f_zmin()
{
var d_newzmin = Number(this.value);
if(Number.isFinite(d_newzmin) != 0)
{//1
if(d_newzmin <= d_zmax)
{
if(d_newzmin == d_zmin)
return;
d_zmin = d_newzmin;
f_cleanpoints();
return;
}
}//1
this.value = d_zmin;
return;
}
////// zmax
function f_zmax()
{
var d_newzmax = Number(this.value);
if(Number.isFinite(d_newzmax) != 0)
{//1
if(d_newzmax >= d_zmin)
{
if(d_newzmax == d_zmax)
return;
d_zmax = d_newzmax;
f_cleanpoints();
return;
}
}//1
this.value = d_zmax;
return;
}
////// showpoints
function f_showpoints()
{
var d_left,d_top;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
var d_xextent = d_xmax - d_xmin;
var d_yextent = d_ymax - d_ymin;
var d_zextent = d_zmax - d_zmin;
for(;;)
{//1
if(d_viewdir == 0)//y right,z down
{
if(d_yextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sy")) - d_ymin) / d_yextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_zextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sz")) - d_zmin) / d_zextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
}
else
{//2
if(d_viewdir == 1)//z right,x down
{
if(d_zextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sz")) - d_zmin) / d_zextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_xextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sx")) - d_xmin) / d_xextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
}
else
{
//d_viewdir = 2,x right,y down
if(d_xextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((Number(d_point.getAttribute("d_sx")) - d_xmin) / d_xextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_point.style.left = d_left + "px";
if(d_yextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((Number(d_point.getAttribute("d_sy")) - d_ymin) / d_yextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_point.style.top = d_top + "px";
}
}//2
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}//1
return;
}
////// viewdir
function f_viewdir()
{
var d_newviewdir = Number(this.value);
if(d_newviewdir == d_viewdir)
return;
d_viewdir = d_newviewdir;
f_showpoints();
return;
}
////// minpos
function f_minpos()
{
var d_newminpos = Number(this.value);
if(Number.isFinite(d_newminpos) != 0)
{//1
if(d_newminpos > 0)
{
if(d_newminpos == d_minpos)
return;
d_minpos = d_newminpos;
return;
}
}//1
this.value = d_minpos;
return;
}
////// mindist
function f_mindist()
{
var d_newmindist = Number(this.value);
if(Number.isFinite(d_newmindist) != 0)
{//1
if(d_newmindist > 0)
{
if(d_newmindist == d_mindist)
return;
d_mindist = d_newmindist;
return;
}
}//1
this.value = d_mindist;
return;
}
////// pointsize
function f_pointsize()
{
var d_newpointsize = Number(this.value);
if(Number.isFinite(d_newpointsize) != 0)
{//1
if(d_newpointsize > 0)
{//2
if(d_newpointsize == Math.round(d_newpointsize))
{//3
if(d_newpointsize == d_pointsize)
return;
d_pointsize = d_newpointsize;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
for(;;)
{
d_point.style.width = d_pointsize + "px";
d_point.style.height = d_pointsize + "px";
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
f_showpoints();
return;
}//3
}//2
}//1
this.value = d_pointsize;
return;
}
////// reds
function f_reds()
{
var d_newreds = Number(this.value);
if(Number.isFinite(d_newreds) != 0)
{//1
if(d_newreds >= 0)
{//2
if(d_newreds == Math.round(d_newreds))
{
if(d_newreds == d_reds)
return;
d_reds = d_newreds;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_newreds;
return;
}
////// greens
function f_greens()
{
var d_newgreens = Number(this.value);
if(Number.isFinite(d_newgreens) != 0)
{//1
if(d_newgreens >= 0)
{//2
if(d_newgreens == Math.round(d_newgreens))
{
if(d_newgreens == d_greens)
return;
d_greens = d_newgreens;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_greens;
return;
}
////// blues
function f_blues()
{
var d_newblues = Number(this.value);
if(Number.isFinite(d_newblues) != 0)
{//1
if(d_newblues >= 0)
{//2
if(d_newblues == Math.round(d_newblues))
{
if(d_newblues == d_blues)
return;
d_blues = d_newblues;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_blues;
return;
}
////// redmass
function f_redmass()
{
var d_newredmass = Number(this.value);
if(Number.isFinite(d_newredmass) != 0)
{//1
if(d_newredmass > 0)
{//2
if(d_newredmass == d_redmass)
return;
d_redmass = d_newredmass;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
for(;;)
{
if(d_point.style.backgroundColor == "red") d_point.setAttribute("d_mass",d_redmass);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//2
}//1
this.value = d_redmass;
return;
}
////// greenmass
function f_greenmass()
{
var d_newgreenmass = Number(this.value);
if(Number.isFinite(d_newgreenmass) != 0)
{//1
if(d_newgreenmass > 0)
{//2
if(d_newgreenmass == d_greenmass)
return;
d_greenmass = d_newgreenmass;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
for(;;)
{
if(d_point.style.backgroundColor == "green") d_point.setAttribute("d_mass",d_greenmass);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//2
}//1
this.value = d_greenmass;
return;
}
////// bluemass
function f_bluemass()
{
var d_newbluemass = Number(this.value);
if(Number.isFinite(d_newbluemass) != 0)
{//1
if(d_newbluemass > 0)
{//2
if(d_newbluemass == d_bluemass)
return;
d_bluemass = d_newbluemass;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
for(;;)
{
if(d_point.style.backgroundColor == "blue") d_point.setAttribute("d_mass",d_bluemass);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}//2
}//1
this.value = d_bluemass;
return;
}
////// xforce
function f_xforce()
{
var d_newxforce = Number(this.value);
if(Number.isFinite(d_newxforce) != 0)
{
if(d_newxforce == d_xforce)
return;
d_xforce = d_newxforce;
return;
}
this.value = d_xforce;
return;
}
////// yforce
function f_yforce()
{
var d_newyforce = Number(this.value);
if(Number.isFinite(d_newyforce) != 0)
{
if(d_newyforce == d_yforce)
return;
d_yforce = d_newyforce;
return;
}
this.value = d_yforce;
return;
}
////// zforce
function f_zforce()
{
var d_newzforce = Number(this.value);
if(Number.isFinite(d_newzforce) != 0)
{
if(d_newzforce == d_zforce)
return;
d_zforce = d_newzforce;
return;
}
this.value = d_zforce;
return;
}
////// velmul
function f_velmul()
{
var d_newvelmul = Number(this.value);
if(Number.isFinite(d_newvelmul) != 0)
{//1
if(d_newvelmul > 0)
{
if(d_newvelmul == d_velmul)
return;
d_velmul = d_newvelmul;
return;
}
}//1
this.value = d_velmul;
return;
}
////// kinmul
function f_kinmul()
{
var d_newkinmul = Number(this.value);
if(Number.isFinite(d_newkinmul) != 0)
{//1
if(d_newkinmul > 0)
{
if(d_newkinmul == d_kinmul)
return;
d_kinmul = d_newkinmul;
return;
}
}//1
this.value = d_kinmul;
return;
}
////// msecs
function f_msecs()
{
var d_newmsecs = Number(this.value);
if(Number.isFinite(d_newmsecs) != 0)
{//1
if(d_newmsecs > 0)
{//2
if(d_newmsecs == Math.round(d_newmsecs))
{
if(d_newmsecs == d_msecs)
return;
d_msecs = d_newmsecs;
return;
}
}//2
}//1
this.value = d_msecs;
return;
}
////// timestep
function f_timestep()
{
var d_newtimestep = Number(this.value);
if(Number.isFinite(d_newtimestep) != 0)
{//1
if(d_newtimestep > 0)
{
if(d_newtimestep == d_timestep)
return;
d_timestep = d_newtimestep;
return;
}
}//1
this.value = d_timestep;
return;
}
////// pxtonum
function f_pxtonum(d_pixels)//?
{
var d_size = d_pixels.length;
if(d_size < 3)
return 0;
return Number(d_pixels.substr(0,d_size - 2));
}
////// simplestep
function f_simplestep()
{
var d_size,d_sx;
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
for(;;)
{
//?d_point.style.left = f_pxtonum(d_point.style.left) + 10;
d_point.setAttribute("d_sx",Number(d_point.getAttribute("d_sx")) + (Number(d_point.getAttribute("d_vx")) * d_timestep));
d_point.setAttribute("d_sy",Number(d_point.getAttribute("d_sy")) + (Number(d_point.getAttribute("d_vy")) * d_timestep));
d_point.setAttribute("d_sz",Number(d_point.getAttribute("d_sz")) + (Number(d_point.getAttribute("d_vz")) * d_timestep));
f_adjustpointx(d_point);
f_adjustpointy(d_point);
f_adjustpointz(d_point);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}
////// onestep
function f_onestep()
{
//?f_simplestep();
f_process();//?
return;
}
////// run
function f_run()
{
d_timer = window.setInterval(f_onestep,d_msecs);
return;
}
////// pause
function f_pause()
{
window.clearInterval(d_timer);
return;
}
////// testwsc
function f_testwsc(d_char)
{
if(d_char != ' ')
{//1
if(d_char != '\t')
{//2
if(d_char != '\r')
{
if(d_char != '\n')
return 0;
}
}//2
}//1
return 1;
}
////// load
function f_load()
{
var d_char,d_num,d_numstr;
var d_point;
var d_area = document.getElementById("d_modelarea");
var d_str = d_area.value;
if(d_str.length < 1)
return;
f_cleanpoints();
var d_index = 0;
var d_limit = d_str.length;
var d_error = 0;
for(;d_index < d_limit;d_index++)
{//1
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
continue;
d_point = document.createElement("div");
d_field.appendChild(d_point);
if(d_char == 'r')
{
d_point.style.backgroundColor = "red";
d_point.setAttribute("d_mass",d_redmass);
}
else
{//2
if(d_char == 'g')
{
d_point.style.backgroundColor = "green";
d_point.setAttribute("d_mass",d_greenmass);
}
else
{//3
if(d_char != 'b')
{
d_area.value = "unexpected char: " + d_char;
d_error = 1;
break;
}
d_point.style.backgroundColor = "blue";
d_point.setAttribute("d_mass",d_bluemass);
}//3
}//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
{
d_area.value = "wsc expected, not this char: " + d_char;
d_error = 1;
break;
}
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sx is incorrect";
d_error = 1;
break;
}
if(d_num < d_xmin) d_num = d_xmin;
else
{
if(d_num > d_xmax) d_num = d_xmax;
}
d_point.setAttribute("d_sx",Number(d_num));//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sy is incorrect";
d_error = 1;
break;
}
if(d_num < d_ymin) d_num = d_ymin;
else
{
if(d_num > d_ymax) d_num = d_ymax;
}
d_point.setAttribute("d_sy",Number(d_num));//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sz is incorrect";
d_error = 1;
break;
}
if(d_num < d_zmin) d_num = d_zmin;
else
{
if(d_num > d_zmax) d_num = d_zmax;
}
d_point.setAttribute("d_sz",Number(d_num));//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vx is incorrect";
d_error = 1;
break;
}
d_point.setAttribute("d_vx",Number(d_num));
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vy is incorrect";
d_error = 1;
break;
}
d_point.setAttribute("d_vy",Number(d_num));
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_index--;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vz is incorrect";
d_error = 1;
break;
}
d_point.setAttribute("d_vz",Number(d_num));
d_point.style.width = d_pointsize + "px";
d_point.style.height = d_pointsize + "px";
d_point.style.position = "absolute";
}//1
if(d_error == 0)
{
f_showpoints();
return;
}
f_cleanpoints();
return;
}
////// save
function f_save()
{
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
var d_str = "";
for(;;)
{//1
for(;;)
{//2
if(d_point.style.backgroundColor == "red") d_str += "r ";
else
{//3
if(d_point.style.backgroundColor == "green") d_str += "g ";
else
{
if(d_point.style.backgroundColor != "blue")
break;
d_str += "b ";
}
}//3
d_str += d_point.getAttribute("d_sx") + " " + d_point.getAttribute("d_sy") + " " + d_point.getAttribute("d_sz") + "\r\n ";
d_str += d_point.getAttribute("d_vx") + " " + d_point.getAttribute("d_vy") + " " + d_point.getAttribute("d_vz") + "\r\n";
break;
}//2
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}//1
var d_area = document.getElementById("d_modelarea");
d_area.value = d_str;
return;
}
////// zeroimp
function f_zeroimp()
{
var d_pointmass;
var d_firstpoint = d_field.firstChild;
if(d_firstpoint == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
var d_mass = 0;
var d_mvx = 0;
var d_mvy = 0;
var d_mvz = 0;
var d_point = d_firstpoint;
for(;;)
{
d_pointmass = Number(d_point.getAttribute("d_mass"));
d_mass += d_pointmass;
d_mvx += Number(d_point.getAttribute("d_vx")) * d_pointmass;
d_mvy += Number(d_point.getAttribute("d_vy")) * d_pointmass;
d_mvz += Number(d_point.getAttribute("d_vz")) * d_pointmass;
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
if(d_mass <= d_minpos)
return;
d_mvx /= d_mass;
d_mvy /= d_mass;
d_mvz /= d_mass;
d_point = d_firstpoint;
for(;;)
{
d_point.setAttribute("d_vx",Number(d_point.getAttribute("d_vx")) - d_mvx);
d_point.setAttribute("d_vy",Number(d_point.getAttribute("d_vy")) - d_mvy);
d_point.setAttribute("d_vz",Number(d_point.getAttribute("d_vz")) - d_mvz);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}
////// mulekin
function f_mulekin()
{
var d_point = d_field.firstChild;
if(d_point == null)
return;
var d_lastpoint = d_field.lastChild;
if(d_lastpoint == null)
return;
var d_rootmul = Math.sqrt(d_kinmul);
for(;;)
{
d_point.setAttribute("d_vx",Number(d_point.getAttribute("d_vx")) * d_rootmul);
d_point.setAttribute("d_vy",Number(d_point.getAttribute("d_vy")) * d_rootmul);
d_point.setAttribute("d_vz",Number(d_point.getAttribute("d_vz")) * d_rootmul);
if(d_point == d_lastpoint)
break;
d_point = d_point.nextSibling;
}
return;
}
////// create
function f_create()
{
var d_area,d_check;
var d_left,d_top;
d_field = document.createElement("div");
d_field.style.backgroundColor = "white";
d_field.style.color = "black";
d_field.style.left = 0;
d_field.style.top = 0;
d_field.style.width = d_width;
d_field.style.height = d_height;
d_field.style.position = "absolute";
document.body.appendChild(d_field);
d_panel = document.createElement("div");
d_panel.style.backgroundColor = "whiteSmoke";
d_panel.style.color = "black";
d_panel.style.left = d_width;
d_panel.style.top = 0;
d_panel.style.width = d_xspace + d_xsize + d_xspace + d_xsize + d_xspace;
d_panel.style.height = 600;
d_panel.style.position = "absolute";
document.body.appendChild(d_panel);
d_top = d_yspace;
d_left = d_xspace;
f_halflabel("d_widthlabel","width",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_widtharea",d_width,d_left,d_top).onchange = f_width;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_heightlabel","height",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_heightarea",d_height,d_left,d_top).onchange = f_height;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_xminlabel","x minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_xminarea",d_xmin,d_left,d_top).onchange = f_xmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_xmaxlabel","x maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_xmaxarea",d_xmax,d_left,d_top).onchange = f_xmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_yminlabel","y minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_yminarea",d_ymin,d_left,d_top).onchange = f_ymin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_ymaxlabel","y maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_ymaxarea",d_ymax,d_left,d_top).onchange = f_ymax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_zminlabel","z minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_zminarea",d_zmin,d_left,d_top).onchange = f_zmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_zmaxlabel","z maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_zmaxarea",d_zmax,d_left,d_top).onchange = f_zmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_xcloselabel","x closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
d_check = document.createElement("input");
d_check.type = "checkbox";
d_check.id = "d_xclosebox";
d_check.style.left = d_left;
d_check.style.top = d_top;
d_check.style.width = d_ysize;
d_check.style.height = d_ysize;
d_check.style.position = "absolute";
if(d_xclose == 0) d_check.checked = false;
else d_check.checked = true;
d_check.onchange = function() { if(this.checked == false) { d_xclose = 0; return;} d_xclose = 1; return; }//?onclick
d_panel.appendChild(d_check);
d_left += d_ysize + d_xspace;
f_halflabel("d_ycloselabel","y closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
d_check = document.createElement("input");
d_check.type = "checkbox";
d_check.id = "d_yclosebox";
d_check.style.left = d_left;
d_check.style.top = d_top;
d_check.style.width = d_ysize;
d_check.style.height = d_ysize;
d_check.style.position = "absolute";
if(d_yclose == 0) d_check.checked = false;
else d_check.checked = true;
d_check.onchange = function() { if(this.checked == false) { d_yclose = 0; return;} d_yclose = 1; return; }//?onclick
d_panel.appendChild(d_check);
d_left += d_ysize + d_xspace;
f_halflabel("d_zcloselabel","z closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
d_check = document.createElement("input");
d_check.type = "checkbox";
d_check.id = "d_zclosebox";
d_check.style.left = d_left;
d_check.style.top = d_top;
d_check.style.width = d_ysize;
d_check.style.height = d_ysize;
d_check.style.position = "absolute";
if(d_zclose == 0) d_check.checked = false;
else d_check.checked = true;
d_check.onchange = function() { if(this.checked == false) { d_zclose = 0; return;} d_zclose = 1; return; }//?onclick
d_panel.appendChild(d_check);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_label("d_viewdirlabel","view along x,y,z",d_left,d_top);
d_left += d_xsize + d_xspace;
d_radio = document.createElement("input");
d_radio.type = "radio";
d_radio.id = "d_xviewdir";
d_radio.name = "d_viewdir";
d_radio.value = 0;
d_radio.style.left = d_left;
d_radio.style.top = d_top;
d_radio.style.width = d_ysize;
d_radio.style.height = d_ysize;
d_radio.style.position = "absolute";
if(d_viewdir == 0) d_radio.checked = true;
else d_radio.checked = false;
d_radio.onclick = f_viewdir;//?onchange
d_panel.appendChild(d_radio);
d_left += d_ysize + d_xspace;
d_radio = document.createElement("input");
d_radio.type = "radio";
d_radio.id = "d_yviewdir";
d_radio.name = "d_viewdir";
d_radio.value = 1;
d_radio.style.left = d_left;
d_radio.style.top = d_top;
d_radio.style.width = d_ysize;
d_radio.style.height = d_ysize;
d_radio.style.position = "absolute";
if(d_viewdir == 1) d_radio.checked = true;
else d_radio.checked = false;
d_radio.onclick = f_viewdir;//?onchange
d_panel.appendChild(d_radio);
d_left += d_ysize + d_xspace;
d_radio = document.createElement("input");
d_radio.type = "radio";
d_radio.id = "d_zviewdir";
d_radio.name = "d_viewdir";
d_radio.value = 2;
d_radio.style.left = d_left;
d_radio.style.top = d_top;
d_radio.style.width = d_ysize;
d_radio.style.height = d_ysize;
d_radio.style.position = "absolute";
if(d_viewdir == 2) d_radio.checked = true;
else d_radio.checked = false;
d_radio.onclick = f_viewdir;//?onchange
d_panel.appendChild(d_radio);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_minposlabel","min positive",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_minposarea",d_minpos,d_left,d_top).onchange = f_minpos;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_mindistlabel","min distance",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_mindistarea",d_mindist,d_left,d_top).onchange = f_mindist;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_pointsizelabel","point size",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_pointsizearea",d_pointsize,d_left,d_top).onchange = f_pointsize;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_redslabel","red points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_redsarea",d_reds,d_left,d_top).onchange = f_reds;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_greenslabel","green points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_greensarea",d_greens,d_left,d_top).onchange = f_greens;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_blueslabel","blue points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_bluesarea",d_blues,d_left,d_top).onchange = f_blues;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_redmasslabel","red mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_redmassarea",d_redmass,d_left,d_top).onchange = f_redmass;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_xforcelabel","force along x",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_xforcearea",d_xforce,d_left,d_top).onchange = f_xforce;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_greenmasslabel","green mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_greenmassarea",d_greenmass,d_left,d_top).onchange = f_greenmass;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_yforcelabel","force along y",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_yforcearea",d_yforce,d_left,d_top).onchange = f_yforce;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_bluemasslabel","blue mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_bluemassarea",d_bluemass,d_left,d_top).onchange = f_bluemass;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_zforcelabel","force along z",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_zforcearea",d_zforce,d_left,d_top).onchange = f_zforce;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_velmullabel","velocity mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_velmularea",d_velmul,d_left,d_top).onchange = f_velmul;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_kinmullabel","kinetic mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_kinmularea",d_kinmul,d_left,d_top).onchange = f_kinmul;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel("d_msecslabel","step msecs",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_msecsarea",d_msecs,d_left,d_top).onchange = f_msecs;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel("d_timesteplabel","time step",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea("d_timesteparea",d_timestep,d_left,d_top).onchange = f_timestep;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton("d_stepbutton","one step",d_left,d_top).onclick = f_onestep;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_runbutton","run model",d_left,d_top).onclick = f_run;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_pausebutton","pause",d_left,d_top).onclick = f_pause;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_createbutton","create",d_left,d_top).onclick = f_createpoints;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton("d_loadbutton","load",d_left,d_top).onclick = f_load;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_savebutton","save",d_left,d_top).onclick = f_save;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_impbutton","0 impulse",d_left,d_top).onclick = f_zeroimp;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton("d_kinbutton","mul Ekin",d_left,d_top).onclick = f_mulekin;
d_top += d_ysize + d_yspace;
d_area = document.createElement("textarea");
d_area.id = "d_modelarea";
d_area.value = "";
d_area.style.left = d_xspace;
d_area.style.top = d_top;
d_area.style.width = d_xsize * 2;
d_area.style.height = d_ysize * 6;
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_panel.appendChild(d_area);
return;
}

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 03 янв 2023, 11:05 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
Обнаруженные баги и мелкие поправки в скрипте gasideal:
1. наименование d_offset нужно заменить именем d_left
2. вместо d_button = document.createElement("button");
лучше написать var d_button = document.createElement("button");
3. вместо d_button.id = "d_id";
нужно написать d_button.id = d_id;
4. в начале функции f_create вместо var d_area,d_check;
лучше написать var d_area,d_check,d_radio;
5. вместо this.value = d_newreds;
нужно написать this.value = d_reds;

Заново не выкладываю скрипт, так как написал более совершенный
для газов и жидкостей. Использование отдельных объектов вместо
аттрибутов элементов "DIV" с вызовами функций радикально ускорило
исполнение программы, точек может быть и тысяча с хорошей скоростью
обработки взаимодействий. Также внесены многие другие улучшения,
и главное разнообразные алгоритмы движения и взаимодействия.
Проблем тоже много, крайне трудно подобрать адекватные настройки
параметров для алгоритмов, и особенно адекватный шаг времени.
Начальное расположение и скорости точек тоже серьёзно влияют.
Точки двух видов, красные и синие, пока различаются только массой,
взаимодействуют по одинаковым законам.

Скрипт запускается следующим образом:

<HTML>
<HEAD>
<script src="gasliq.txt"></script>
</HEAD>
<BODY>
<noscript style="text-align: center; font-size: 50;">JAVASCRIPT MUST BE TURNED ON</noscript>
<script type="text/javascript">
document.body.style.backgroundColor = "WhiteSmoke";
f_create();
</script>
</BODY>
</HTML>

В файле gasliq.txt, который должен быть в той же папке, содержится остальной код.

Пояснения к интерфейсу:
Целочисленные width и height определяют ширину и высоту модельного поля в пикселах.
Поля x,y,z minimum и maximum задают границы реального объёма.
Отмеченные чекбоксы x,y,z closed показывают замкнутость пространства отдельно
по каждому измерению, в замкнутом вместо отталкивания от "стенок" точка
переходит на другую сторону модельного объёма.
Радио переключатели view along показывают, вдоль какой оси пользователем наблюдается
модельный объём, по умолчанию вдоль z, остальные оси всегда направлены вправо и вниз
(используется правая система координат).
Кнопка methods вызывает интерфейс с настройками взаимодействий, скрывается он
при повторном нажатии этой же кнопки или кнопки hide settings на самом интерфейсе.
Следует учитывать, что текстовые поля реально изменяются не после нажатия клавиши enter,
а после клика мышкой в другом месте.
Поле min positive обозначает минимальную положительную величину, допустимую в расчётах,
в частности, для деления, чтобы знаменатель не был равным нулю.
Поле min distance (требует осторожности) показывает на каком расстоянии (или меньшем)
начинают взаимодействовать точки между собой при упругом отталкивании.
Поля force along x,y,z задают дополнительные силы, действующие вдоль каждого измерения,
если например, задать небольшую положительную (скажем, 0.1) вдоль y, то видно как
"атмосфера" оседает вниз.
Величина point size обозначает размеры точки (квадратика) в пикселах.
Целочисленные red, blue points показывают количество точек каждого вида,
всего возможно два вида: красные и синие.
Далее идут массы точки (mass) по каждому виду.
Поле velocity mul это множитель для скоростей, задаваемых при создании рандомной модели.
Поле kinetic mul используется при нажатии кнопки mul Ekin, чтобы умножить
кинетическую энергию системы на заданное число, то есть фактически уменьшить
или увеличить скорость движения точек и условную "температуру".
Поле msecs показывает как часто (в миллисекундах) вызывается шаг симуляции.
Поле time step это шаг времени, это величина для использования в расчётах обновления
реальных скоростей и положений точек в системе координат.
Кнопка one step делает один шаг в симуляции.
Кнопка run model запускает регулярно повторяемую симуляцию.
Кнопка pause останавливает исполнение.
Кнопка create создаёт рандомную модель с заданными выше настройками.
Кнопки load и save нужны для загрузки и сохранения модели через текстовое поле
внизу панели управления, в формате "буква цвета" + 3 числа для положений x,y,z
+ 3 числа для скоростей x,y,z, числа разделяются одним или многими white-space
символами, к которым относится пробел, табуляция (горизонтальная),
перевод на новую строку и возврат каретки.
Кнопка 0 impulse обнуляет суммарный импульс системы по всем измерениям,
чтобы не было общего дрейфа точек в какую-то сторону.
Кнопка mul Ekin, как написано выше, использует множитель для кинетической энергии
системы точек, изменяет "температуру".
Кнопка get Ekin получает суммарную кинетическую энергию в поле справа.
Кнопка set Ekin загружает из этого поля кинетическую энергию, с соответствующим
уножением скоростей точек, если это математически возможно.
Кнопка get Epot получает суммарную кинетическую энергию в поле справа.

Интерфейс дополнительной панели настроек (вызывается и скрывается кнопкой methods
или скрывается hide settings):
Радио переключатели motion выбирают, используется ли схема Верле, или перемещение
точки зависит от силы, делённой на массу с умножением на квадрат шага времени
и множитель 1 или 1/2. Кстати, по моим наблюдениям, схема Верле даже ухудшает
движение точек, растёт разброс кинетической энергии при осцилляции.
Но при всех вариантах энергия осциллирует, нет безудержного роста или уменьшения
(по крайней мере при упругом отталкивании с дополнительными силами).
Радио переключатели action выбирают упругое отталкивание, схему Леннарда-Джонса,
Букингэма или Морзе.
Поля Johns Emin и Rmin задают минимум энергии в схеме Леннарда-Джонса
(значение энергии положительное, хотя потом по факту будет отрицательное),
и расстояние, на котором энергия взаимодействия минимальная.
Чекбоксы Johns cut и splines показывают, используется ли "отрезание" потенциала
на больших расстояниях, с нулём на расстоянии 2.5 сигмы, и сплайны для приближения.
Поля Buckingham A,B,C задают коэффициенты для exp-6.
Поля Morse Emin и Rmin задают минимум энергии в схеме Морзе и расстояние,
на котором энергия взаимодействия минимальная.
Morse a(exp) множитель для экспоненты.

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 03 янв 2023, 11:08 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
Содержание файла gasliq.txt

////// global data
var d_field;
var p_points = null;
var d_xspace = 5,d_xsize = 200,d_yspace = 5,d_ysize = 20;
var d_panel;
var d_width = 600,d_height = 600;
var d_xmin = -1,d_xmax = 1,d_ymin = -1,d_ymax = 1,d_zmin = 0,d_zmax = 0;
var d_xclose = 0,d_yclose = 0,d_zclose = 0;
var d_viewdir = 2;
var d_minpos = 0.000001;
var d_mindist = 0.03;
var d_xforce = 0,d_yforce = 0,d_zforce = 0;
var d_pointsize = 3;
var d_reds = 100,d_blues = 100;
var d_redmass = 1,d_bluemass = 5;
var d_velmul = 0.1;
var d_kinmul = 0.5;
var d_timer;
var d_msecs = 100;
var d_timestep = 0.1;
var d_ekin = 0;
var d_epot = 0;
var d_colldir = 0;
var d_methods;
var d_motion = 1;//1=dt^2,2=dt^2/2,3=verlet(leapfrog)
var d_action = 1;//1=elastic,2=lennard-johns,3=buckingham,4=morse
var d_johnsemin = 0.01;//?
var d_johnsrmin = 0.01;//?
var d_johnscut = 1;
var d_johnssplines = 0;
var d_bucka = 0.01;//?
var d_buckb = 0.01;//?
var d_buckc = 0.01;//?
var d_morseemin = 0.01;//?
var d_morsermin = 0.01;//?
var d_morseexp = 0.01;//?
////// label
function f_label(d_div,d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = d_xsize + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_div.appendChild(d_label);
return;
}
////// halflabel
function f_halflabel(d_div,d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = (d_xsize / 2) + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_div.appendChild(d_label);
return;
}
////// area
function f_area(d_div,d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = d_xsize + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_div.appendChild(d_area);
return d_area;
}
////// halfarea
function f_halfarea(d_div,d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = (d_xsize / 2) + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_div.appendChild(d_area);
return d_area;
}
////// button
function f_button(d_div,d_id,d_text,d_left,d_top)
{
var d_button = document.createElement("button");
d_button.id = d_id;
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = d_xsize + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.backgroundColor = "whiteSmoke";
d_button.style.color = "black";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_div.appendChild(d_button);
return d_button;
}
////// halfbutton
function f_halfbutton(d_div,d_id,d_text,d_left,d_top)
{
var d_button = document.createElement("button");
d_button.id = d_id;
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = (d_xsize / 2) + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.backgroundColor = "whiteSmoke";
d_button.style.color = "black";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_div.appendChild(d_button);
return d_button;
}
////// check
function f_check(d_div,d_id,d_var,d_left,d_top)
{
var d_check = document.createElement("input");
d_check.type = "checkbox";
d_check.id = d_id;
if(d_var == 0) d_check.checked = false;
else d_check.checked = true;
d_check.style.left = d_left + "px";
d_check.style.top = d_top + "px";
d_check.style.width = d_ysize + "px";
d_check.style.height = d_ysize + "px";
d_check.style.position = "absolute";
d_div.appendChild(d_check);
return d_check;
}
////// radio
function f_radio(d_div,d_id,d_name,d_value,d_var,d_left,d_top)
{
var d_radio = document.createElement("input");
d_radio.type = "radio";
d_radio.id = d_id;
d_radio.name = d_name;
d_radio.value = d_value;
if(d_var == d_value) d_radio.checked = true;
else d_radio.checked = false;
d_radio.style.left = d_left + "px";
d_radio.style.top = d_top + "px";
d_radio.style.width = d_ysize + "px";
d_radio.style.height = d_ysize + "px";
d_radio.style.position = "absolute";
d_div.appendChild(d_radio);
return d_radio;
}
////// width
function f_width()
{
var d_extent,d_left;
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_new == d_width)
return;
d_width = d_new;
d_field.style.width = d_width + "px";
d_panel.style.left = d_width + "px";
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
if(d_viewdir == 0) d_extent = d_ymax - d_ymin;//y right,z down
else
{
if(d_viewdir == 1) d_extent = d_zmax - d_zmin;//z right,x down
else d_extent = d_xmax - d_xmin;//d_viewdir = 2,x right,y down
}
for(;;)
{//4
if(d_extent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else
{//5
if(d_viewdir == 0) d_left = Math.round((((d_point.d_sy - d_ymin) / d_extent) * d_width) - (d_pointsize / 2));
else
{
if(d_viewdir == 1) d_left = Math.round((((d_point.d_sz - d_zmin) / d_extent) * d_width) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sx - d_xmin) / d_extent) * d_width) - (d_pointsize / 2));
}
}//5
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//4
return;
}//3
}//2
}//1
this.value = d_width;
return;
}
////// height
function f_height()
{
var d_extent,d_top;
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_new == d_height)
return;
d_height = d_new;
d_field.style.height = d_height + "px";
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
if(d_viewdir == 0) d_extent = d_zmax - d_zmin;//y right,z down
else
{
if(d_viewdir == 1) d_extent = d_xmax - d_xmin;//z right,x down
else d_extent = d_ymax - d_ymin;//d_viewdir = 2,x right,y down
}
for(;;)
{//4
if(d_extent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else
{//5
if(d_viewdir == 0) d_top = Math.round((((d_point.d_sz - d_zmin) / d_extent) * d_height) - (d_pointsize / 2));
else
{
if(d_viewdir == 1) d_top = Math.round((((d_point.d_sx - d_xmin) / d_extent) * d_height) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sy - d_ymin) / d_extent) * d_height) - (d_pointsize / 2));
}
}//5
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//4
return;
}//3
}//2
}//1
this.value = d_height;
return;
}
////// cleanpoints
function f_cleanpoints()
{
var d_nextdiv;
var d_nextpoint;
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
for(;;)
{
d_nextdiv = d_div.nextSibling;
d_nextpoint = d_point.d_nextpoint;
d_field.removeChild(d_div);
delete d_point;//?
if(d_nextpoint == null)
break;
d_div = d_nextdiv;
d_point = d_nextpoint;
}
p_points = null;
return;
}
////// xmin
function f_xmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_xmax)
{
if(d_new == d_xmin)
return;
d_xmin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_xmin;
return;
}
////// xmax
function f_xmax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_xmin)
{
if(d_new == d_xmax)
return;
d_xmax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_xmax;
return;
}
////// ymin
function f_ymin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_ymax)
{
if(d_new == d_ymin)
return;
d_ymin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_ymin;
return;
}
////// ymax
function f_ymax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_ymin)
{
if(d_new == d_ymax)
return;
d_ymax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_ymax;
return;
}
////// zmin
function f_zmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_zmax)
{
if(d_new == d_zmin)
return;
d_zmin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_zmin;
return;
}
////// zmax
function f_zmax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_zmin)
{
if(d_new == d_zmax)
return;
d_zmax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_zmax;
return;
}
////// showpoints
function f_showpoints()
{
var d_left,d_top;
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
var d_xextent = d_xmax - d_xmin;
var d_yextent = d_ymax - d_ymin;
var d_zextent = d_zmax - d_zmin;
for(;;)
{//1
if(d_viewdir == 0)//y right,z down
{
if(d_yextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sy - d_ymin) / d_yextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_zextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sz - d_zmin) / d_zextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
else
{//2
if(d_viewdir == 1)//z right,x down
{
if(d_zextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sz - d_zmin) / d_zextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_xextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sx - d_xmin) / d_xextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
else
{
//d_viewdir = 2,x right,y down
if(d_xextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sx - d_xmin) / d_xextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_yextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sy - d_ymin) / d_yextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
}//2
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//1
return;
}
////// viewdir
function f_viewdir()
{
var d_new = Number(this.value);
if(d_new == d_viewdir)
return;
d_viewdir = d_new;
f_showpoints();
return;
}
////// methods
function f_methods()
{
if(d_methods.style.visibility == "visible")
{
d_methods.style.visibility = "hidden";
return;
}
d_methods.style.visibility = "visible";
return;
}
////// minpos
function f_minpos()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_minpos) d_minpos = d_new;
return;
}
}//1
this.value = d_minpos;
return;
}
////// mindist
function f_mindist()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_mindist) d_mindist = d_new;
return;
}
}//1
this.value = d_mindist;
return;
}
////// xforce
function f_xforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_xforce) d_xforce = d_new;
return;
}
this.value = d_xforce;
return;
}
////// yforce
function f_yforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_yforce) d_yforce = d_new;
return;
}
this.value = d_yforce;
return;
}
////// zforce
function f_zforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_zforce) d_zforce = d_new;
return;
}
this.value = d_zforce;
return;
}
////// pointsize
function f_pointsize()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_newpointsize == d_pointsize)
return;
d_pointsize = d_new;
var d_div = d_field.firstChild;
if(d_div == null)
return;
var d_lastdiv = d_field.lastChild;
if(d_lastdiv == null)
return;
for(;;)
{
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
if(d_div == d_lastdiv)
break;
d_div = d_div.nextSibling;
}
f_showpoints();
return;
}//3
}//2
}//1
this.value = d_pointsize;
return;
}
////// reds
function f_reds()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new == d_reds)
return;
d_reds = d_new;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_reds;
return;
}
////// blues
function f_blues()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new == d_blues)
return;
d_blues = d_new;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_blues;
return;
}
////// redmass
function f_redmass()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == d_redmass)
return;
d_redmass = d_new;
if(p_points == null)
return;
var d_point = p_points;
for(;;)
{
if(d_point.d_type == 1) d_point.d_mass = d_redmass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}//2
}//1
this.value = d_redmass;
return;
}
////// bluemass
function f_bluemass()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == d_bluemass)
return;
d_bluemass = d_new;
if(p_points == null)
return;
var d_point = p_points;
for(;;)
{
if(d_point.d_type == 2) d_point.d_mass = d_bluemass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}//2
}//1
this.value = d_bluemass;
return;
}
////// velmul
function f_velmul()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_velmul) d_velmul = d_new;
return;
}
}//1
this.value = d_velmul;
return;
}
////// kinmul
function f_kinmul()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_kinmul) d_kinmul = d_new;
return;
}
}//1
this.value = d_kinmul;
return;
}
////// msecs
function f_msecs()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new != d_msecs) d_msecs = d_new;
return;
}
}//2
}//1
this.value = d_msecs;
return;
}
////// timestep
function f_timestep()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_timestep) d_timestep = d_new;
return;
}
}//1
this.value = d_timestep;
return;
}
////// adjustpoint
function f_adjustpoint(d_div,d_point)
{
var d_sx,d_sy,d_sz;
var d_dx,d_dy,d_dz;
var d_left,d_top;
var d_xextent = d_xmax - d_xmin;
if(d_xextent <= d_minpos) d_point.d_sx = (d_xmin + d_xmax) / 2;
else
{//1
d_sx = d_point.d_sx;
if(d_sx < d_xmin)
{//2
d_dx = d_xmin - d_sx;
d_dx -= Math.floor(d_dx / d_xextent) * d_xextent;
if(d_xclose != 0) d_sx = d_xmax - d_dx;
else
{
d_sx = d_xmin + d_dx;
if(d_point.d_vx < 0) d_point.d_vx = - d_point.d_vx;
}
d_point.d_sx = d_sx;
}//2
else
{//2
if(d_sx > d_xmax)
{//3
d_dx = d_sx - d_xmax;
d_dx -= Math.floor(d_dx / d_xextent) * d_xextent;
if(d_xclose != 0) d_sx = d_xmin + d_dx;
else
{
d_sx = d_xmax - d_dx;
if(d_point.d_vx > 0) d_point.d_vx = - d_point.d_vx;
}
d_point.d_sx = d_sx;
}//3
}//2
}//1
var d_yextent = d_ymax - d_ymin;
if(d_yextent <= d_minpos) d_point.d_sy = (d_ymin + d_ymax) / 2;
else
{//1
d_sy = d_point.d_sy;
if(d_sy < d_ymin)
{//2
d_dy = d_ymin - d_sy;
d_dy -= Math.floor(d_dy / d_yextent) * d_yextent;
if(d_yclose != 0) d_sy = d_ymax - d_dy;
else
{
d_sy = d_ymin + d_dy;
if(d_point.d_vy < 0) d_point.d_vy = - d_point.d_vy;
}
d_point.d_sy = d_sy;
}//2
else
{//2
if(d_sy > d_ymax)
{//3
d_dy = d_sy - d_ymax;
d_dy -= Math.floor(d_dy / d_yextent) * d_yextent;
if(d_yclose != 0) d_sy = d_ymin + d_dy;
else
{
d_sy = d_ymax - d_dy;
if(d_point.d_vy > 0) d_point.d_vy = - d_point.d_vy;
}
d_point.d_sy = d_sy;
}//3
}//2
}//1
var d_zextent = d_zmax - d_zmin;
if(d_zextent <= d_minpos) d_point.d_sz = (d_zmin + d_zmax) / 2;
else
{//1
d_sz = d_point.d_sz;
if(d_sz < d_zmin)
{//2
d_dz = d_zmin - d_sz;
d_dz -= Math.floor(d_dz / d_zextent) * d_zextent;
if(d_zclose != 0) d_sz = d_zmax - d_dz;
else
{
d_sz = d_zmin + d_dz;
if(d_point.d_vz < 0) d_point.d_vz = - d_point.d_vz;
}
d_point.d_sz = d_sz;
}//2
else
{//2
if(d_sz > d_zmax)
{//3
d_dz = d_sz - d_zmax;
d_dz -= Math.floor(d_dz / d_zextent) * d_zextent;
if(d_zclose != 0) d_sz = d_zmin + d_dz;
else
{
d_sz = d_zmax - d_dz;
if(d_point.d_vz > 0) d_point.d_vz = - d_point.d_vz;
}
d_point.d_sz = d_sz;
}//3
}//2
}//1
if(d_viewdir == 0)//y right,z down
{
if(d_yextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sy - d_ymin) / d_yextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_zextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sz - d_zmin) / d_zextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
if(d_viewdir == 1)//z right,x down
{
if(d_zextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sz - d_zmin) / d_zextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_xextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sx - d_xmin) / d_xextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
//d_viewdir = 2,x right,y down
if(d_xextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sx - d_xmin) / d_xextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_yextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sy - d_ymin) / d_yextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
////// simplestep
function f_simplestep()
{
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
for(;;)
{
d_point.d_sx += d_point.d_vx * d_timestep;
d_point.d_sy += d_point.d_vy * d_timestep;
d_point.d_sz += d_point.d_vz * d_timestep;
f_adjustpoint(d_div,d_point);
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}
return;
}
////// actelastic
//interaction axis is drawen from first point to second
//v1 - v2 always > 0, collision force F > 0
//v1'(new) = v1(old) - dt * F / m1, v2'(new) = v2(old) + dt * F / m2
//kinetic energy (/2): m1 * v1'^2 + m2 * v2'^2 = m1 * v1^2 + m2 * v2^2
//F * dt = m1 * m2 * 2 * (v1 - v2) / (m1 + m2)
function f_actelastic(d_point1,d_point2)
{
var d_cosx,d_cosy,d_cosz;
var d_dx = d_point2.d_sx - d_point1.d_sx;
var d_dy = d_point2.d_sy - d_point1.d_sy;
var d_dz = d_point2.d_sz - d_point1.d_sz;
var d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist > d_mindist)
return;
if(d_dist < d_minpos)
{//1
if(d_colldir == 0)
{
d_cosx = 1;
d_cosy = 0;
d_cosz = 0;
}
else
{//2
if(d_colldir == 1)
{
d_cosx = 0;
d_cosy = 1;
d_cosz = 0;
}
else
{
d_cosx = 0;
d_cosy = 0;
d_cosz = 1;
}
}//2
d_colldir++;
if(d_colldir > 2) d_colldir = 0;
}//1
else
{
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosz = d_dz / d_dist;
}
var d_v1 = (d_point1.d_vx * d_cosx) + ((d_point1.d_vy * d_cosy) + (d_point1.d_vz * d_cosz));
var d_v2 = (d_point2.d_vx * d_cosx) + ((d_point2.d_vy * d_cosy) + (d_point2.d_vz * d_cosz));
if(d_v1 <= d_v2)
return;
var d_m1 = d_point1.d_mass;
var d_m2 = d_point2.d_mass;
var d_vmul = (2 * (d_v1 - d_v2)) / (d_m1 + d_m2);
var d_vmul1 = d_m2 * d_vmul;
var d_vmul2 = d_m1 * d_vmul;
d_point1.d_vx -= d_vmul1 * d_cosx;
d_point1.d_vy -= d_vmul1 * d_cosy;
d_point1.d_vz -= d_vmul1 * d_cosz;
d_point2.d_vx += d_vmul2 * d_cosx;
d_point2.d_vy += d_vmul2 * d_cosy;
d_point2.d_vz += d_vmul2 * d_cosz;
return;
}
////// interact
function f_interact(d_point1,d_point2,d_addepot)
{
var d_cosx,d_cosy,d_cosz;
var d_force;
var d_rc,d_rmindivrpow6;
var d_dx = d_point2.d_sx - d_point1.d_sx;
var d_dy = d_point2.d_sy - d_point1.d_sy;
var d_dz = d_point2.d_sz - d_point1.d_sz;
var d_dist2 = (d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz));
var d_dist = Math.sqrt(d_dist2);
if(d_dist < d_minpos)
{//1
var d_minposmul2 = d_minpos * 2;
if(d_colldir == 0)
{
d_point2.d_sx = d_point1.d_sx + d_minpos;
d_point1.d_sx -= d_minpos;
d_point2.d_sy = d_point1.d_sy;
d_point2.d_sz = d_point1.d_sz;
d_cosx = 1; d_cosy = 0; d_cosz = 0;
}
else
{//2
if(d_colldir == 1)
{
d_point2.d_sx = d_point1.d_sx;
d_point2.d_sy = d_point1.d_sy + d_minpos;
d_point1.d_sy -= d_minpos;
d_point2.d_sz = d_point1.d_sz;
d_cosx = 0; d_cosy = 1; d_cosz = 0;
}
else
{
d_point2.d_sx = d_point1.d_sx;
d_point2.d_sy = d_point1.d_sy;
d_point2.d_sz = d_point1.d_sz + d_minpos;
d_point1.d_sz -= d_minpos;
d_cosx = 0; d_cosy = 0; d_cosz = 1;
}
}//2
d_colldir++;
if(d_colldir > 2) d_colldir = 0;
d_dist = d_minposmul2;
}//1
else
{
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosz = d_dz / d_dist;
}
for(;;)
{//1
if(d_action == 4)//morse
{
var d_exp = Math.exp( - (d_morseexp * (d_dist - d_morsermin)));
d_force = (d_morseemin * (2 * d_morseexp)) * (d_exp * (d_exp - 1));
if(d_addepot == 0)
break;
d_epot += (d_morseemin * d_exp) * (d_exp - 2);
break;
}
if(d_action == 3)//buckingham
{
var d_num1 = d_bucka * Math.exp(- (d_buckb * d_dist));
var d_num2 = d_buckc / Math.pow(d_dist,6);
d_force = (d_buckb * d_num1) - ((6 / d_dist) * d_num2);
if(d_addepot == 0)
break;
d_epot += d_num1 - d_num2;
break;
}
if(d_action != 2)
return;
//lennard-johns
if(d_johnscut != 0)
{
d_rc = d_johnsrmin * (2.5 / Math.pow(2,1/6));
if(d_dist > d_rc)
return;
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
d_force = (d_johnsemin * (12 / d_dist)) * (d_rmindivrpow6 * (d_rmindivrpow6 - 1));
if(d_addepot == 0)
break;
var d_04pow6 = Math.pow(0.4,6);
d_epot += d_johnsemin * ((d_rmindivrpow6 * (d_rmindivrpow6 - 2)) - (4 * (d_04pow6 * (d_04pow6 - 1))));
break;
}
else
{//2
if(d_johnssplines != 0)
{//3
var d_rs = d_johnsrmin * Math.pow(13/7,1/6);
d_rc = d_rs * (67/48);
if(d_dist > d_rc)
return;
if(d_dist > d_rs)
{
var d_rs2 = d_rs * d_rs;
var d_k3 = - ((387072/61009) / (d_rs2 * d_rs));
var d_k2 = - ((24192/3211) / d_rs2);
var d_dif = d_dist - d_rc;
var d_dif2 = d_dif * d_dif;
d_force = (- d_johnsemin) * (((3 * d_k3) * d_dif2) + ((2 * d_k2) * d_dif));
if(d_addepot == 0)
break;
d_epot += d_johnsemin * ((d_k3 * (d_dif2 * d_dif)) + (d_k2 * d_dif2));
break;
}
}//3
}//2
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
d_force = (d_johnsemin * (12 / d_dist)) * (d_rmindivrpow6 * (d_rmindivrpow6 - 1));
if(d_addepot == 0)
break;
d_epot += d_johnsemin * (d_rmindivrpow6 * (d_rmindivrpow6 - 2));
break;
}//1
var d_xforce = d_force * d_cosx;
var d_yforce = d_force * d_cosy;
var d_zforce = d_force * d_cosz;
d_point1.d_fx -= d_xforce;
d_point1.d_fy -= d_yforce;
d_point1.d_fz -= d_zforce;
d_point2.d_fx += d_xforce;
d_point2.d_fy += d_yforce;
d_point2.d_fz += d_zforce;
return;
}
////// process
function f_process()
{
var d_div;
var d_point1,d_point2;
var d_mass,d_fmul,d_amul,d_vmul,d_pos;
if(p_points == null)
return;
var d_firstdiv = d_field.firstChild;
d_epot = 0;
if(d_action == 1)//elastic
{//1
//interactions between points
d_point1 = p_points;
for(;;)
{
//no interaction twice
for(d_point2 = d_point1.d_nextpoint;d_point2 != null;d_point2 = d_point2.d_nextpoint) f_actelastic(d_point1,d_point2);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}
d_div = d_firstdiv;
d_point1 = p_points;
if(d_motion == 1) d_fmul = d_timestep * d_timestep;
else
{
if(d_motion == 2) d_fmul = (d_timestep * d_timestep) / 2;
else d_fmul = 0;
}
for(;;)
{//2
d_point1.d_sx += d_point1.d_vx * d_timestep;
d_point1.d_sy += d_point1.d_vy * d_timestep;
d_point1.d_sz += d_point1.d_vz * d_timestep;
d_mass = d_point1.d_mass;
if(d_mass >= d_minpos)
{
d_vmul = d_timestep / d_mass;
d_point1.d_vx += d_xforce * d_vmul;
d_point1.d_vy += d_yforce * d_vmul;
d_point1.d_vz += d_zforce * d_vmul;
d_amul = d_fmul / d_mass;
d_point1.d_sx += d_xforce * d_amul;
d_point1.d_sy += d_yforce * d_amul;
d_point1.d_sz += d_zforce * d_amul;
}
f_adjustpoint(d_div,d_point1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
d_div = d_div.nextSibling;
}//2
return;
}//1
d_point1 = p_points;
for(;;)
{
d_point1.d_fx = d_xforce;
d_point1.d_fy = d_yforce;
d_point1.d_fz = d_zforce;
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}
//interactions between points
d_point1 = p_points;
for(;;)
{
//no interaction twice
for(d_point2 = d_point1.d_nextpoint;d_point2 != null;d_point2 = d_point2.d_nextpoint) f_interact(d_point1,d_point2,1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}
if(d_motion == 3)//verlet(leapfrog)
{//1
d_div = d_firstdiv;
d_point1 = p_points;
d_fmul = d_timestep * d_timestep;
for(;;)
{
d_mass = d_point1.d_mass;
if(d_mass >= d_minpos) d_amul = d_fmul / d_mass;
else d_amul = 0;
d_pos = d_point1.d_sx;
d_point1.d_sx = ((2 * d_pos) - d_point1.d_tx) + (d_point1.d_fx * d_amul);
d_point1.d_tx = d_pos;
d_point1.d_vx = (d_point1.d_sx - d_pos) / d_timestep;
d_pos = d_point1.d_sy;
d_point1.d_sy = ((2 * d_pos) - d_point1.d_ty) + (d_point1.d_fy * d_amul);
d_point1.d_ty = d_pos;
d_point1.d_vy = (d_point1.d_sy - d_pos) / d_timestep;
d_pos = d_point1.d_sz;
d_point1.d_sz = ((2 * d_pos) - d_point1.d_tz) + (d_point1.d_fz * d_amul);
d_point1.d_tz = d_pos;
d_point1.d_vz = (d_point1.d_sz - d_pos) / d_timestep;
f_adjustpoint(d_div,d_point1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
d_div = d_div.nextSibling;
}
return;
}//1
d_div = d_firstdiv;
d_point1 = p_points;
if(d_motion == 1) d_fmul = d_timestep * d_timestep;
else
{
if(d_motion == 2) d_fmul = (d_timestep * d_timestep) / 2;
else d_fmul = 0;
}
for(;;)
{//1
d_point1.d_sx += d_point1.d_vx * d_timestep;
d_point1.d_sy += d_point1.d_vy * d_timestep;
d_point1.d_sz += d_point1.d_vz * d_timestep;
d_mass = d_point1.d_mass;
if(d_mass >= d_minpos)
{
d_vmul = d_timestep / d_mass;
d_point1.d_vx += d_point1.d_fx * d_vmul;
d_point1.d_vy += d_point1.d_fy * d_vmul;
d_point1.d_vz += d_point1.d_fz * d_vmul;
d_amul = d_fmul / d_mass;
d_point1.d_sx += d_point1.d_fx * d_amul;
d_point1.d_sy += d_point1.d_fy * d_amul;
d_point1.d_sz += d_point1.d_fz * d_amul;
}
f_adjustpoint(d_div,d_point1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
d_div = d_div.nextSibling;
}//1
return;
}
////// step
function f_step()
{
//?f_simplestep();
f_process();//?
return;
}
////// run
function f_run()
{
d_timer = window.setInterval(f_step,d_msecs);
return;
}
////// pause
function f_pause()
{
window.clearInterval(d_timer);
return;
}
////// verlet
function f_verlet()
{
if(p_points == null)
return;
var d_point = p_points;
for(;;)
{
d_point.d_tx = d_point.d_sx;
d_point.d_ty = d_point.d_sy;
d_point.d_tz = d_point.d_sz;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// createpoints
function f_createpoints()
{
var d_index,d_limit;
var d_div;
var d_point,d_prevpoint;
var d_x,d_y,d_z;
var d_w,d_h
var d_left,d_top;
f_cleanpoints();
var d_dx = d_xmax - d_xmin;
var d_dy = d_ymax - d_ymin;
var d_dz = d_zmax - d_zmin;
d_limit = d_reds;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = new Object();//?
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.d_sx = d_xmin + (d_x * d_dx);
d_point.d_sy = d_ymin + (d_y * d_dy);
d_point.d_sz = d_zmin + (d_z * d_dz);
d_point.d_vx = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vy = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vz = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_mass = d_redmass;
d_point.d_type = 1;
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
delete d_point;//?
d_div = document.createElement("div");
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
d_div.style.backgroundColor = "red";
d_field.appendChild(d_div);
}//1
d_limit = d_blues;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = new Object();//?
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.d_sx = d_xmin + (d_x * d_dx);
d_point.d_sy = d_ymin + (d_y * d_dy);
d_point.d_sz = d_zmin + (d_z * d_dz);
d_point.d_vx = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vy = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vz = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_mass = d_bluemass;
d_point.d_type = 2;
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
delete d_point;//?
d_div = document.createElement("div");
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
d_div.style.backgroundColor = "blue";
d_field.appendChild(d_div);
}//1
if(d_motion == 3) f_verlet();
return;
}
////// testwsc
function f_testwsc(d_char)
{
if(d_char != ' ')
{//1
if(d_char != '\t')
{//2
if(d_char != '\r')
{
if(d_char != '\n')
return 0;
}
}//2
}//1
return 1;
}
////// load
function f_load()
{
var d_char,d_num,d_numstr;
var d_div;
var d_point,d_prevpoint;
var d_area = document.getElementById("d_modelarea");
var d_str = d_area.value;
if(d_str.length < 1)
return;
f_cleanpoints();
var d_index = 0;
var d_limit = d_str.length;
var d_error = 0;
for(;d_index < d_limit;d_index++)
{//1
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
continue;
d_div = document.createElement("div");
d_field.appendChild(d_div);
d_point = new Object();//?
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
if(d_char == 'r')
{
d_div.style.backgroundColor = "red";
d_point.d_mass = d_redmass;
d_point.d_type = 1;
}
else
{//2
if(d_char != 'b')
{
d_area.value = "unexpected char: " + d_char;
d_error = 1;
break;
}
d_div.style.backgroundColor = "blue";
d_point.d_mass = d_bluemass;
d_point.d_type = 2;
}//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
{
d_area.value = "wsc expected, not this char: " + d_char;
d_error = 1;
break;
}
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sx is incorrect";
d_error = 1;
break;
}
if(d_num < d_xmin) d_num = d_xmin;
else
{
if(d_num > d_xmax) d_num = d_xmax;
}
d_point.d_sx = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sy is incorrect";
d_error = 1;
break;
}
if(d_num < d_ymin) d_num = d_ymin;
else
{
if(d_num > d_ymax) d_num = d_ymax;
}
d_point.d_sy = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sz is incorrect";
d_error = 1;
break;
}
if(d_num < d_zmin) d_num = d_zmin;
else
{
if(d_num > d_zmax) d_num = d_zmax;
}
d_point.d_sz = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vx is incorrect";
d_error = 1;
break;
}
d_point.d_vx = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vy is incorrect";
d_error = 1;
break;
}
d_point.d_vy = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_index--;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vz is incorrect";
d_error = 1;
break;
}
d_point.d_vz = Number(d_num);//?Number
delete d_point;//?
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
}//1
if(d_error == 0)
{
if(d_motion == 3) f_verlet();
f_showpoints();
return;
}
f_cleanpoints();
return;
}
////// save
function f_save()
{
if(p_points == null)
return;
var d_point = p_points;
var d_str = "";
for(;;)
{//1
for(;;)
{//2
if(d_point.d_type == 1) d_str += "r ";
else
{
if(d_point.d_type != 2)
break;
d_str += "b ";
}
d_str += d_point.d_sx + " " + d_point.d_sy + " " + d_point.d_sz + "\r\n ";
d_str += d_point.d_vx + " " + d_point.d_vy + " " + d_point.d_vz + "\r\n";
break;
}//2
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}//1
var d_area = document.getElementById("d_modelarea");
d_area.value = d_str;
return;
}
////// zeroimp
function f_zeroimp()
{
var d_pointmass;
if(p_points == null)
return;
var d_mass = 0;
var d_mvx = 0;
var d_mvy = 0;
var d_mvz = 0;
var d_point = p_points;
for(;;)
{
d_pointmass = d_point.d_mass;
d_mass += d_pointmass;
d_mvx += d_point.d_vx * d_pointmass;
d_mvy += d_point.d_vy * d_pointmass;
d_mvz += d_point.d_vz * d_pointmass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
if(d_mass < d_minpos)
return;
d_mvx /= d_mass;
d_mvy /= d_mass;
d_mvz /= d_mass;
d_point = p_points;
for(;;)
{
d_point.d_vx -= d_mvx;
d_point.d_vy -= d_mvy;
d_point.d_vz -= d_mvz;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// mulekin
function f_mulekin()
{
if(p_points == null)
return;
var d_point = p_points;
var d_rootmul = Math.sqrt(d_kinmul);
for(;;)
{
d_point.d_vx *= d_rootmul;
d_point.d_vy *= d_rootmul;
d_point.d_vz *= d_rootmul;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// getekin
function f_getekin()
{
if(p_points == null)
return;
var d_point = p_points;
var d_newekin = 0;
for(;;)
{
d_newekin += (d_point.d_mass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
var d_area = document.getElementById("d_ekinarea");
if(Number.isFinite(d_newekin) == 0)
{
d_area.value = "infinity";
return;
}
d_area.value = d_newekin;
d_ekin = d_newekin;
return;
}
////// setekin
function f_setekin()
{
if(p_points == null)
return;
var d_area = document.getElementById("d_ekinarea");
var d_newekin = Number(d_area.value);
if(Number.isFinite(d_newekin) == 0)
return;
if(d_newekin < d_minpos)
return;
var d_point = p_points;
var d_oldekin = 0;
for(;;)
{
d_oldekin += (d_point.d_mass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
if(Number.isFinite(d_oldekin) == 0)
return;
if(d_oldekin < d_minpos)
return;
var d_rootmul = Math.sqrt(d_newekin / d_oldekin);
if(Number.isFinite(d_rootmul) == 0)
return;
d_point = p_points;
for(;;)
{
d_point.d_vx *= d_rootmul;
d_point.d_vy *= d_rootmul;
d_point.d_vz *= d_rootmul;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
d_ekin = d_newekin;
return;
}
////// getepot
function f_getepot()
{
var d_area = document.getElementById("d_epotarea");
if(Number.isFinite(d_epot) == 0)
{
d_area.value = "undefined";
return;
}
d_area.value = d_epot;
return;
}
////// motion
function f_motion()
{
var d_new = Number(this.value);
if(d_new == d_motion)
return;
d_motion = d_new;
if(d_motion == 3) f_verlet();
return;
}
////// action
function f_action()
{
var d_new = Number(this.value);
if(d_new == d_action)
return;
d_action = d_new;
return;
}
////// johnsemin
function f_johnsemin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_johnsemin) d_johnsemin = d_new;
return;
}
}//1
this.value = d_johnsemin;
return;
}
////// johnsrmin
function f_johnsrmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_johnsrmin) d_johnsrmin = d_new;
return;
}
}//1
this.value = d_johnsrmin;
return;
}
////// bucka
function f_bucka()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_bucka) d_bucka = d_new;
return;
}
}//1
this.value = d_bucka;
return;
}
////// buckb
function f_buckb()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_buckb) d_buckb = d_new;
return;
}
}//1
this.value = d_buckb;
return;
}
////// buckc
function f_buckc()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_buckc) d_buckc = d_new;
return;
}
}//1
this.value = d_buckc;
return;
}
////// morseemin
function f_morseemin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morseemin) d_morseemin = d_new;
return;
}
}//1
this.value = d_morseemin;
return;
}
////// morsermin
function f_morsermin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morsermin) d_morsermin = d_new;
return;
}
}//1
this.value = d_morsermin;
return;
}
////// morseexp
function f_morseexp()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morseexp) d_morseexp = d_new;
return;
}
}//1
this.value = d_morseexp;
return;
}
////// create
function f_create()
{
var d_area;
var d_left,d_top;
d_field = document.createElement("div");
d_field.style.left = 0 + "px";
d_field.style.top = 0 + "px";
d_field.style.width = d_width + "px";
d_field.style.height = d_height + "px";
d_field.style.position = "absolute";
d_field.style.backgroundColor = "white";
d_field.style.color = "black";
document.body.appendChild(d_field);
d_panel = document.createElement("div");
d_panel.style.left = d_width + "px";
d_panel.style.top = 0 + "px";
d_panel.style.width = (d_xspace + d_xsize + d_xspace + d_xsize + d_xspace + 20) + "px";
d_panel.style.height = 600 + "px";
d_panel.style.position = "absolute";
d_panel.style.backgroundColor = "whiteSmoke";
d_panel.style.color = "black";
document.body.appendChild(d_panel);
d_top = d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_widthlabel","width",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_widtharea",d_width,d_left,d_top).onchange = f_width;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_heightlabel","height",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_heightarea",d_height,d_left,d_top).onchange = f_height;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xminlabel","x minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xminarea",d_xmin,d_left,d_top).onchange = f_xmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_xmaxlabel","x maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xmaxarea",d_xmax,d_left,d_top).onchange = f_xmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_yminlabel","y minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_yminarea",d_ymin,d_left,d_top).onchange = f_ymin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_ymaxlabel","y maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_ymaxarea",d_ymax,d_left,d_top).onchange = f_ymax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_zminlabel","z minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zminarea",d_zmin,d_left,d_top).onchange = f_zmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_zmaxlabel","z maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zmaxarea",d_zmax,d_left,d_top).onchange = f_zmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xcloselabel","x closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_xclosecheck",d_xclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_xclose = 0; return; } d_xclose = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_panel,"d_ycloselabel","y closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_yclosecheck",d_yclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_yclose = 0; return; } d_yclose = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_panel,"d_zcloselabel","z closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_zclosecheck",d_zclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_zclose = 0; return; } d_zclose = 1; return; }//?onclick
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_label(d_panel,"d_viewdirlabel","view along x,y,z",d_left,d_top);
d_left += d_xsize + d_xspace;
f_radio(d_panel,"d_xviewdirradio","d_viewdir",0,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += d_ysize + d_xspace;
f_radio(d_panel,"d_yviewdirradio","d_viewdir",1,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += d_ysize + d_xspace;
f_radio(d_panel,"d_zviewdirradio","d_viewdir",2,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += (d_ysize * 2) + d_xspace;
f_halfbutton(d_panel,"d_methodsbutton","methods",d_left,d_top).onclick = f_methods;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_minposlabel","min positive",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_minposarea",d_minpos,d_left,d_top).onchange = f_minpos;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_mindistlabel","min distance",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_mindistarea",d_mindist,d_left,d_top).onchange = f_mindist;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xforcelabel","force along x",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xforcearea",d_xforce,d_left,d_top).onchange = f_xforce;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_yforcelabel","force along y",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_yforcearea",d_yforce,d_left,d_top).onchange = f_yforce;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_zforcelabel","force along z",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zforcearea",d_zforce,d_left,d_top).onchange = f_zforce;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_pointsizelabel","point size",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_pointsizearea",d_pointsize,d_left,d_top).onchange = f_pointsize;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_redslabel","red points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_redsarea",d_reds,d_left,d_top).onchange = f_reds;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_blueslabel","blue points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_bluesarea",d_blues,d_left,d_top).onchange = f_blues;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_redmasslabel","red mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_redmassarea",d_redmass,d_left,d_top).onchange = f_redmass;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_bluemasslabel","blue mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_bluemassarea",d_bluemass,d_left,d_top).onchange = f_bluemass;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_velmullabel","velocity mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_velmularea",d_velmul,d_left,d_top).onchange = f_velmul;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_kinmullabel","kinetic mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_kinmularea",d_kinmul,d_left,d_top).onchange = f_kinmul;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_msecslabel","msecs",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_msecsarea",d_msecs,d_left,d_top).onchange = f_msecs;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_timesteplabel","time step",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_timesteparea",d_timestep,d_left,d_top).onchange = f_timestep;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_stepbutton","one step",d_left,d_top).onclick = f_step;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_runbutton","run model",d_left,d_top).onclick = f_run;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_pausebutton","pause",d_left,d_top).onclick = f_pause;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_createbutton","create",d_left,d_top).onclick = f_createpoints;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_loadbutton","load",d_left,d_top).onclick = f_load;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_savebutton","save",d_left,d_top).onclick = f_save;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_zeroimpbutton","0 impulse",d_left,d_top).onclick = f_zeroimp;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_mulekinbutton","mul Ekin",d_left,d_top).onclick = f_mulekin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_getekinbutton","get Ekin",d_left,d_top).onclick = f_getekin;
d_left += (d_xsize / 2) + d_xspace;
f_area(d_panel,"d_ekinarea",d_ekin,d_left,d_top);
d_left += d_xsize + d_xspace;
f_halfbutton(d_panel,"d_setekinbutton","set Ekin",d_left,d_top).onclick = f_setekin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_getepotbutton","get Epot",d_left,d_top).onclick = f_getepot;
d_left += (d_xsize / 2) + d_xspace;
f_area(d_panel,"d_epotarea",d_epot,d_left,d_top);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
d_area = document.createElement("textarea");
d_area.id = "d_modelarea";
d_area.value = "";
d_area.style.left = d_xspace + "px";
d_area.style.top = d_top + "px";
d_area.style.width = (d_xsize * 2) + "px";
d_area.style.height = (d_ysize * 6) + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_panel.appendChild(d_area);
d_methods = document.createElement("div");
d_methods.style.left = 0 + "px";
d_methods.style.top = 0; + "px"
d_methods.style.width = (d_xspace + d_xsize + d_xspace + d_xsize + d_xspace + 20) + "px";
d_methods.style.height = 300 + "px";
d_methods.style.position = "absolute";
d_methods.style.backgroundColor = "whiteSmoke";
d_methods.style.color = "black";
d_methods.style.visibility = "hidden";
document.body.appendChild(d_methods);
d_top = d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_motionlabel","motion",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_dt2label","dt^2",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_dt2radio","d_motionradio",1,d_motion,d_left,d_top).onclick = f_motion;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_dt2div2label","dt^2 / 2",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_dt2div2radio","d_motionradio",2,d_motion,d_left,d_top).onclick = f_motion;//?onchange
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_verletlabel","Verlet",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_verletradio","d_motionradio",3,d_motion,d_left,d_top).onclick = f_motion;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_actionlabel","action",d_left,d_top);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_elasticlabel","elastic",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_elasticradio","d_actionradio",1,d_action,d_left,d_top).onclick = f_action;//?onchange
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_johnslabel","Lennard-Johns",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_johnsradio","d_actionradio",2,d_action,d_left,d_top).onclick = f_action;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_bucklabel","Buckingham",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_buckradio","d_actionradio",3,d_action,d_left,d_top).onclick = f_action;//?onchange
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_morselabel","Morse",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_morseradio","d_actionradio",4,d_action,d_left,d_top).onclick = f_action;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_johnseminlabel","Johns Emin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_johnseminarea",d_johnsemin,d_left,d_top).onchange = f_johnsemin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_johnsrminlabel","Johns Rmin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_johnsrminarea",d_johnsrmin,d_left,d_top).onchange = f_johnsrmin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_johnscut","Johns cut",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_methods,"d_johnscutcheck",d_johnscut,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_johnscut = 0; return; } d_johnscut = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_johnssplines","Johns splines",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_methods,"d_johnssplinescheck",d_johnssplines,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_johnssplines = 0; return; } d_johnssplines = 1; return; }//?onclick
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_buckalabel","Buckingham A",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckaarea",d_bucka,d_left,d_top).onchange = f_bucka;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_buckblabel","Buckingham B",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckbarea",d_bucka,d_left,d_top).onchange = f_buckb;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_buckclabel","Buckingham C",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckcarea",d_buckc,d_left,d_top).onchange = f_buckc;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_morseeminlabel","Morse Emin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morseeminarea",d_morseemin,d_left,d_top).onchange = f_morseemin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_morserminlabel","Morse Rmin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morserminarea",d_morsermin,d_left,d_top).onchange = f_morsermin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_morseexplabel","Morse a (exp)",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morseexparea",d_morseexp,d_left,d_top).onchange = f_morseexp;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_button(d_methods,"d_hidebutton","hide settings",d_left,d_top).onclick = function() { d_methods.style.visibility = "hidden"; return; }
return;
}


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

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 04 янв 2023, 09:52 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
Очень разочаровала схема Верле. По размаху осцилляций кинетической энергии системы мало отличается от расчётов с использованием скорости. Провёл тесты с настройками по умолчанию + дополнительная сила 0.01 вдоль оси y. Лучшие результаты (минимум колебаний энергии) получены при схеме s = s + v * dt + f / m * dt^2, второе место у схемы Верле, наихудшая s = s + v * dt + f / m * dt^2 / 2. Схема с прогнозом и коррекцией реализована не была, так как очень требовательна к ресурсам, пришлось бы повторно проходить взаимодействие всех точек со всеми. Но вряд ли была бы радикально лучше при резком изменении потенциала и сил отталкивания точек вблизи друг друга. Эдакая средняя температура по палате, и достаточно чуть увеличить шаг времени, чтобы система пошла вразнос. А если делать движение слишком медленным, долго придётся ждать результатов. Кажется вообще не стоит использовать схемы с силами как градиентами потенциала, лучше использовать сам потенциал с более строгим сохранением энергии, а о сохранении имульса меньше заботиться.

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 11 янв 2023, 12:34 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

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

Выкладываю программу на Javascript для моделирования движения точек, представляющих собой молекулы газа или жидкости.
Скрипт запускается следующим образом (эти строки можно поместить в файл с расширением .htm или .html):

<HTML>
<HEAD>
<script src="gasliq3.txt"></script>
</HEAD>
<BODY>
<noscript style="text-align: center; font-size: 50;">JAVASCRIPT MUST BE TURNED ON</noscript>
<script type="text/javascript">
document.body.style.backgroundColor = "WhiteSmoke";
f_create();
</script>
</BODY>
</HTML>

В файле gasliq3.txt, который должен быть в той же папке, содержится остальной код.

Пояснения к интерфейсу:
Целочисленные width и height определяют ширину и высоту модельного поля в пикселах.
Поля x,y,z minimum и maximum задают границы реального объёма.
Отмеченные чекбоксы x,y,z closed показывают замкнутость пространства отдельно
по каждому измерению (работает не во всех режимах), в замкнутом вместо отталкивания
от "стенок" точка переходит на другую сторону модельного объёма.
Радио переключатели view along показывают, вдоль какой оси пользователь наблюдает
модельный объём, по умолчанию вдоль z, остальные оси всегда направлены вправо и вниз
(используется правая система координат).
Кнопка methods вызывает интерфейс с настройками взаимодействий, скрывается он
при повторном нажатии этой же кнопки или кнопки hide settings на самом интерфейсе.
Следует учитывать, что текстовые поля реально изменяются не после нажатия клавиши enter,
а после клика мышкой в другом месте.
Поле min positive обозначает минимальную положительную величину, допустимую в расчётах,
в частности, для деления, чтобы знаменатель не был равным нулю.
Поле min distance (требует осторожности) показывает на каком расстоянии (или меньшем)
начинают взаимодействовать точки между собой при упругом отталкивании.
Поля force along x,y,z задают дополнительные силы, действующие вдоль каждого измерения,
если например, задать небольшую положительную (скажем, 0.1) вдоль y, то видно
как "атмосфера" оседает вниз. Энергия системы при этом может значительно колебаться.
Величина point size обозначает размеры точки (квадратика) в пикселах.
Целочисленные red, blue points показывают количество точек каждого вида, всего два вида:
красные и синие, различаются только массой, взаимодействуют по одинаковым законам.
Далее идут массы точки (mass) по каждому виду.
Поле velocity mul это множитель для скоростей, задаваемых при создании рандомной модели.
Поле kinetic mul используется при нажатии кнопки mul Ekin, чтобы умножить
кинетическую энергию системы на заданное число, то есть фактически уменьшить
или увеличить скорость движения точек и условную "температуру".
Поле msecs показывает как часто (в миллисекундах) вызывается шаг симуляции.
Поле time step это шаг времени, это величина для использования в расчётах обновления
реальных скоростей и положений точек в системе координат.
Кнопка one step делает один шаг в симуляции.
Кнопка run model запускает регулярно повторяемую симуляцию.
Кнопка pause останавливает исполнение.
Кнопка create создаёт рандомную модель с заданными выше настройками.
Кнопки load и save нужны для загрузки и сохранения модели через текстовое поле
внизу панели управления, в формате "буква цвета" + 3 числа для положений x,y,z
+ 3 числа для скоростей x,y,z, числа разделяются одним или многими white-space
символами, к которым относится пробел, табуляция (горизонтальная),
перевод на новую строку и возврат каретки.
Кнопка 0 impulse обнуляет суммарный импульс системы по всем измерениям,
чтобы не было общего дрейфа точек в какую-то сторону.
Кнопка mul Ekin, как написано выше, использует множитель для кинетической энергии
системы точек, изменяет "температуру".
Кнопка get Ekin получает суммарную кинетическую энергию в поле справа.
Кнопка set Ekin загружает из этого поля кинетическую энергию, с соответствующим
уножением скоростей точек, если это математически возможно.
Кнопка get Epot получает суммарную потенциальную энергию в поле справа.
Кнопка get energy получает суммарную энергию в поле справа.

Интерфейс дополнительной панели настроек (вызывается и скрывается кнопкой methods
или скрывается hide settings):
Радио переключатели выбирают упругое отталкивание, схему Леннарда-Джонса,
Букингэма или Морзе.
Поля Johns Emin и Rmin задают минимум энергии в схеме Леннарда-Джонса
(значение энергии положительное, хотя потом по факту будет отрицательное),
и расстояние, на котором энергия взаимодействия минимальная.
Чекбоксы Johns cut и splines показывают, используется ли "отрезание" потенциала
на больших расстояниях, с нулём на расстоянии 2.5 сигмы, и сплайны для приближения.
Поля Buckingham A,B,C задают коэффициенты для exp-6.
Поля Morse Emin и Rmin задают минимум энергии в схеме Морзе и расстояние,
на котором энергия взаимодействия минимальная.
Morse a(exp) множитель для экспоненты.

Настройки по умолчанию могут быть не лучшими, экспериментируйте.

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 11 янв 2023, 12:34 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
////// global data
var d_field;
var p_points = null;
var d_xspace = 5,d_xsize = 200,d_yspace = 5,d_ysize = 20;
var d_panel;
var d_width = 600,d_height = 600;
var d_xmin = -1,d_xmax = 1,d_ymin = -1,d_ymax = 1,d_zmin = 0,d_zmax = 0;
var d_xclose = 0,d_yclose = 0,d_zclose = 0;
var d_viewdir = 2;
var d_minpos = 0.000001;
var d_mindist = 0.03;
var d_xforce = 0,d_yforce = 0,d_zforce = 0;
var d_pointsize = 3;
var d_reds = 20,d_blues = 20;
var d_redmass = 1,d_bluemass = 5;
var d_velmul = 0.1;
var d_kinmul = 0.5;
var d_timer;
var d_msecs = 100;
var d_timestep = 0.05;
var d_colldir = 0;
var d_methods;
var d_action = 1;//1=elastic,2=lennard-johns,3=buckingham,4=morse
var d_johnsemin = 0.1;//?
var d_johnsrmin = 0.1;//?
var d_johnscut = 1;
var d_johnssplines = 0;
var d_bucka = 0.01;//?
var d_buckb = 0.01;//?
var d_buckc = 0.01;//?
var d_morseemin = 0.01;//?
var d_morsermin = 0.05;//?
var d_morseexp = 0.01;//?
////// label
function f_label(d_div,d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = d_xsize + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_div.appendChild(d_label);
return;
}
////// halflabel
function f_halflabel(d_div,d_id,d_text,d_left,d_top)
{
var d_label = document.createElement("div");
d_label.id = d_id;
d_label.innerText = d_text;
d_label.style.left = d_left + "px";
d_label.style.top = d_top + "px";
d_label.style.width = (d_xsize / 2) + "px";
d_label.style.height = d_ysize + "px";
d_label.style.position = "absolute";
d_label.style.backgroundColor = "whiteSmoke";
d_label.style.color = "black";
d_label.style.FontSize = 16;
d_label.style.textAlign = "center";
d_div.appendChild(d_label);
return;
}
////// area
function f_area(d_div,d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = d_xsize + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_div.appendChild(d_area);
return d_area;
}
////// halfarea
function f_halfarea(d_div,d_id,d_text,d_left,d_top)
{
var d_area = document.createElement("textarea");
d_area.id = d_id;
d_area.value = d_text;
d_area.style.left = d_left + "px";
d_area.style.top = d_top + "px";
d_area.style.width = (d_xsize / 2) + "px";
d_area.style.height = d_ysize + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_div.appendChild(d_area);
return d_area;
}
////// button
function f_button(d_div,d_id,d_text,d_left,d_top)
{
var d_button = document.createElement("button");
d_button.id = d_id;
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = d_xsize + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.backgroundColor = "whiteSmoke";
d_button.style.color = "black";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_div.appendChild(d_button);
return d_button;
}
////// halfbutton
function f_halfbutton(d_div,d_id,d_text,d_left,d_top)
{
var d_button = document.createElement("button");
d_button.id = d_id;
d_button.innerText = d_text;
d_button.style.left = d_left + "px";
d_button.style.top = d_top + "px";
d_button.style.width = (d_xsize / 2) + "px";
d_button.style.height = d_ysize + "px";
d_button.style.position = "absolute";
d_button.style.backgroundColor = "whiteSmoke";
d_button.style.color = "black";
d_button.style.FontSize = 16;
d_button.style.textAlign = "center";
d_div.appendChild(d_button);
return d_button;
}
////// check
function f_check(d_div,d_id,d_var,d_left,d_top)
{
var d_check = document.createElement("input");
d_check.type = "checkbox";
d_check.id = d_id;
if(d_var == 0) d_check.checked = false;
else d_check.checked = true;
d_check.style.left = d_left + "px";
d_check.style.top = d_top + "px";
d_check.style.width = d_ysize + "px";
d_check.style.height = d_ysize + "px";
d_check.style.position = "absolute";
d_div.appendChild(d_check);
return d_check;
}
////// radio
function f_radio(d_div,d_id,d_name,d_value,d_var,d_left,d_top)
{
var d_radio = document.createElement("input");
d_radio.type = "radio";
d_radio.id = d_id;
d_radio.name = d_name;
d_radio.value = d_value;
if(d_var == d_value) d_radio.checked = true;
else d_radio.checked = false;
d_radio.style.left = d_left + "px";
d_radio.style.top = d_top + "px";
d_radio.style.width = d_ysize + "px";
d_radio.style.height = d_ysize + "px";
d_radio.style.position = "absolute";
d_div.appendChild(d_radio);
return d_radio;
}
////// width
function f_width()
{
var d_extent,d_left;
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_new == d_width)
return;
d_width = d_new;
d_field.style.width = d_width + "px";
d_panel.style.left = d_width + "px";
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
if(d_viewdir == 0) d_extent = d_ymax - d_ymin;//y right,z down
else
{
if(d_viewdir == 1) d_extent = d_zmax - d_zmin;//z right,x down
else d_extent = d_xmax - d_xmin;//d_viewdir = 2,x right,y down
}
for(;;)
{//4
if(d_extent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else
{//5
if(d_viewdir == 0) d_left = Math.round((((d_point.d_sy - d_ymin) / d_extent) * d_width) - (d_pointsize / 2));
else
{
if(d_viewdir == 1) d_left = Math.round((((d_point.d_sz - d_zmin) / d_extent) * d_width) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sx - d_xmin) / d_extent) * d_width) - (d_pointsize / 2));
}
}//5
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//4
return;
}//3
}//2
}//1
this.value = d_width;
return;
}
////// height
function f_height()
{
var d_extent,d_top;
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_new == d_height)
return;
d_height = d_new;
d_field.style.height = d_height + "px";
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
if(d_viewdir == 0) d_extent = d_zmax - d_zmin;//y right,z down
else
{
if(d_viewdir == 1) d_extent = d_xmax - d_xmin;//z right,x down
else d_extent = d_ymax - d_ymin;//d_viewdir = 2,x right,y down
}
for(;;)
{//4
if(d_extent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else
{//5
if(d_viewdir == 0) d_top = Math.round((((d_point.d_sz - d_zmin) / d_extent) * d_height) - (d_pointsize / 2));
else
{
if(d_viewdir == 1) d_top = Math.round((((d_point.d_sx - d_xmin) / d_extent) * d_height) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sy - d_ymin) / d_extent) * d_height) - (d_pointsize / 2));
}
}//5
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//4
return;
}//3
}//2
}//1
this.value = d_height;
return;
}
////// cleanpoints
function f_cleanpoints()
{
var d_nextdiv;
var d_nextpoint;
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
for(;;)
{
d_nextdiv = d_div.nextSibling;
d_nextpoint = d_point.d_nextpoint;
d_field.removeChild(d_div);
delete d_point;//?
if(d_nextpoint == null)
break;
d_div = d_nextdiv;
d_point = d_nextpoint;
}
p_points = null;
return;
}
////// xmin
function f_xmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_xmax)
{
if(d_new == d_xmin)
return;
d_xmin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_xmin;
return;
}
////// xmax
function f_xmax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_xmin)
{
if(d_new == d_xmax)
return;
d_xmax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_xmax;
return;
}
////// ymin
function f_ymin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_ymax)
{
if(d_new == d_ymin)
return;
d_ymin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_ymin;
return;
}
////// ymax
function f_ymax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_ymin)
{
if(d_new == d_ymax)
return;
d_ymax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_ymax;
return;
}
////// zmin
function f_zmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new <= d_zmax)
{
if(d_new == d_zmin)
return;
d_zmin = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_zmin;
return;
}
////// zmax
function f_zmax()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= d_zmin)
{
if(d_new == d_zmax)
return;
d_zmax = d_new;
f_cleanpoints();
return;
}
}//1
this.value = d_zmax;
return;
}
////// showpoints
function f_showpoints()
{
var d_left,d_top;
if(p_points == null)
return;
var d_div = d_field.firstChild;
var d_point = p_points;
var d_xextent = d_xmax - d_xmin;
var d_yextent = d_ymax - d_ymin;
var d_zextent = d_zmax - d_zmin;
for(;;)
{//1
if(d_viewdir == 0)//y right,z down
{
if(d_yextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sy - d_ymin) / d_yextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_zextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sz - d_zmin) / d_zextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
else
{//2
if(d_viewdir == 1)//z right,x down
{
if(d_zextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sz - d_zmin) / d_zextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_xextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sx - d_xmin) / d_xextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
else
{
//d_viewdir = 2,x right,y down
if(d_xextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_point.d_sx - d_xmin) / d_xextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_yextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_point.d_sy - d_ymin) / d_yextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
}
}//2
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
d_div = d_div.nextSibling;
}//1
return;
}
////// viewdir
function f_viewdir()
{
var d_new = Number(this.value);
if(d_new == d_viewdir)
return;
d_viewdir = d_new;
f_showpoints();
return;
}
////// methods
function f_methods()
{
if(d_methods.style.visibility == "visible")
{
d_methods.style.visibility = "hidden";
return;
}
d_methods.style.visibility = "visible";
return;
}
////// minpos
function f_minpos()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_minpos) d_minpos = d_new;
return;
}
}//1
this.value = d_minpos;
return;
}
////// mindist
function f_mindist()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_mindist) d_mindist = d_new;
return;
}
}//1
this.value = d_mindist;
return;
}
////// xforce
function f_xforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_xforce) d_xforce = d_new;
return;
}
this.value = d_xforce;
return;
}
////// yforce
function f_yforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_yforce) d_yforce = d_new;
return;
}
this.value = d_yforce;
return;
}
////// zforce
function f_zforce()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{
if(d_new != d_zforce) d_zforce = d_new;
return;
}
this.value = d_zforce;
return;
}
////// pointsize
function f_pointsize()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{//3
if(d_newpointsize == d_pointsize)
return;
d_pointsize = d_new;
var d_div = d_field.firstChild;
if(d_div == null)
return;
var d_lastdiv = d_field.lastChild;
if(d_lastdiv == null)
return;
for(;;)
{
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
if(d_div == d_lastdiv)
break;
d_div = d_div.nextSibling;
}
f_showpoints();
return;
}//3
}//2
}//1
this.value = d_pointsize;
return;
}
////// reds
function f_reds()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new == d_reds)
return;
d_reds = d_new;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_reds;
return;
}
////// blues
function f_blues()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new >= 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new == d_blues)
return;
d_blues = d_new;
f_cleanpoints();
return;
}
}//2
}//1
this.value = d_blues;
return;
}
////// redmass
function f_redmass()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == d_redmass)
return;
d_redmass = d_new;
if(p_points == null)
return;
var d_point = p_points;
for(;;)
{
if(d_point.d_type == 1) d_point.d_mass = d_redmass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}//2
}//1
this.value = d_redmass;
return;
}
////// bluemass
function f_bluemass()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == d_bluemass)
return;
d_bluemass = d_new;
if(p_points == null)
return;
var d_point = p_points;
for(;;)
{
if(d_point.d_type == 2) d_point.d_mass = d_bluemass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}//2
}//1
this.value = d_bluemass;
return;
}
////// velmul
function f_velmul()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_velmul) d_velmul = d_new;
return;
}
}//1
this.value = d_velmul;
return;
}
////// kinmul
function f_kinmul()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_kinmul) d_kinmul = d_new;
return;
}
}//1
this.value = d_kinmul;
return;
}
////// msecs
function f_msecs()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{//2
if(d_new == Math.round(d_new))
{
if(d_new != d_msecs) d_msecs = d_new;
return;
}
}//2
}//1
this.value = d_msecs;
return;
}
////// timestep
function f_timestep()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_timestep) d_timestep = d_new;
return;
}
}//1
this.value = d_timestep;
return;
}
////// adjustpoint
function f_adjustpoint(d_div,d_point)
{
var d_sx,d_sy,d_sz;
var d_dx,d_dy,d_dz;
var d_left,d_top;
var d_xextent = d_xmax - d_xmin;
if(d_xextent <= d_minpos) d_point.d_sx = (d_xmin + d_xmax) / 2;
else
{//1
d_sx = d_point.d_sx;
if(d_sx < d_xmin)
{//2
d_dx = d_xmin - d_sx;
d_dx -= Math.floor(d_dx / d_xextent) * d_xextent;
if(d_xclose != 0) d_sx = d_xmax - d_dx;
else
{
d_sx = d_xmin + d_dx;
if(d_point.d_vx < 0) d_point.d_vx = - d_point.d_vx;
}
d_point.d_sx = d_sx;
}//2
else
{//2
if(d_sx > d_xmax)
{//3
d_dx = d_sx - d_xmax;
d_dx -= Math.floor(d_dx / d_xextent) * d_xextent;
if(d_xclose != 0) d_sx = d_xmin + d_dx;
else
{
d_sx = d_xmax - d_dx;
if(d_point.d_vx > 0) d_point.d_vx = - d_point.d_vx;
}
d_point.d_sx = d_sx;
}//3
}//2
}//1
var d_yextent = d_ymax - d_ymin;
if(d_yextent <= d_minpos) d_point.d_sy = (d_ymin + d_ymax) / 2;
else
{//1
d_sy = d_point.d_sy;
if(d_sy < d_ymin)
{//2
d_dy = d_ymin - d_sy;
d_dy -= Math.floor(d_dy / d_yextent) * d_yextent;
if(d_yclose != 0) d_sy = d_ymax - d_dy;
else
{
d_sy = d_ymin + d_dy;
if(d_point.d_vy < 0) d_point.d_vy = - d_point.d_vy;
}
d_point.d_sy = d_sy;
}//2
else
{//2
if(d_sy > d_ymax)
{//3
d_dy = d_sy - d_ymax;
d_dy -= Math.floor(d_dy / d_yextent) * d_yextent;
if(d_yclose != 0) d_sy = d_ymin + d_dy;
else
{
d_sy = d_ymax - d_dy;
if(d_point.d_vy > 0) d_point.d_vy = - d_point.d_vy;
}
d_point.d_sy = d_sy;
}//3
}//2
}//1
var d_zextent = d_zmax - d_zmin;
if(d_zextent <= d_minpos) d_point.d_sz = (d_zmin + d_zmax) / 2;
else
{//1
d_sz = d_point.d_sz;
if(d_sz < d_zmin)
{//2
d_dz = d_zmin - d_sz;
d_dz -= Math.floor(d_dz / d_zextent) * d_zextent;
if(d_zclose != 0) d_sz = d_zmax - d_dz;
else
{
d_sz = d_zmin + d_dz;
if(d_point.d_vz < 0) d_point.d_vz = - d_point.d_vz;
}
d_point.d_sz = d_sz;
}//2
else
{//2
if(d_sz > d_zmax)
{//3
d_dz = d_sz - d_zmax;
d_dz -= Math.floor(d_dz / d_zextent) * d_zextent;
if(d_zclose != 0) d_sz = d_zmin + d_dz;
else
{
d_sz = d_zmax - d_dz;
if(d_point.d_vz > 0) d_point.d_vz = - d_point.d_vz;
}
d_point.d_sz = d_sz;
}//3
}//2
}//1
if(d_viewdir == 0)//y right,z down
{
if(d_yextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sy - d_ymin) / d_yextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_zextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sz - d_zmin) / d_zextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
if(d_viewdir == 1)//z right,x down
{
if(d_zextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sz - d_zmin) / d_zextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_xextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sx - d_xmin) / d_xextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
//d_viewdir = 2,x right,y down
if(d_xextent <= d_minpos) d_left = Math.round((d_width / 2) - (d_pointsize / 2));
else d_left = Math.round((((d_sx - d_xmin) / d_xextent) * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
if(d_yextent <= d_minpos) d_top = Math.round((d_height / 2) - (d_pointsize / 2));
else d_top = Math.round((((d_sy - d_ymin) / d_yextent) * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
return;
}
////// elastic
//interaction axis is drawen from first point to second
//v1 - v2 always > 0, collision force F > 0
//v1'(new) = v1(old) - dt * F / m1, v2'(new) = v2(old) + dt * F / m2
//kinetic energy (/2): m1 * v1'^2 + m2 * v2'^2 = m1 * v1^2 + m2 * v2^2
//F * dt = m1 * m2 * 2 * (v1 - v2) / (m1 + m2)
function f_elastic(d_point1,d_point2)
{
var d_sign,d_cosx,d_cosy,d_cosz;
var d_dx = d_point2.d_sx - d_point1.d_sx;
var d_dy = d_point2.d_sy - d_point1.d_sy;
var d_dz = d_point2.d_sz - d_point1.d_sz;
var d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist > d_mindist)
return;
if(d_dist < d_minpos)
{//1
if(Math.random() >= 0.5) d_sign = 1;
else d_sign = -1;
if(d_colldir == 0) { d_cosx = d_sign; d_cosy = 0; d_cosz = 0; }
else
{
if(d_colldir == 1) { d_cosx = 0; d_cosy = d_sign; d_cosz = 0; }
else { d_cosx = 0; d_cosy = 0; d_cosz = d_sign; }
}
d_colldir++;
if(d_colldir > 2) d_colldir = 0;
}//1
else
{
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosz = d_dz / d_dist;
}
var d_v1 = (d_point1.d_vx * d_cosx) + ((d_point1.d_vy * d_cosy) + (d_point1.d_vz * d_cosz));
var d_v2 = (d_point2.d_vx * d_cosx) + ((d_point2.d_vy * d_cosy) + (d_point2.d_vz * d_cosz));
if(d_v1 <= d_v2)
return;
var d_m1 = d_point1.d_mass;
var d_m2 = d_point2.d_mass;
var d_vmul = (2 * (d_v1 - d_v2)) / (d_m1 + d_m2);
var d_vmul1 = d_m2 * d_vmul;
var d_vmul2 = d_m1 * d_vmul;
d_point1.d_vx -= d_vmul1 * d_cosx;
d_point1.d_vy -= d_vmul1 * d_cosy;
d_point1.d_vz -= d_vmul1 * d_cosz;
d_point2.d_vx += d_vmul2 * d_cosx;
d_point2.d_vy += d_vmul2 * d_cosy;
d_point2.d_vz += d_vmul2 * d_cosz;
return;
}
////// force12
function f_force12(d_dist)
{
var d_rc,d_rmindivrpow6;
if(d_action == 4)//morse
{
var d_exp = Math.exp(- (d_morseexp * (d_dist - d_morsermin)));
return (d_morseemin * (2 * d_morseexp)) * (d_exp * (d_exp - 1));
}
if(d_action == 3)//buckingham
{
var d_num1 = d_bucka * Math.exp(- (d_buckb * d_dist));
var d_num2 = d_buckc / Math.pow(d_dist,6);
return (d_buckb * d_num1) - ((6 / d_dist) * d_num2);
}
if(d_action != 2)
return 0;
//lennard-johns
if(d_johnscut != 0)
{
d_rc = d_johnsrmin * (2.5 / Math.pow(2,1/6));
if(d_dist > d_rc)
return 0;
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
return (d_johnsemin * (12 / d_dist)) * (d_rmindivrpow6 * (d_rmindivrpow6 - 1));
}
if(d_johnssplines != 0)
{//1
var d_rs = d_johnsrmin * Math.pow(13/7,1/6);
d_rc = d_rs * (67/48);
if(d_dist > d_rc)
return 0;
if(d_dist > d_rs)
{
var d_rs2 = d_rs * d_rs;
var d_k3 = - ((387072/61009) / (d_rs2 * d_rs));
var d_k2 = - ((24192/3211) / d_rs2);
var d_dif = d_dist - d_rc;
var d_dif2 = d_dif * d_dif;
return (- d_johnsemin) * (((3 * d_k3) * d_dif2) + ((2 * d_k2) * d_dif));
}
}//1
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
return (d_johnsemin * (12 / d_dist)) * (d_rmindivrpow6 * (d_rmindivrpow6 - 1));
}
////// upot12
function f_upot12(d_dist)
{
var d_rc,d_rmindivrpow6;
if(d_action == 4)//morse
{
var d_exp = Math.exp(- (d_morseexp * (d_dist - d_morsermin)));
return (d_morseemin * d_exp) * (d_exp - 2);
}
if(d_action == 3)//buckingham
return (d_bucka * Math.exp(- (d_buckb * d_dist))) - (d_buckc / Math.pow(d_dist,6));
if(d_action != 2)
return;
//lennard-johns
if(d_johnscut != 0)
{
d_rc = d_johnsrmin * (2.5 / Math.pow(2,1/6));
if(d_dist > d_rc)
return 0;
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
var d_04pow6 = Math.pow(0.4,6);
return d_johnsemin * ((d_rmindivrpow6 * (d_rmindivrpow6 - 2)) - (4 * (d_04pow6 * (d_04pow6 - 1))));
}
if(d_johnssplines != 0)
{//1
var d_rs = d_johnsrmin * Math.pow(13/7,1/6);
d_rc = d_rs * (67/48);
if(d_dist > d_rc)
return 0;
if(d_dist > d_rs)
{
var d_rs2 = d_rs * d_rs;
var d_k3 = - ((387072/61009) / (d_rs2 * d_rs));
var d_k2 = - ((24192/3211) / d_rs2);
var d_dif = d_dist - d_rc;
var d_dif2 = d_dif * d_dif;
return d_johnsemin * ((d_k3 * (d_dif2 * d_dif)) + (d_k2 * d_dif2));
}
}//1
d_rmindivrpow6 = Math.pow(d_johnsrmin / d_dist,6);
return d_johnsemin * (d_rmindivrpow6 * (d_rmindivrpow6 - 2));
}
////// impekin
function f_impekin()
{
var d_pointmass;
if(p_points == null)
return;
var d_mass = 0;
var d_mvx = 0;
var d_mvy = 0;
var d_mvz = 0;
var d_oldekin = 0;
var d_point = p_points;
for(;;)
{
d_pointmass = d_point.d_mass;
d_mass += d_pointmass;
d_mvx += d_point.d_vx * d_pointmass;
d_mvy += d_point.d_vy * d_pointmass;
d_mvz += d_point.d_vz * d_pointmass;
d_oldekin += (d_pointmass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
if(Number.isFinite(d_oldekin) == 0)
return;
if(d_oldekin < d_minpos)
return;
d_mvx /= d_mass;
d_mvy /= d_mass;
d_mvz /= d_mass;
var d_newekin = 0;
d_point = p_points;
for(;;)
{
d_point.d_vx -= d_mvx;
d_point.d_vy -= d_mvy;
d_point.d_vz -= d_mvz;
d_newekin += (d_point.d_mass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
if(Number.isFinite(d_newekin) == 0)
return;
if(d_newekin < d_minpos)
return;
var d_rootmul = Math.sqrt(d_oldekin / d_newekin);
if(Number.isFinite(d_rootmul) == 0)
return;
d_point = p_points;
for(;;)
{
d_point.d_vx *= d_rootmul;
d_point.d_vy *= d_rootmul;
d_point.d_vz *= d_rootmul;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// process
function f_process()
{
var d_div;
var d_point1,d_point2;
var d_mass,d_fmul,d_amul,d_vmul;
var d_sx0,d_sy0,d_sz0;
var d_sx,d_sy,d_sz;
var d_vx,d_vy,d_vz;
var d_vx2,d_vy2,d_vz2;
var d_fx,d_fy,d_fz;
var d_f,d_u1,d_u2,d_du;
var d_dx,d_dy,d_dz,d_dist;
var d_sign,d_cosx,d_cosy,d_cosz;
var d_signx,d_signy,d_signz;
if(p_points == null)
return;
var d_firstdiv = d_field.firstChild;
if(d_action == 1)//elastic
{//1
//interactions between points
d_point1 = p_points;
for(;;)
{
//no interaction twice
for(d_point2 = d_point1.d_nextpoint;d_point2 != null;d_point2 = d_point2.d_nextpoint) f_elastic(d_point1,d_point2);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}
d_div = d_firstdiv;
d_point1 = p_points;
d_fmul = (d_timestep * d_timestep) / 2;
for(;;)
{
d_point1.d_sx += d_point1.d_vx * d_timestep;
d_point1.d_sy += d_point1.d_vy * d_timestep;
d_point1.d_sz += d_point1.d_vz * d_timestep;
d_mass = d_point1.d_mass;
d_amul = d_fmul / d_mass;
d_point1.d_sx += d_xforce * d_amul;
d_point1.d_sy += d_yforce * d_amul;
d_point1.d_sz += d_zforce * d_amul;
d_vmul = d_timestep / d_mass;
d_point1.d_vx += d_xforce * d_vmul;
d_point1.d_vy += d_yforce * d_vmul;
d_point1.d_vz += d_zforce * d_vmul;
f_adjustpoint(d_div,d_point1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
d_div = d_div.nextSibling;
}
return;
}//1
d_div = d_firstdiv;
d_point1 = p_points;
d_fmul = (d_timestep * d_timestep) / 2;
for(;;)
{//1
d_sx0 = d_point1.d_sx;
d_sy0 = d_point1.d_sy;
d_sz0 = d_point1.d_sz;
d_fx = d_xforce;
d_fy = d_yforce;
d_fz = d_zforce;
d_u1 = 0;
for(d_point2 = p_points;d_point2 != null;d_point2 = d_point2.d_nextpoint)
{//2
if(d_point2 == d_point1)
continue;
d_dx = d_point2.d_sx - d_sx0;
d_dy = d_point2.d_sy - d_sy0;
d_dz = d_point2.d_sz - d_sz0;
d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist < d_minpos)
{//3
if(Math.random() >= 0.5) d_sign = 1;
else d_sign = -1;
if(d_colldir == 0) { d_cosx = d_sign; d_cosy = 0; d_cosz = 0; }
else
{
if(d_colldir == 1) { d_cosx = 0; d_cosy = d_sign; d_cosz = 0; }
else { d_cosx = 0; d_cosy = 0; d_cosz = d_sign; }
}
d_colldir++;
if(d_colldir > 2) d_colldir = 0;
d_dist = d_minpos;
}//3
else
{
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosz = d_dz / d_dist;
}
d_f = f_force12(d_dist);
d_fx -= d_f * d_cosx;
d_fy -= d_f * d_cosy;
d_fz -= d_f * d_cosz;
d_u1 += f_upot12(d_dist);
}//2
d_mass = d_point1.d_mass;
d_amul = d_fmul / d_mass;
d_vx = d_point1.d_vx;
d_vy = d_point1.d_vy;
d_vz = d_point1.d_vz;
d_sx = (d_sx0 + (d_vx * d_timestep)) + (d_fx * d_amul);
d_sy = (d_sy0 + (d_vy * d_timestep)) + (d_fy * d_amul);
d_sz = (d_sz0 + (d_vz * d_timestep)) + (d_fz * d_amul);
if(d_sx < d_xmin) d_sx = d_xmin;
else
{
if(d_sx > d_xmax) d_sx = d_xmax;
}
if(d_sy < d_ymin) d_sy = d_ymin;
else
{
if(d_sy > d_ymax) d_sy = d_ymax;
}
if(d_sz < d_zmin) d_sz = d_zmin;
else
{
if(d_sz > d_zmax) d_sz = d_zmax;
}
d_dx = d_sx - d_sx0;
d_dy = d_sy - d_sy0;
d_dz = d_sz - d_sz0;
d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist >= d_minpos)
{//2
d_cosx = d_dx / d_dist;
d_cosy = d_dy / d_dist;
d_cosx = d_dx / d_dist;
d_u2 = 0;
for(d_point2 = p_points;d_point2 != null;d_point2 = d_point2.d_nextpoint)
{
if(d_point2 == d_point1)
continue;
d_dx = d_point2.d_sx - d_sx;
d_dy = d_point2.d_sy - d_sy;
d_dz = d_point2.d_sz - d_sz;
d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist < d_minpos) d_dist = d_minpos;
d_u2 += f_upot12(d_dist);
}
d_du = d_u2 - d_u1;
for(;;)
{//3
if(d_du != 0)
{//4
if(d_du < 0)
{
d_vx2 = (d_vx * d_vx) - ((d_du * (d_cosx * d_cosx)) * (2 / d_mass));
d_vy2 = (d_vy * d_vy) - ((d_du * (d_cosy * d_cosy)) * (2 / d_mass));
d_vz2 = (d_vz * d_vz) - ((d_du * (d_cosz * d_cosz)) * (2 / d_mass));
}
else
{//5
d_vx2 = (d_vx * d_vx) - ((d_du * (d_cosx * d_cosx)) * (2 / d_mass));
if(d_vx2 < 0)
{
d_point1.d_vx = - d_vx;
d_point1.d_vy = - d_vy;
d_point1.d_vz = - d_vz;
break;
}
d_vy2 = (d_vy * d_vy) - ((d_du * (d_cosy * d_cosy)) * (2 / d_mass));
if(d_vy2 < 0)
{
d_point1.d_vx = - d_vx;
d_point1.d_vy = - d_vy;
d_point1.d_vz = - d_vz;
break;
}
d_vz2 = (d_vz * d_vz) - ((d_du * (d_cosz * d_cosz)) * (2 / d_mass));
if(d_vz2 < 0)
{
d_point1.d_vx = - d_vx;
d_point1.d_vy = - d_vy;
d_point1.d_vz = - d_vz;
break;
}
}//5
d_vmul = d_timestep / d_mass;
d_vx += d_fx * d_vmul;
d_vy += d_fy * d_vmul;
d_vz += d_fz * d_vmul;
for(;;)
{//5
if(d_vx > 0)
{ d_signx = 1; break; }
if(d_vx < 0)
{ d_signx = -1; break; }
if(d_point1.d_vx > 0)
{ d_signx = 1; break; }
if(d_point1.d_vx < 0)
{ d_signx = -1; break; }
if(d_fx > 0)
{ d_signx = 1; break; }
if(d_fx < 0)
{ d_signx = -1; break; }
if(d_cosx > 0)
{ d_signx = 1; break; }
if(d_cosx < 0)
{ d_signx = -1; break; }
if(Math.random() >= 0.5)
{ d_signx = 1; break; }
d_signx = -1; break;
}//5
for(;;)
{//5
if(d_vy > 0)
{ d_signy = 1; break; }
if(d_vy < 0)
{ d_signy = -1; break; }
if(d_point1.d_vy > 0)
{ d_signy = 1; break; }
if(d_point1.d_vy < 0)
{ d_signy = -1; break; }
if(d_fy > 0)
{ d_signy = 1; break; }
if(d_fy < 0)
{ d_signy = -1; break; }
if(d_cosy > 0)
{ d_signy = 1; break; }
if(d_cosy < 0)
{ d_signy = -1; break; }
if(Math.random() >= 0.5)
{ d_signy = 1; break; }
d_signy = -1; break;
}//5
for(;;)
{//5
if(d_vz > 0)
{ d_signz = 1; break; }
if(d_vz < 0)
{ d_signz = -1; break; }
if(d_point1.d_vz > 0)
{ d_signz = 1; break; }
if(d_point1.d_vz < 0)
{ d_signz = -1; break; }
if(d_fz > 0)
{ d_signz = 1; break; }
if(d_fz < 0)
{ d_signz = -1; break; }
if(d_cosz > 0)
{ d_signz = 1; break; }
if(d_cosz < 0)
{ d_signz = -1; break; }
if(Math.random() >= 0.5)
{ d_signz = 1; break; }
d_signz = -1; break;
}//5
d_point1.d_vx = d_signx * Math.sqrt(d_vx2);
d_point1.d_vy = d_signy * Math.sqrt(d_vy2);
d_point1.d_vz = d_signz * Math.sqrt(d_vz2);
}//4
if(d_sx <= d_xmin)
{
if(d_point1.d_vx < 0) d_point1.d_vx = - d_point1.d_vx;
}
else
{//4
if(d_sx >= d_xmax)
{
if(d_point1.d_vx > 0) d_point1.d_vx = - d_point1.d_vx;
}
}//4
if(d_sy <= d_ymin)
{
if(d_point1.d_vy < 0) d_point1.d_vy = - d_point1.d_vy;
}
else
{//4
if(d_sy >= d_ymax)
{
if(d_point1.d_vy > 0) d_point1.d_vy = - d_point1.d_vy;
}
}//4
if(d_sz <= d_zmin)
{
if(d_point1.d_vz < 0) d_point1.d_vz = - d_point1.d_vz;
}
else
{//4
if(d_sz >= d_zmax)
{
if(d_point1.d_vz > 0) d_point1.d_vz = - d_point1.d_vz;
}
}//4
d_point1.d_sx = d_sx;
d_point1.d_sy = d_sy;
d_point1.d_sz = d_sz;
break;
}//3
}//2
f_adjustpoint(d_div,d_point1);
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
d_div = d_div.nextSibling;
}//1
f_impekin();
return;
}
////// step
function f_step()
{
f_process();
return;
}
////// run
function f_run()
{
d_timer = window.setInterval(f_step,d_msecs);
return;
}
////// pause
function f_pause()
{
window.clearInterval(d_timer);
return;
}
////// createpoints
function f_createpoints()
{
var d_index,d_limit;
var d_div;
var d_point,d_prevpoint;
var d_x,d_y,d_z;
var d_w,d_h
var d_left,d_top;
f_cleanpoints();
var d_dx = d_xmax - d_xmin;
var d_dy = d_ymax - d_ymin;
var d_dz = d_zmax - d_zmin;
d_limit = d_reds;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = new Object();//?
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.d_sx = d_xmin + (d_x * d_dx);
d_point.d_sy = d_ymin + (d_y * d_dy);
d_point.d_sz = d_zmin + (d_z * d_dz);
d_point.d_vx = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vy = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vz = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_mass = d_redmass;
d_point.d_type = 1;
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
delete d_point;//?
d_div = document.createElement("div");
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
d_div.style.backgroundColor = "red";
d_field.appendChild(d_div);
}//1
d_limit = d_blues;
for(d_index = 0;d_index < d_limit;d_index++)
{//1
d_point = new Object();//?
d_x = Math.random();
d_y = Math.random();
d_z = Math.random();
d_point.d_sx = d_xmin + (d_x * d_dx);
d_point.d_sy = d_ymin + (d_y * d_dy);
d_point.d_sz = d_zmin + (d_z * d_dz);
d_point.d_vx = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vy = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_vz = ((Math.random() * 2) - 1) * d_velmul;
d_point.d_mass = d_bluemass;
d_point.d_type = 2;
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
delete d_point;//?
d_div = document.createElement("div");
if(d_viewdir == 2) { d_w = d_x; d_h = d_y; }//x right,y down
else
{
if(d_viewdir == 1) { d_w = d_z; d_h = d_x; }//z right,x down
else { d_w = d_y; d_h = d_z; }//d_viewdir = 0,y right,z down
}
d_left = Math.round((d_w * d_width) - (d_pointsize / 2));
if((d_left + d_pointsize) > d_width) d_left = d_width - d_pointsize;
if(d_left < 0) d_left = 0;
d_div.style.left = d_left + "px";
d_top = Math.round((d_h * d_height) - (d_pointsize / 2));
if((d_top + d_pointsize) > d_height) d_top = d_height - d_pointsize;
if(d_top < 0) d_top = 0;
d_div.style.top = d_top + "px";
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
d_div.style.backgroundColor = "blue";
d_field.appendChild(d_div);
}//1
return;
}
////// testwsc
function f_testwsc(d_char)
{
if(d_char != ' ')
{//1
if(d_char != '\t')
{//2
if(d_char != '\r')
{
if(d_char != '\n')
return 0;
}
}//2
}//1
return 1;
}
////// load
function f_load()
{
var d_char,d_num,d_numstr;
var d_div;
var d_point,d_prevpoint;
var d_area = document.getElementById("d_modelarea");
var d_str = d_area.value;
if(d_str.length < 1)
return;
f_cleanpoints();
var d_index = 0;
var d_limit = d_str.length;
var d_error = 0;
for(;d_index < d_limit;d_index++)
{//1
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
continue;
d_div = document.createElement("div");
d_field.appendChild(d_div);
d_point = new Object();//?
d_point.d_nextpoint = null;
if(p_points == null) p_points = d_point;
else d_prevpoint.d_nextpoint = d_point;
d_prevpoint = d_point;
if(d_char == 'r')
{
d_div.style.backgroundColor = "red";
d_point.d_mass = d_redmass;
d_point.d_type = 1;
}
else
{//2
if(d_char != 'b')
{
d_area.value = "unexpected char: " + d_char;
d_error = 1;
break;
}
d_div.style.backgroundColor = "blue";
d_point.d_mass = d_bluemass;
d_point.d_type = 2;
}//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
{
d_area.value = "wsc expected, not this char: " + d_char;
d_error = 1;
break;
}
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sx is incorrect";
d_error = 1;
break;
}
if(d_num < d_xmin) d_num = d_xmin;
else
{
if(d_num > d_xmax) d_num = d_xmax;
}
d_point.d_sx = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sy is incorrect";
d_error = 1;
break;
}
if(d_num < d_ymin) d_num = d_ymin;
else
{
if(d_num > d_ymax) d_num = d_ymax;
}
d_point.d_sy = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "sz is incorrect";
d_error = 1;
break;
}
if(d_num < d_zmin) d_num = d_zmin;
else
{
if(d_num > d_zmax) d_num = d_zmax;
}
d_point.d_sz = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vx is incorrect";
d_error = 1;
break;
}
d_point.d_vx = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vy is incorrect";
d_error = 1;
break;
}
d_point.d_vy = Number(d_num);//?Number
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_area.value = "unexpected end";
d_error = 1;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) == 0)
break;
}//2
if(d_error != 0)
break;
d_numstr = String(d_char);//?String
for(;;)
{//2
d_index++;
if(d_index >= d_limit)
{
d_index--;
break;
}
d_char = d_str.charAt(d_index);
if(f_testwsc(d_char) != 0)
break;
d_numstr += d_char;
}//2
if(d_error != 0)
break;
d_num = Number(d_numstr);
if(Number.isFinite(d_num) == 0)
{
d_area.value = "vz is incorrect";
d_error = 1;
break;
}
d_point.d_vz = Number(d_num);//?Number
delete d_point;//?
d_div.style.width = d_pointsize + "px";
d_div.style.height = d_pointsize + "px";
d_div.style.position = "absolute";
}//1
if(d_error == 0)
{
f_showpoints();
return;
}
f_cleanpoints();
return;
}
////// save
function f_save()
{
if(p_points == null)
return;
var d_point = p_points;
var d_str = "";
for(;;)
{//1
for(;;)
{//2
if(d_point.d_type == 1) d_str += "r ";
else
{
if(d_point.d_type != 2)
break;
d_str += "b ";
}
d_str += d_point.d_sx + " " + d_point.d_sy + " " + d_point.d_sz + "\r\n ";
d_str += d_point.d_vx + " " + d_point.d_vy + " " + d_point.d_vz + "\r\n";
break;
}//2
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}//1
var d_area = document.getElementById("d_modelarea");
d_area.value = d_str;
return;
}
////// zeroimp
function f_zeroimp()
{
var d_pointmass;
if(p_points == null)
return;
var d_mass = 0;
var d_mvx = 0;
var d_mvy = 0;
var d_mvz = 0;
var d_point = p_points;
for(;;)
{
d_pointmass = d_point.d_mass;
d_mass += d_pointmass;
d_mvx += d_point.d_vx * d_pointmass;
d_mvy += d_point.d_vy * d_pointmass;
d_mvz += d_point.d_vz * d_pointmass;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
d_mvx /= d_mass;
d_mvy /= d_mass;
d_mvz /= d_mass;
d_point = p_points;
for(;;)
{
d_point.d_vx -= d_mvx;
d_point.d_vy -= d_mvy;
d_point.d_vz -= d_mvz;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// mulekin
function f_mulekin()
{
if(p_points == null)
return;
var d_point = p_points;
var d_rootmul = Math.sqrt(d_kinmul);
for(;;)
{
d_point.d_vx *= d_rootmul;
d_point.d_vy *= d_rootmul;
d_point.d_vz *= d_rootmul;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// getekin
function f_getekin()
{
if(p_points == null)
return;
var d_point = p_points;
var d_newekin = 0;
for(;;)
{
d_newekin += (d_point.d_mass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
var d_area = document.getElementById("d_ekinarea");
if(Number.isFinite(d_newekin) == 0)
{
d_area.value = "infinity";
return;
}
d_area.value = d_newekin;
return;
}
////// setekin
function f_setekin()
{
if(p_points == null)
return;
var d_area = document.getElementById("d_ekinarea");
var d_newekin = Number(d_area.value);
if(Number.isFinite(d_newekin) == 0)
return;
if(d_newekin < d_minpos)
return;
var d_point = p_points;
var d_oldekin = 0;
for(;;)
{
d_oldekin += (d_point.d_mass / 2) * ((d_point.d_vx * d_point.d_vx) + ((d_point.d_vy * d_point.d_vy) + (d_point.d_vz * d_point.d_vz)));
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
if(Number.isFinite(d_oldekin) == 0)
return;
if(d_oldekin < d_minpos)
return;
var d_rootmul = Math.sqrt(d_newekin / d_oldekin);
if(Number.isFinite(d_rootmul) == 0)
return;
d_point = p_points;
for(;;)
{
d_point.d_vx *= d_rootmul;
d_point.d_vy *= d_rootmul;
d_point.d_vz *= d_rootmul;
d_point = d_point.d_nextpoint;
if(d_point == null)
break;
}
return;
}
////// getepot
function f_getepot()
{
var d_point2;
var d_dx,d_dy,d_dz,d_dist;
var d_area = document.getElementById("d_epotarea");
if(p_points == null)
{
d_area.value = 0;
return;
}
var d_upot = 0;
var d_point1 = p_points;
for(;;)
{//1
//no interaction twice
for(d_point2 = d_point1.d_nextpoint;d_point2 != null;d_point2 = d_point2.d_nextpoint)
{
d_dx = d_point2.d_sx - d_point1.d_sx;
d_dy = d_point2.d_sy - d_point1.d_sy;
d_dz = d_point2.d_sz - d_point1.d_sz;
d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist < d_minpos) d_dist = d_minpos;
d_upot += f_upot12(d_dist);
}
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}//1
if(Number.isFinite(d_upot) != 0)
{
d_area.value = d_upot;
return;
}
d_area.value = "undefined";
return;
}
////// getenergy
function f_getenergy()
{
var d_point2;
var d_dx,d_dy,d_dz,d_dist;
var d_area = document.getElementById("d_energyarea");
if(p_points == null)
{
d_area.value = 0;
return;
}
var d_ukin = 0;
var d_upot = 0;
var d_point1 = p_points;
for(;;)
{//1
d_ukin += (d_point1.d_mass / 2) * ((d_point1.d_vx * d_point1.d_vx) + ((d_point1.d_vy * d_point1.d_vy) + (d_point1.d_vz * d_point1.d_vz)));
//no interaction twice
for(d_point2 = d_point1.d_nextpoint;d_point2 != null;d_point2 = d_point2.d_nextpoint)
{
d_dx = d_point2.d_sx - d_point1.d_sx;
d_dy = d_point2.d_sy - d_point1.d_sy;
d_dz = d_point2.d_sz - d_point1.d_sz;
d_dist = Math.sqrt((d_dx * d_dx) + ((d_dy * d_dy) + (d_dz * d_dz)));
if(d_dist < d_minpos) d_dist = d_minpos;
d_upot += f_upot12(d_dist);
}
d_point1 = d_point1.d_nextpoint;
if(d_point1 == null)
break;
}//1
if(Number.isFinite(d_upot) != 0)
{//1
if(Number.isFinite(d_ukin) != 0)
{//2
var d_energy = d_ukin + d_upot;
if(Number.isFinite(d_energy) != 0)
{
d_area.value = d_energy;
return;
}
}//2
}//1
d_area.value = "undefined";
return;
}
////// action
function f_action()
{
var d_new = Number(this.value);
if(d_new != d_action) d_action = d_new;
return;
}
////// johnsemin
function f_johnsemin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_johnsemin) d_johnsemin = d_new;
return;
}
}//1
this.value = d_johnsemin;
return;
}
////// johnsrmin
function f_johnsrmin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_johnsrmin) d_johnsrmin = d_new;
return;
}
}//1
this.value = d_johnsrmin;
return;
}
////// bucka
function f_bucka()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_bucka) d_bucka = d_new;
return;
}
}//1
this.value = d_bucka;
return;
}
////// buckb
function f_buckb()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_buckb) d_buckb = d_new;
return;
}
}//1
this.value = d_buckb;
return;
}
////// buckc
function f_buckc()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_buckc) d_buckc = d_new;
return;
}
}//1
this.value = d_buckc;
return;
}
////// morseemin
function f_morseemin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morseemin) d_morseemin = d_new;
return;
}
}//1
this.value = d_morseemin;
return;
}
////// morsermin
function f_morsermin()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morsermin) d_morsermin = d_new;
return;
}
}//1
this.value = d_morsermin;
return;
}
////// morseexp
function f_morseexp()
{
var d_new = Number(this.value);
if(Number.isFinite(d_new) != 0)
{//1
if(d_new > 0)
{
if(d_new != d_morseexp) d_morseexp = d_new;
return;
}
}//1
this.value = d_morseexp;
return;
}
////// create
function f_create()
{
var d_area;
var d_left,d_top;
d_field = document.createElement("div");
d_field.style.left = 0 + "px";
d_field.style.top = 0 + "px";
d_field.style.width = d_width + "px";
d_field.style.height = d_height + "px";
d_field.style.position = "absolute";
d_field.style.backgroundColor = "white";
d_field.style.color = "black";
document.body.appendChild(d_field);
d_panel = document.createElement("div");
d_panel.style.left = d_width + "px";
d_panel.style.top = 0 + "px";
d_panel.style.width = (d_xspace + d_xsize + d_xspace + d_xsize + d_xspace + 20) + "px";
d_panel.style.height = 600 + "px";
d_panel.style.position = "absolute";
d_panel.style.backgroundColor = "whiteSmoke";
d_panel.style.color = "black";
document.body.appendChild(d_panel);
d_top = d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_widthlabel","width",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_widtharea",d_width,d_left,d_top).onchange = f_width;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_heightlabel","height",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_heightarea",d_height,d_left,d_top).onchange = f_height;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xminlabel","x minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xminarea",d_xmin,d_left,d_top).onchange = f_xmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_xmaxlabel","x maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xmaxarea",d_xmax,d_left,d_top).onchange = f_xmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_yminlabel","y minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_yminarea",d_ymin,d_left,d_top).onchange = f_ymin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_ymaxlabel","y maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_ymaxarea",d_ymax,d_left,d_top).onchange = f_ymax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_zminlabel","z minimum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zminarea",d_zmin,d_left,d_top).onchange = f_zmin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_zmaxlabel","z maximum",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zmaxarea",d_zmax,d_left,d_top).onchange = f_zmax;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xcloselabel","x closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_xclosecheck",d_xclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_xclose = 0; return; } d_xclose = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_panel,"d_ycloselabel","y closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_yclosecheck",d_yclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_yclose = 0; return; } d_yclose = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_panel,"d_zcloselabel","z closed",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_panel,"d_zclosecheck",d_zclose,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_zclose = 0; return; } d_zclose = 1; return; }//?onclick
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_label(d_panel,"d_viewdirlabel","view along x,y,z",d_left,d_top);
d_left += d_xsize + d_xspace;
f_radio(d_panel,"d_xviewdirradio","d_viewdir",0,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += d_ysize + d_xspace;
f_radio(d_panel,"d_yviewdirradio","d_viewdir",1,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += d_ysize + d_xspace;
f_radio(d_panel,"d_zviewdirradio","d_viewdir",2,d_viewdir,d_left,d_top).onclick = f_viewdir;//?onchange
d_left += (d_ysize * 2) + d_xspace;
f_halfbutton(d_panel,"d_methodsbutton","methods",d_left,d_top).onclick = f_methods;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_minposlabel","min positive",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_minposarea",d_minpos,d_left,d_top).onchange = f_minpos;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_mindistlabel","min distance",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_mindistarea",d_mindist,d_left,d_top).onchange = f_mindist;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_xforcelabel","force along x",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_xforcearea",d_xforce,d_left,d_top).onchange = f_xforce;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_yforcelabel","force along y",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_yforcearea",d_yforce,d_left,d_top).onchange = f_yforce;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_zforcelabel","force along z",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_zforcearea",d_zforce,d_left,d_top).onchange = f_zforce;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_pointsizelabel","point size",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_pointsizearea",d_pointsize,d_left,d_top).onchange = f_pointsize;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_redslabel","red points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_redsarea",d_reds,d_left,d_top).onchange = f_reds;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_blueslabel","blue points",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_bluesarea",d_blues,d_left,d_top).onchange = f_blues;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_redmasslabel","red mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_redmassarea",d_redmass,d_left,d_top).onchange = f_redmass;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_bluemasslabel","blue mass",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_bluemassarea",d_bluemass,d_left,d_top).onchange = f_bluemass;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_velmullabel","velocity mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_velmularea",d_velmul,d_left,d_top).onchange = f_velmul;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_kinmullabel","kinetic mul",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_kinmularea",d_kinmul,d_left,d_top).onchange = f_kinmul;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_panel,"d_msecslabel","msecs",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_msecsarea",d_msecs,d_left,d_top).onchange = f_msecs;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_panel,"d_timesteplabel","time step",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_panel,"d_timesteparea",d_timestep,d_left,d_top).onchange = f_timestep;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_stepbutton","one step",d_left,d_top).onclick = f_step;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_runbutton","run model",d_left,d_top).onclick = f_run;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_pausebutton","pause",d_left,d_top).onclick = f_pause;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_createbutton","create",d_left,d_top).onclick = f_createpoints;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_loadbutton","load",d_left,d_top).onclick = f_load;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_savebutton","save",d_left,d_top).onclick = f_save;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_zeroimpbutton","0 impulse",d_left,d_top).onclick = f_zeroimp;
d_left += (d_xsize / 2) + d_xspace;
f_halfbutton(d_panel,"d_mulekinbutton","mul Ekin",d_left,d_top).onclick = f_mulekin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_getekinbutton","get Ekin",d_left,d_top).onclick = f_getekin;
d_left += (d_xsize / 2) + d_xspace;
f_area(d_panel,"d_ekinarea",0,d_left,d_top);
d_left += d_xsize + d_xspace;
f_halfbutton(d_panel,"d_setekinbutton","set Ekin",d_left,d_top).onclick = f_setekin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_getepotbutton","get Epot",d_left,d_top).onclick = f_getepot;
d_left += (d_xsize / 2) + d_xspace;
f_area(d_panel,"d_epotarea",0,d_left,d_top);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halfbutton(d_panel,"d_getenergybutton","get energy",d_left,d_top).onclick = f_getenergy;
d_left += (d_xsize / 2) + d_xspace;
f_area(d_panel,"d_energyarea",0,d_left,d_top);
d_top += d_ysize + d_yspace;
d_left = d_xspace;
d_area = document.createElement("textarea");
d_area.id = "d_modelarea";
d_area.value = "";
d_area.style.left = d_xspace + "px";
d_area.style.top = d_top + "px";
d_area.style.width = (d_xsize * 2) + "px";
d_area.style.height = (d_ysize * 6) + "px";
d_area.style.position = "absolute";
d_area.style.backgroundColor = "white";
d_area.style.color = "black";
d_area.style.FontSize = 16;
d_area.style.textAlign = "left";
d_panel.appendChild(d_area);
d_methods = document.createElement("div");
d_methods.style.left = 0 + "px";
d_methods.style.top = 0; + "px"
d_methods.style.width = (d_xspace + d_xsize + d_xspace + d_xsize + d_xspace + 20) + "px";
d_methods.style.height = 300 + "px";
d_methods.style.position = "absolute";
d_methods.style.backgroundColor = "whiteSmoke";
d_methods.style.color = "black";
d_methods.style.visibility = "hidden";
document.body.appendChild(d_methods);
d_top = d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_elasticlabel","elastic",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_elasticradio","d_actionradio",1,d_action,d_left,d_top).onclick = f_action;//?onchange
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_johnslabel","Lennard-Johns",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_johnsradio","d_actionradio",2,d_action,d_left,d_top).onclick = f_action;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_bucklabel","Buckingham",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_buckradio","d_actionradio",3,d_action,d_left,d_top).onclick = f_action;//?onchange
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_morselabel","Morse",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_radio(d_methods,"d_morseradio","d_actionradio",4,d_action,d_left,d_top).onclick = f_action;//?onchange
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_johnseminlabel","Johns Emin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_johnseminarea",d_johnsemin,d_left,d_top).onchange = f_johnsemin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_johnsrminlabel","Johns Rmin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_johnsrminarea",d_johnsrmin,d_left,d_top).onchange = f_johnsrmin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_johnscut","Johns cut",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_methods,"d_johnscutcheck",d_johnscut,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_johnscut = 0; return; } d_johnscut = 1; return; }//?onclick
d_left += d_ysize + d_xspace;
f_halflabel(d_methods,"d_johnssplines","Johns splines",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_check(d_methods,"d_johnssplinescheck",d_johnssplines,d_left,d_top).onchange = function()
{ if(this.checked == false) { d_johnssplines = 0; return; } d_johnssplines = 1; return; }//?onclick
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_buckalabel","Buckingham A",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckaarea",d_bucka,d_left,d_top).onchange = f_bucka;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_buckblabel","Buckingham B",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckbarea",d_bucka,d_left,d_top).onchange = f_buckb;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_buckclabel","Buckingham C",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_buckcarea",d_buckc,d_left,d_top).onchange = f_buckc;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_morseeminlabel","Morse Emin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morseeminarea",d_morseemin,d_left,d_top).onchange = f_morseemin;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_halflabel(d_methods,"d_morserminlabel","Morse Rmin",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morserminarea",d_morsermin,d_left,d_top).onchange = f_morsermin;
d_left += (d_xsize / 2) + d_xspace;
f_halflabel(d_methods,"d_morseexplabel","Morse a (exp)",d_left,d_top);
d_left += (d_xsize / 2) + d_xspace;
f_halfarea(d_methods,"d_morseexparea",d_morseexp,d_left,d_top).onchange = f_morseexp;
d_top += d_ysize + d_yspace;
d_left = d_xspace;
f_button(d_methods,"d_hidebutton","hide settings",d_left,d_top).onclick = function() { d_methods.style.visibility = "hidden"; return; }
return;
}

Вернуться к началу
 Профиль  
Cпасибо сказано 
 Заголовок сообщения: Re: Точечная модель газов и жидкостей
СообщениеДобавлено: 22 янв 2023, 19:42 
Не в сети
Одарённый
Зарегистрирован:
25 окт 2022, 19:47
Сообщений: 113
Cпасибо сказано: 2
Спасибо получено:
5 раз в 5 сообщениях
Очков репутации: 5

Добавить очки репутацииУменьшить очки репутации
Обнаруженные баги и улучшения:

В файлах gasliq.txt, gasliq2.txt, gasliq3.txt
нужно заменить слово d_newpointsize словом d_new

В файле gasliq3.txt:
вместо
d_cosx = d_dx / d_dist;
d_u2 = 0;
написать
d_cosz = d_dz / d_dist;
d_u2 = 0;

В файле gasliq3.txt:
вместо
if(d_dist >= d_minpos)
{//2
написать
if(d_dist < d_minpos)
{
d_point1.d_vx = - d_vx;
d_point1.d_vy = - d_vy;
d_point1.d_vz = - d_vz;
}
else
{//2

Во всех файлах в функции f_createpoints
вместо var d_w ,d_h написать var d_w, d_h;
(точка с запятой не помешает).

В файлах gasliq2.txt, gasliq3.txt:
в функции  f_setekin
вместо if(d_newekin < d_minpos) написать if(d_newekin < 0)

Вернуться к началу
 Профиль  
Cпасибо сказано 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему      Страница 1 из 1 [ Сообщений: 10 ]

 Похожие темы   Автор   Ответы   Просмотры   Последнее сообщение 
Точечная модель твёрдого тела в компьютерной симуляции

в форуме Механика

computer

3

56

20 ноя 2022, 09:44

Транспортная задача по сбору жидкостей

в форуме Исследование операций и Задачи оптимизации

bossyara

0

266

15 окт 2016, 16:54

Точечная система координат

в форуме Размышления по поводу и без

ivashenko

290

6267

24 сен 2017, 09:33

Модеилрование САР отходящих газов

в форуме MATLAB

lyakon2607

0

313

07 апр 2015, 09:11

Причина землетрясений - взрыв магматических газов

в форуме Палата №6

Fermer

1

84

12 дек 2021, 09:09

Модель эванса

в форуме Экономика и Финансы

juliet_p

0

202

01 дек 2020, 22:23

Составить мат. модель

в форуме Исследование операций и Задачи оптимизации

Word90098008

2

1052

25 мар 2017, 15:28

Математическая модель

в форуме Исследование операций и Задачи оптимизации

belo4ka

1

691

30 мар 2013, 20:18

Модель CCAPM

в форуме Экономика и Финансы

EGYCH

0

507

08 мар 2013, 14:24

Составить мат. модель

в форуме Исследование операций и Задачи оптимизации

mashka4190

5

593

23 июн 2014, 21:47


Часовой пояс: UTC + 3 часа [ Летнее время ]



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Яндекс.Метрика

Copyright © 2010-2022 MathHelpPlanet.com. All rights reserved