Создание произвольно искаженной 2D-сетки

Я хочу исказить 2D-сетку на основе расположения точечных масс. Наличие массы должно сжимать сетку следующим образом:

Создание произвольно искаженной 2D-сетки

Но я хочу исказить его произвольным количеством частиц на сетке.

Это для того, чтобы я мог визуализировать влияние гравитации на пространство: исказил пространство, где присутствуют большие массы.

То, что я пробовал до сих пор, — это итеративная настройка краев ячейки в зависимости от количества частиц внутри нее. Ячейка со многими частицами должна сжимать свои края.

Однако полученное изображение разочаровывает и на самом деле не выглядит искаженным 2D-пространством. Я думаю, потому что деформация должна иметь глобальный эффект, а не только влияние на одну ячейку?

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

Создание произвольно искаженной 2D-сетки

Есть ли у вас ограничения по времени обработки или памяти? Или, может быть, грубая оценка количества частиц? Я могу себе представить один метод, простой, но медленный, а другой потенциально быстрый, но его сложно реализовать.

Rethunk 11.02.2019 19:34

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

Bram 11.02.2019 19:50

Хорошо. Я думаю, что смогу кое-что соорудить в течение следующих двенадцати часов. А пока несколько дополнительных вопросов. Будет ли наименьшая масса занимать один пиксель или она может занимать дробную часть пикселя? Какое максимальное разрешение экрана? Хотя вы упомянули произвольное количество пикселей, существует ли практический предел количеству масс/частиц? Можем ли мы предположить, что массы представляют собой сфероиды, или вы хотите иметь дело со странными формами? Была бы у вас возможность работать с OpenGL (или VTK) или CUDA, или просто реализовывать для ядер ЦП?

Rethunk 11.02.2019 20:24

Кроме того: вам нужно описание «настоящей» математики или просто что-то, что выглядит реалистично? Из вашего профиля я вижу, что вы пишете на C, поэтому я придумаю код на C++; дайте мне знать, если вы хотите, чтобы он больше походил на C, чем на C++.

Rethunk 11.02.2019 20:26

Это не пиксельная симуляция. Он использует векторы и работает на процессоре, а не на графическом процессоре. В настоящее время я использую до 50 тысяч частиц или около того, все с одинаковой массой. Вы можете попробовать существующую версию без искажения пространства здесь: bram.itch.io/брызнуть-брызнуть-маленькая звезда

Bram 11.02.2019 21:02

Спасибо. Приложение выглядит красиво! Я попробую несколько идей и вернусь к вам.

Rethunk 11.02.2019 22:25

Извините, я так устал, что боролся с наивной реализацией (ради демонстрации) и даже не добрался до быстрой реализации. Короче говоря, я думаю, что есть быстрый способ справиться с суперпозицией гравитационного притяжения всех масс, но мне нужен более свежий мозг, чтобы написать это. Я вернусь к вам, когда смогу.

Rethunk 12.02.2019 06:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
7
567
3

Ответы 3

Я бы смоделировал двумерную плоскость как сделанную из какого-то эластичного материала, чтобы вы могли деформировать ее, применяя силы, имитирующие вес данного объекта.

Поскольку вы хотите визуализировать некоторый физический эффект, я думаю, что физически обоснованная визуализация может быть адекватным выбором.

Относительно простой способ моделирования такого упругого поведения — создание системы масса-пружина:

https://en.m.wikipedia.org/wiki/Soft-body_dynamics

Однако применение этого типа методов требует хорошего понимания физики Гука, ОДУ, интеграции и других связанных математических вещей.

Я создал скрипт, в котором каждая частица влияет на каждое пересечение сетки на основе гравитационного правила обратных квадратов. https://jsfiddle.net/1nrjcsqa/2/

    dx = points[i][0] - x;
    dy = points[i][1] - y;
    d = Math.sqrt(dx * dx + dy * dy);
    f = gravity_force / Math.pow(d, falloff);

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

Возможно, вам придется настроитьgravity_force, чтобы все выглядело правильно для вас.

Я опубликую несколько быстрых предложений на данный момент, а затем продолжу, когда смогу.

Хотя вы прямо сказали в своем посте и комментариях, что это будет обрабатываться на ЦП, выполнение этого на графическом процессоре и использование OpenGL для отображения может сильно помочь. Обработка эффектов десятков тысяч точек на частоте 60 Гц (~16 мс на проход) требует много ресурсов процессора, даже если он имеет восемь ядер.

Тем не менее, несколько подготовительных мыслей:

  • Как указывает пользователь aptriangle, сила тяжести падает пропорционально квадрату расстояния. На некотором расстоянии вы можете игнорировать эффекты, тем более что все ваши объекты имеют одинаковую массу.
  • Учитывая, что вы будете поддерживать большое количество масс, возникают проблемы с масштабированием при сохранении хорошей скорости обновления для взаимодействия и плавной анимации.
  • Ваша цель — визуализация, а это значит, что вы сможете использовать более короткие пути, к которым в противном случае могла бы привести строгая интерпретация математики. На самом деле, я думаю, что по крайней мере некоторые ярлыки необходимы для работы на любой скорости, близкой к желаемой.
  • Перебор масс и всех точек сетки, на которые они влияют, скорее всего, не приведет к привлекательному графическому обновлению с желаемой скоростью.
  • Вам нужно будет учитывать суперпозиция и поле векторов. (Я использую здесь общий смысл, а не правильную терминологию.) Каждая масса будет влиять на все пространство вокруг нее. Из любой точки пространства будет некоторый вектор, указывающий на эту массу, длина которого равна вектору, представляющему силу притяжения. В любой точке пространства вы складываете векторы. Это может привести к «мертвой точке», где два разных тела тянут силы, которые уравновешивают друг друга.
  • При большом количестве масс визуализация изогнутых линий сетки может стать настолько сложной, что это скорее запутает, чем просветит пользователя. Представьте себе эластичный резиновый лист с прикрепленными к нему тысячами стальных грузов, иногда со сгруппированными грузами: форма поверхности может выглядеть очень сложно и странно.
  • Как писал Маурисио Селе Лопес Белон, вы можете смоделировать поверхность как эластичный материал, то есть напрямую реализовать геометрию поверхности «резинового листа». Если не считать использования CUDA и OpenGL на графическом процессоре, я не думаю, что вы заставите это работать.
  • Основное препятствие — время расчета.
  • Чтобы свести к минимуму время вычислений, выполняйте предварительные вычисления как можно больше.
  • Обратите внимание, что, поскольку ваши массы равны, эффекты этих масс при любом заданном смещении (dx,dy) одинаковы.
  • Хотя точки, представляющие массы, могут иметь действительные местоположения, такие как (23,32342, -15,38963) или что-то еще, вы, вероятно, можете (и, вероятно, должны) вычислить эффекты на целочисленной сетке, чтобы упростить вычисления.

Учитывая все это, я имею в виду быстрый метод, который определяет гравитационное поле вокруг каждой массы как кусок памяти, который (более или менее) подвергается операции ИЛИ вместе с другой памятью, чтобы получить окончательную карту векторов поля.

Потом дело за рисованием. Опять же, использование OpenGL для создания истинного 3D-представления, которое затем проецируется на 2D-дисплей, было бы моим предпочтительным способом. OpenGL может работать на встроенной графике, и я бы рекомендовал именно это. В противном случае вычисления, которые необходимо выполнить для изменения 2D-линий сетки в виде 2D-фигур, могут быть сложными.

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

Из первоначального кода, который я написал просто для того, чтобы показать медленный и менее желательный способ решения проблемы, вот очень грубый пример изгиба линий сетки, рассматривая их как точки, которые можно по отдельности притягивать к каждой массе. Это НЕ способ реалистичного отношения к линиям сетки; код также имеет некоторые ошибки.

Rough sample of gridlines bent by mass

Я думаю, вы неправильно поняли: у меня уже запущен симулятор N-Body с десятками тысяч частиц, за 16 мс на процессоре. Сим сделан. Что я хочу наложить, так это визуализацию того, как пространство искажается под действием гравитации. youtube.com/watch?v=YiAiEWqxLWg

Bram 12.02.2019 20:04

Я понял это. Чтобы рассчитать, как согнуть линии сетки на основе всех точек, будет сложно втиснуться в те же 16 мс, тем более что я все еще не уверен в ограничениях на количество масс, памяти, ядер и т. д. Если у вас есть неиспользуемый процессор ядра и/или могут быть разгружены на графический процессор или встроенную графику. Если у вас уже определено поле и/или у вас есть быстрый поиск точки в целочисленном или вещественном пространстве, то должен быть способ создать линии сетки в виде кусочных кривых, связанных вместе.

Rethunk 12.02.2019 20:31

Другие вопросы по теме