Я должен поместить мозаики на большую сетку, исходящую от центральной точки способом, которая выглядит органической и случайной. Новые мозаики должны будут найти открытое пространство на сетке, которая касается по крайней мере 1 другой мозаики.
Кто-либо может указать на меня в праве на направление к чему-нибудь, что могло бы помочь с этим? Или некоторые фундаментальные понятия, которые я могу считать на этом, находятся в этой вене?
Например, в этом изображении, существует форма, уже создал (желтый), и я могу получать новую мозаику, которая может быть 1x1, 2x2, или 3x3. Попытка найти хороший способ выяснить, куда я могу поместить новую мозаику так, чтобы это коснулось максимальной суммы текущих мозаик.
Изображение: сопроводительный текст http://osomer.com/grid.JPG
В качестве альтернативы, вы можете подойти к этой проблеме, когда желтые плитки «размываются» на синем / фоне. Для этого на каждом этапе пусть желтая плитка добавляет фиксированное число к «сумме эрозии» E всех фоновых плиток, соседствующих с ней в кардинальном направлении (и, возможно, может быть часть этого числа, чтобы фоновые плитки, соседствующие с ним по диагонали).
Затем, когда придет время разместить новый тайл, вы можете для каждого фонового тайла выбрать случайное число от 0 до E ; самый большой из них «размывается». В качестве альтернативы вы можете сделать простой взвешенный случайный выбор с E их весами.
Для плиток 2x2 или 3x3 вы можете выбрать только те плитки, которые подходящим образом «вписываются» в квадрат 2x2 или 3x3 (то есть 2x2 или 3x3 размытая плитка на краю, чтобы не вызывать перекрытия. с уже уложенными плитками). Но на самом деле вы никогда не получите ничего такого же естественного, как пошаговая эрозия / укладка плитки.
Вы можете сэкономить время, пересчитывая суммы эрозии, сохраняя их на каждой итерации, только при добавлении нового тайла увеличивайте суммы эрозии соседних с ним (простой + =
). На данный момент, по сути, это то же самое, что предложен в другом ответе, хотя и с другой точки зрения / философии.
Примерная сетка сумм эрозии E , где прямые кардинальные соседи равны +4, а диагональные соседи - +1:
Суммы эрозии http://img199.imageshack.us/img199/4766 / эрозия.png
Те, у кого выше E , скорее всего, будут «размыты»; например, в этом случае два маленьких входа на западной и южной сторонах, скорее всего, будут размыты желтым цветом, за которыми следуют меньшие заливы на северной и восточной сторонах. Наименее вероятны те, которые едва касаются желтого одним углом. Вы можете решить, какой из них, либо назначив случайное число от 0 до E для каждого тайла и удалив тот, у которого наибольшее случайное число, либо выполнив простой взвешенный случайный выбор, либо любым методом принятия решения по вашему выбору. .
Для чисто случайного вы начинаете с пустая сетка и список «кандидатов» (тоже пустой).
Поместите первую плитку в центр сетки, затем добавьте каждую соседнюю плитку к той, которую вы только что поместили в список «кандидатов». Затем каждый ход выбирайте случайную запись в списке «кандидатов» и помещайте туда плитку. Посмотрите на каждую смежную ячейку сетки рядом с тем местом, где вы только что поместили плитку, и для каждой, которая также пуста, поместите ее в список «кандидатов» в следующий раз (если еще не там).
Чтобы избежать образования дыр в вашей сетке плиток, увеличьте вероятность выбора местоположения сетки на основе количества соседних плиток, которые уже заполнены (так что, если только одна соседняя плитка уже заполнена, она, вероятно, низкая. Если они ' повторно все залито, будет очень большая вероятность).
В псевдокоде:
grid = new array[width,height];
candidates = new list();
function place_tile(x,y) {
// place the tile at the given location
grid[x,y] = 1;
// loop through all the adjacent grid locations around the one
// we just placed
for(y1 = y - 1; y1 < y + 1; y1++) {
for(x1 = x - 1; x1 < x + 1; x1++) {
// if this location doesn't have a tile and isn't already in
// the candidate list, add it
if (grid[x,y] != 1 && !candidates.contains(x1,y1)) {
candidates.add(x1,y1);
}
}
}
}
// place the first tile in the centre
place_tile(width/2, height/2);
while (!finished) {
// choose a random tile from the candidate list
int index = rand(0, candidates.length - 1);
// place a tile at that location (remove the entry from
// the candidate list)
x, y = candidates[index];
candidates.remove(index);
place_tile(x, y);
}
Проблема с вашим вопросом в том, что «органическое и случайное» может означать много разных вещей. Позвольте мне показать две ссылки
Два приведенных выше образца для меня «органические и случайные», но они могут вас не удовлетворить. Итак, я думаю, вам нужно лучше определить, что такое «органическое и случайное».
А пока я возьму ваше определение руководящего правила для добавления новых плиток (но не думаю, что это обязательно одна и та же проблема), которое я прочитал как:
Учитывая две формы (с учетом растровых изображений) найти относительное положение формы такие, что количество максимальное касание сторон
Я также предполагаю, что
При таком условий, которые необходимо протестировать менее x y решений, и в каждом из них необходимо - отбросьте, если есть перекрытие - выбросьте, если они не соприкасаются - если они касаются, то подсчитайте количество общих ребер Все три из вышеперечисленных тестов могут быть выполнены за постоянное время путем сканирования всех желтых плиток (число которых равно konst x * y)
Таким образом, описанное выше может быть легко выполнено за O (n ^ 4), Вам этого достаточно?
Вычислите случайное проходящее дерево для двойного графа, то есть решетки, вершинами которой являются центры ваших клеток. Для этого начните с центра решетки и выполните случайный поиск в глубину. Затем постройте клетки по возрастанию расстояния дерева от центра.