摘要:你能否在一个像素平面上提出一个数学算法,它会生成一个中等有趣的图像,最好是一个总体上类似的图像?
到目前为止的故事:
曾几何时,我决定努力减少我(无可否认)太多计算机上的周期浪费,并开始以适度有趣的方式生成图像; 使用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;
}
Run Code Online (Sandbox Code Playgroud)
注意:虽然这个问题严格来说似乎并不是"可回答的"; 我仍然认为它可以产生一些"正确"的答案.也许.
快乐狩猎.
mct*_*ylr 10
分形?他们不仅仅是股市分析了(Mandelbrot开玩笑,对不起).
一些分形图像往往让人联想到现实世界的地理位置.特别是IFS分形可用于相当逼真的植物和树木以及地形.
fractal.c是一个简单的单色Mandelbrot集,默认为缩放.
添加:
无上下文语法可用于表达可以绘制在美学上令人愉悦的图像的方程.Jared Tarbell有一个相关的画廊,里面有一些由节目制作的精彩图像.阿扎的算法墨水
第二次补充:
代数或计算艺术的另一种主要形式来自元胞自动机(CA),例如(John)Conway的生命游戏,由Martin Gardner撰写的1970年科学美国文章而闻名.2002年,斯蒂芬·沃尔夫勒姆(Stephen Wolfram)自行出版了"新种科学"(NKS),将CA重新引入公众.这些系统往往是封闭的动态系统,基于一套简单的规则"活"或"死".
与分形相关的是混沌系统,或非线性动态系统,如果你想听起来很聪明.它们可以在物理系统上建模,如天气预报,并且可以提供非真实随机但难以预测的数字输出,可以将其视为奇怪的吸引子(和SA).