生成适度有趣的图像

Wil*_*and 22 c

摘要:你能否在一个像素平面上提出一个数学算法,它会生成一个中等有趣的图像,最好是一个总体上类似的图像?

到目前为止的故事:

曾几何时,我决定努力减少我(无可否认)太多计算机上的周期浪费,并开始以适度有趣的方式生成图像; 使用PRNG和一些聪明的数学来创建总体上类似于某些东西的图像.

或者至少,这是计划.事实证明,聪明的数学需要成为一个聪明的数学家; 我不是.

在某种程度上,我得到了一种偏好直线的方法(因为这些直线通常是我们世界的组成部分),也许过于强烈.结果有点有趣; 或许像城市网格一样:

也许是城市网格?http://totlandweb.info/imggen.out.png

现在问题是正确的:给出这个小程序的源代码; 你可以改进它并提出一种方法,给出更有趣的结果吗?(例如,不是城市网格,但也许是面孔,动物,地理,你有什么)

这也是一种挑战; 我想,因此我已经制定了一些完全随意且同样可选的规则:

  1. 代码中的注释说明了这一切.建议和"解决方案"应该编辑算法本身,而不是周围的框架,除了修复阻止样本编译的错误.

  2. 代码应该使用标准问题C编译器干净地编译.(如果提供的示例没有,哎呀!告诉我,我会修复.:)

  3. 该方法应该是可选的,不需要从友好的邻域数学库中获得帮助,并且总体上使用(P)RNG作为其主要数据输入通道.

  4. 解决方案应该可以通过简单地排除剪切线之间的任何内容(分别表示你不应该在上面和下面编辑的那些)来提供,特别是你需要添加到前导码的效果的声明.

  5. 编辑:有时很容易忘记互联网上的人无法读懂我的想法; 但你去了.除了评估结果并选择最佳结果外,该程序应该在生成图像时至少需要人为干预.

代码需要一个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)

注意:虽然这个问题严格来说似乎并不是"可回答的"; 我仍然认为它可以产生一些"正确"的答案.也许.

快乐狩猎.

编辑(再次):我的答案(读下来)中使用的简单bezier路径的源代码可以在这里这里找到.

mct*_*ylr 10

分形?他们不仅仅是股市分析了(Mandelbrot开玩笑,对不起).

一些分形图像往往让人联想到现实世界的地理位置.特别是IFS分形可用于相当逼真的植物树木以及地形.

fractal.c是一个简单的单色Mandelbrot集,默认为缩放.


添加:

无上下文语法可用于表达可以绘制在美学上令人愉悦的图像的方程.Jared Tarbell有一个相关的画廊,里面有一些由节目制作的精彩图像.阿扎算法墨水

第二次补充:

代数或计算艺术的另一种主要形式来自元胞自动机(CA),例如(John)Conway的生命游戏,由Martin Gardner撰写的1970年科学美国文章而闻名.2002年,斯蒂芬·沃尔夫勒姆(Stephen Wolfram)自行出版了"新种科学"(NKS),将CA重新引入公众.这些系统往往是封闭的动态系统,基于一套简单的规则"活"或"死".

与分形相关的是混沌系统,或非线性动态系统,如果你想听起来很聪明.它们可以在物理系统上建模,如天气预报,并且可以提供非真实随机但难以预测的数字输出,可以将其视为奇怪的吸引子(和SA).