Аннотация: Можете ли вы предложить математический алгоритм на плоскости пикселей, который будет генерировать умеренно интересное изображение, предпочтительно такое, которое в целом напоминает что-то?
История до сих пор:
Однажды я решил попытаться сократить количество циклов на моих (по общему признанию) многочисленных компьютерах и решил генерировать изображения в умеренно интересной манере; используя PRNG и некоторую умную математику для создания изображений, которые в целом будут напоминать что-то.
Или, по крайней мере, это был план. Как оказалось, умная математика требует умного математика; это не я.
В какой-то степени я пришел к методу, который предпочитал прямые линии (поскольку это, как правило, компоненты, из которых состоит наш мир), возможно, слишком сильно. Результат слегка интересно; напоминающие, возможно, городские сетки как таковые:
Городские сетки, может быть? http://totlandweb.info/imggen.out.png
Теперь к собственно вопросу: приведен исходный код этой маленькой программы; Можете ли вы улучшить его и предложить метод, который дает несколько более интересные результаты? (например, не городские сетки, а, возможно, лица, животные, география, что у вас)
Это также означает своего рода вызов; Я полагаю, и поэтому я установил некоторые совершенно произвольные и одинаково необязательные правила:
Комментарии в коде говорят все на самом деле. Предложения и «решения» должны
редактировать сам алгоритм, а не окружающий фреймворк, кроме как для исправления
ошибки, препятствующие компиляции образца.
Код должен быть аккуратно скомпилирован с помощью стандартного компилятора языка C. (Если
пример, приведенный не, упс! Скажи мне, и я исправлю. :)
Метод должен, хотя, опять же, это не является обязательным, не нужно вызывать помощь от
вашей дружественной математической библиотеке соседства, и в целом используйте (P) RNG в качестве его
первичный канал ввода данных.
Решения, вероятно, должны быть доставлены простым извлечением всего, что находится между
отрывочные строки (те, которые говорят, что вы не должны редактировать выше и ниже соответственно),
с заявлением о том, что вам нужно добавить к преамбуле, в частности.
Редактировать: Иногда легко забыть, что люди в Интернете не могут читать мои
разум; но там вы идете. Программа должна требовать минимального вмешательства человека в
генерация изображений, за исключением оценки результатов и выбора лучших
из них.
Код требует компилятора C и libpng для сборки; Я не совсем уверен, что компилятор MinGW обеспечивает все необходимое, но я был бы удивлен, если бы этого не произошло. Для Debian вам понадобится пакет libpng-dev, а для Mac OS X - инструменты XCode.
Исходный код можно скачать здесь .
Предупреждение: Массивная ошибка кода!
// 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;
}
Примечание: Хотя этот вопрос, строго говоря, не кажется "ответственным" как таковой; Я все еще верю, что это может привести к какому-то «правильному» ответу. Может быть.
Счастливой охоты.
Редактировать (снова): Исходный код для упрощенных путей Безье, использованных в моем ответе (читать), можно найти здесь и здесь .