Подтвердить что ты не робот

Создание умеренно интересных изображений

Аннотация: Можете ли вы предложить математический алгоритм над плоскостью пикселей, который будет генерировать умеренно интересный образ, желательно тот, который в целом что-то напоминает?

История до сих пор:

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

Или, по крайней мере, это был план. Как оказалось, умная математика требует умного математика; этого я не знаю.

В какой-то мере я пришел к методу, который предпочитал прямые линии (поскольку они обычно являются компонентами, из которых сделан наш мир), возможно, слишком сильно. Результат слегка интересен; напоминающие, возможно, городские сетки как таковые:

Городские решетки, может быть? http://totlandweb.info/imggen.out.png

Теперь для собственно вопроса: учитывая исходный код этой маленькой программы; вы можете улучшить его и предложить метод, который дает несколько более интересные результаты? (например, не городские сетки, но, возможно, лица, животные, география, что у вас есть)

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

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

  • Код должен компилироваться с помощью стандартного компилятора C. (Если  пример предоставлен, нет, oops! Скажи мне, и я исправлю.:)

  • Метод должен, хотя опять же, это необязательно, не нужно запрашивать помощь от  вашей дружественной математической библиотеке, и в целом используют (Р) РНГ как  канал ввода первичных данных.

  • Решения, вероятно, должны быть реализованы, просто вытаскивая все, что между  линии снайпа (те, которые говорят, что вы не должны редактировать выше и ниже, соответственно),  с утверждением о том, что вам нужно добавить к преамбуле в частности.

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

Для этого требуется компилятор C и libpng; Я не совсем уверен, что компилятор MinGW предоставляет вам необходимые вещи, но я был бы удивлен, если бы этого не произошло. Для Debian вам понадобится пакет libpng-dev, а для Mac OS X вам понадобятся инструменты XCode.

Исходный код может быть загружен здесь.

Предупреждение: Массивный код splurge incoming!

// compile with gcc -o imggen -lpng imggen.c
// optionally with -DITERATIONS=x, where x is an appropriate integer
// If you're on a Mac or using MinGW, you may have to fiddle with the linker flags to find the library and includes.

#include <stdio.h>
#include <stdlib.h>
#include <png.h>

#ifdef ITERATIONS
#define REPEAT
#endif // ITERATIONS

// YOU MAY CHANGE THE FOLLOWING DEFINES
#define WIDTH 320
#define HEIGHT 240

// YOU MAY REPLACE THE FOLLOWING DEFINES AS APPROPRIATE
#define INK 16384

void writePNG (png_bytepp imageBuffer, png_uint_32 width, png_uint_32 height, int iteration) {
  char *fname;
  asprintf(&fname, "out.%d.png", iteration);

  FILE *fp = fopen(fname, "wb");
  if (!fp) return;
  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  png_infop  info_ptr = png_create_info_struct(png_ptr);
  png_init_io(png_ptr, fp);
  png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, PNG_FILTER_NONE);
  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
  png_set_IHDR(png_ptr, info_ptr, width, height, 8,
               PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  png_set_rows(png_ptr, info_ptr, imageBuffer);
  png_set_invert_mono(png_ptr); /// YOU MAY COMMENT OUT THIS LINE
  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
  png_destroy_write_struct(&png_ptr, &info_ptr);
  fclose(fp);
  free(fname);
}

int main (int argc, const char * argv[]) {
  png_uint_32 height = HEIGHT, width = WIDTH;


  int iteration = 1;
#ifdef REPEAT
  for (iteration = 1; iteration <= ITERATIONS; iteration++) {
#endif // REPEAT  

    png_bytepp imageBuffer = malloc(sizeof(png_bytep) * height);
    for (png_uint_32 i = 0; i < height; i++) {
      imageBuffer[i] = malloc(sizeof(png_byte) * width);
      for (png_uint_32 j = 0; j < width; j++) {
        imageBuffer[i][j] = 0;
      }
    }    

    /// CUT ACROSS THE DASHED LINES
    /// -------------------------------------------
    /// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED

    int ink = INK;
    int x = rand() % width, y = rand() % height;

    int xdir = (rand() % 2)?1:-1;
    int ydir = (rand() % 2)?1:-1;

    while (ink) {
      imageBuffer[y][x] = 255;
      --ink;
      xdir += (rand() % 2)?(1):(-1);
      ydir += (rand() % 2)?(1):(-1);
      if (ydir > 0) {
        ++y;
      } else if (ydir < 0) {
        --y;
      }
      if (xdir > 0) {
        ++x;
      } else if (xdir < 0) {
        --x;
      }
      if (x == -1 || y == -1 || x == width || y == height || x == y && x == 0) {
        x = rand() % width; y = rand() % height;
        xdir = (rand() % 2)?1:-1;
        ydir = (rand() % 2)?1:-1;
      }
    }

    /// NO EDITING BELOW THIS LINE
    /// -------------------------------------------

    writePNG(imageBuffer, width, height, iteration);

    for (png_uint_32 i = 0; i < height; i++) {
      free(imageBuffer[i]);
    }    
    free(imageBuffer);
#ifdef REPEAT
  }
#endif // REPEAT
  return 0;
}

Примечание:. Хотя этот вопрос не является, строго говоря, "ответственным" как таковым; Я все еще верю, что это может вызвать какой-то "правильный" ответ. Может быть.

Счастливая охота.

Изменить (снова): Исходный код упрощенных путей безье, используемых в моем ответе (чтение), можно найти здесь и здесь.

4b9b3361

Ответ 1

Fractals? Они уже не просто для анализа фондовых рынков (шутка Мандельброта, извините).

Некоторые Фрактальные изображения, как правило, напоминают реальные географические регионы. В частности, фракции IFS могут использоваться для довольно реалистичных plants и деревья и ландшафт.

fractal.c - это простой монохроматический набор Мандельброта при его масштабировании по умолчанию.


Добавлено:

Контекстно-свободные грамматики могут использоваться для выражения уравнений, которые могут рисовать изображения, которые эстетически нравятся людям. У Джареда Тарбелла есть соответствующая галерея некоторых замечательных образов, созданных программами. Aza Алгоритм Чернила

Второе дополнение:

Другим основным видом алгебраического или вычислительного искусства является Сотовый автомат (CA), такой как (John) Conway Game of Life, прославленный 1970 Scientific American, написанная Мартин Гарднер. CA был вновь представлен публике со своей собственной публикации Стивена Вольфрама "Новый вид науки" (NKS) в 2002 году. Они, как правило, закрытых динамических систем, которые "живут" или "умирают" на основе простого набора правил.

Связанные с фракталами хаотические системы или нелинейные динамические системы, если вы хотите звучать умно. Они могут быть смоделированы по физическим системам, например прогнозирование погоды, и могут предоставлять неслучайный, но трудно прогнозируемый числовой вывод, который может визуализироваться как странный аттракторSA),

Ответ 2

Хммм. Я помню, как давно создал генератор страны. Основная стратегия заключалась в том, чтобы засеять его живописцем для каждого цвета и иметь правило: "Цветные художники перемещаются случайным образом, но не могут перемещаться по какой-либо области, если она не окрашена в свой цвет". Результатом стало несколько смежных областей. Художники перемещались случайным образом в 4 направлениях, а сетка имела размер 50 × 50 или около того.

Сделав это, я взял 50х50 изображение, расширил его (с ближайшим соседом) на что-то намного большее и использовал некоторые стандартные графические фильтры (размытие и т.д.), чтобы сделать его достойным. Если вы хотите монохромное изображение, просто поверните все черные и все остальные белые.

Эта стратегия не поддерживает прямые линии.

Ответ 3

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

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

Ответ 4

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

Возьмите сетку (постройте ее из квадратов, шестиугольников или что у вас есть) и создайте случайное поле точек на ней. Теперь рассмотрим все возможные способы подключения этого фиксированного набора точек, используя строки, которые следуют за сеткой. Возьмите фрагменты изображений с подобной темой (например, листья) и преобразуйте их в стиль "line art", чтобы уменьшить их до контура. Для каждого набора из нескольких точек просмотрите свою библиотеку фрагментов и попытайтесь найти ту, которая может соединять точки (или, по крайней мере, приблизиться, это может потребовать поворота, зеркалирования и т.д.). Вы обнаружите, что существует множество возможных результатов, но если все сделано правильно, вы можете оказаться со многими, которые выглядят как листья (даже если они являются "новыми" типами листьев, которые никогда раньше не были замечены)!

Ответ 5

Вместо прямой случайности вы можете добавить какое-то тривиальное состояние в поведение. Например, вместо того, чтобы выбрать x и y на основе P, где P по существу rand % 2, вы можете выбрать их на основе условного уравнения. В качестве простого примера:

два состояния http://img121.imageshack.us/img121/9018/twostate.png

Если вы разрешаете состоянию 1 представлять "поддерживать текущий путь" и 0 как "направление изменения", то, регулируя порог Q, вы управляете частотой, с которой вы меняете направление. Добавление состояний добавляет сложности, но вы, вероятно, получите умеренно интересные результаты с тщательно подобранными значениями для P и Q.

Ответ 6

В духе полного разрушения моих собственных (по общему признанию, произвольных правил я пошел прямо и сам создал ответ)

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

В дополнение к редактированию текстового поля я также добавил, конечно,

#include "bezier.h"

Это не очень хорошо работает без этой строки.;)

/// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED

Bezier *path = newBezier(newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height));

float t;
Point *point = NULL;

for (t = 0.0; t <= 1.0; t += 0.00000006) {
  point = bezierPoint(path, t, point);

  int32_t x = point->x, y = point->y;

  if (x >= 0 && x < width && y >= 0 && y < height)
    imageBuffer[y][x] = 255;
}

destroyPoint(point);

/// NO EDITING BELOW THIS LINE