Аннотация: Можете ли вы предложить математический алгоритм над плоскостью пикселей, который будет генерировать умеренно интересный образ, желательно тот, который в целом что-то напоминает?
История до сих пор:
Когда-то я решил в попытке уменьшить количество отходов цикла на моих (по общему признанию,) многочисленных компьютерах и решил генерировать изображения в умеренно интересном стиле; используя 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;
}
Примечание:. Хотя этот вопрос не является, строго говоря, "ответственным" как таковым; Я все еще верю, что это может вызвать какой-то "правильный" ответ. Может быть.
Счастливая охота.
Изменить (снова): Исходный код упрощенных путей безье, используемых в моем ответе (чтение), можно найти здесь и здесь.