C ++ создает объекты «блоб» случайной формы - PullRequest
0 голосов
/ 22 февраля 2019

Мне нужно определить объект (или область), который имеет вид «шарика», сформированного на дискретной сетке.Это должно выглядеть примерно так: enter image description here

, где красная область обозначает центральную точку (это всего лишь идеи, любая пузырьковая форма будет работать до тех пор, пока она может изменяться случайным образом),Моя идея до сих пор заключалась в том, чтобы итеративно увеличивать угол от начальной точки (= 0 градусов) до 360 градусов и использовать тригонометрию для вычисления внешних точек окружности (что приведет к единичной окружности, если радиус = 1 = const).Затем я использовал алгоритм линий Брезенхэма (помните: мы движемся по дискретной сетке), чтобы вычислить линию, которая соединяет центр круга и внешнюю точку, с которой я только что придумал.Моя идея состояла в том, что, если бы я мог немного изменить радиус, я мог бы создать эти пузырьковые формы.То, что я придумала до сих пор, дает мне красивые формы, хотя они просто не очень «пухлые».Вот мой код (обратите внимание, что x0 и y0 отмечают центральную точку моей карты сетки, plotBresenham просто помещает все 1s в регионы, чтобы карта сетки могла быть визуализирована):

double radius = 10; 
for(int alpha=0; alpha<360; alpha++) {
   double x = cos(alpha*M_PI/180.0)*radius;
   double y = sin(alpha*M_PI/180.0)*radius;

   if(alpha<45) radius+=0.5;
   else if(alpha<90) radius-=0.5; 
   else if(alpha<135) radius+=0.5; 
   else if(alpha<180) radius-=0.5; 
   else if(alpha<225) radius+=0.5; 
   else if(alpha<270) radius-=0.5; 
   else if(alpha<315) radius+=0.5; 
   else radius-=0.5; 

   plotBresenhamLine(x0,y0,x,y)

}

Результат выглядит так:

enter image description here

Извините за грубый чертеж.Язык программирования - C ++, но я думаю, что подход на самом деле не зависит от используемого языка.Любые советы / помощь / руководство о том, как я могу создавать фигуры, которые больше похожи на те, которые мне нужны?Или даже Framework, который делает такие вещи для вас?Для меня просто важно иметь координаты точек внутри, чтобы поместить их в мою сетку.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

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

  1. радиус вернется к своему первоначальному значению после поворота на 360 °,
  2. вы можете легко контролировать диапазон радиусов, с которыми вы сталкиваетесь.(Вам нужно избегать перехода на ноль меньше нуля).

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

Я не собираюсь писать это на C ++, потому что, как вы сказали, это не добавит ничего важного в алгоритм.Это может выглядеть так:

  1. Возьмите N, количество волн, которое вам нужно.
  2. Определите массивы с плавающей точкой amps[N] и phases[N].
  3. Выберите случайное число от 0 до 1 / (2N) для каждого amps[i] и от 0 до 2π для каждого phases[i].
  4. Для каждого угла alpha (в радианах), рассчитайте
radius = 1 + sum[i=0 to N-1] amps[i] * cos((i+1)*alpha + phases[i])
x = cos(alpha)*radius;
y = cos(alpha)*radius;
Продолжайте, как и раньше.

Результаты (от Wolfram Mathematica):

Чтобы сделать его несколько более интересным, ограничьте k -ая амплитуда с некоторой отрицательной степенью k (или k + 1, поскольку мы индексируем с нуля).Вот когда вместо 2N случайное число делится на pow(i+1,1.5) на шаге 3, для N = 30:

0 голосов
/ 22 февраля 2019

Для округлой формы (несколько плотное) созвездие метаболов может привести к красивым формам.

...