慢羊羊的空间

工作做不完了,300出,无瑕。

[译] 短小精悍又不可思议的数学艺术挑战赛 - 作品集 1

比赛简介

怎样使用本文中的代码,以及详细比赛规则,请看:https://codebus.cn/yangw/tweetable-mathematical-art

以下是各路大神的优秀作品。

1. Table cloths

by trichoplax,208 票。

步骤一,平展的效果。代码:

unsigned char RD(int i,int j)
{
	float s=3./(j+99);
	return (int((i+DIM)*s+j*s)%2+int((DIM*2-i)*s+j*s)%2)*127;
}
unsigned char GR(int i,int j)
{
	float s=3./(j+99);
	return (int((i+DIM)*s+j*s)%2+int((DIM*2-i)*s+j*s)%2)*127;
}
unsigned char BL(int i,int j)
{
	float s=3./(j+99);
	return (int((i+DIM)*s+j*s)%2+int((DIM*2-i)*s+j*s)%2)*127;
}

生成效果:

步骤二,加涟漪效果。代码:

unsigned char RD(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}
unsigned char GR(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}
unsigned char BL(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}

生成效果:

步骤三,加彩色效果。代码:

unsigned char RD(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}
unsigned char GR(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int(5*((i+DIM)*s+y))%2+int(5*((DIM*2-i)*s+y))%2)*127;
}
unsigned char BL(int i,int j)
{
	float s=3./(j+99);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
	return (int(29*((i+DIM)*s+y))%2+int(29*((DIM*2-i)*s+y))%2)*127;
}

生成效果:

步骤四,加动态效果。代码:

增加的常量 P(两位小数)表示涟漪的相位。通过修改 P 可以得到一系列的图片,连续起来就可以整合成一个平滑的动画。

unsigned char RD(int i,int j)
{
	#define P 6.03
	float s=3./(j+250),y=(j+sin((i*i+_sq(j-700)*5)/100./DIM+P)*15)*s;return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}
unsigned char GR(int i,int j)
{
	float s=3./(j+250);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM+P)*15)*s;
	return (int(5*((i+DIM)*s+y))%2+int(5*((DIM*2-i)*s+y))%2)*127;
}
unsigned char BL(int i,int j)
{
	float s=3./(j+250);
	float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM+P)*15)*s;
	return (int(29*((i+DIM)*s+y))%2+int(29*((DIM*2-i)*s+y))%2)*127;
}

生成效果:

2. Random painter

by Martin Ender,190 票。

这是一个基于随机性的作品。对于大约 0.1% 的像素,它选择随机颜色,对于其他像素,它使用相邻像素的颜色。注意,每种颜色都是独立的,所以这实际上只是一个随机的绿色、蓝色和红色叠加的图片。注:为了在不同的运行中获得不同的结果,需要将srand(time(NULL))添加到主函数中(原挑战的主函数没有设置随机种子)。

代码:

unsigned char RD(int i, int j)
{
	#define r(n) (rand()%n)
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):RD((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}
unsigned char GR(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):GR((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}
unsigned char BL(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):BL((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}

生成效果:

现在来看一些变化。

通过跳过像素,我们可以使其更加模糊。

代码:(原作者未提供,以下代码为译者补充,不能确保是作者的本意)

unsigned char RD(int i, int j)
{
	#define r(n) (rand()%n)
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):RD((i+r(4))%1024,(j+r(4))%1024):c[i][j];
}
unsigned char GR(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):GR((i+r(4))%1024,(j+r(4))%1024):c[i][j];
}
unsigned char BL(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):BL((i+r(4))%1024,(j+r(4))%1024):c[i][j];
}

生成效果:

然后我们可以慢慢地改变颜色,溢出会导致突然的变化,这让它看起来更像画笔。

代码:(作者未提供)

生成效果:

必须指出:

  • 出于某种原因,我无法在这些函数中放置 srand,否则会产生段错误。
  • 如果我能使这三种颜色的随机游动相同,它可能看起来更有秩序。

也可以使随机行走各向同性,代码:

unsigned char RD(int i, int j)
{
	#define r(n) (rand()%n)
	static char c[1024][1024];return!c[i][j]?c[i][j]=r(999)?RD((i+r(5)+1022)%1024,(j+r(5)+1022)%1024):r(256):c[i][j];
}
unsigned char GR(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=r(999)?GR((i+r(5)+1022)%1024,(j+r(5)+1022)%1024):r(256):c[i][j];
}
unsigned char BL(int i, int j)
{
	static char c[1024][1024];return!c[i][j]?c[i][j]=r(999)?BL((i+r(5)+1022)%1024,(j+r(5)+1022)%1024):r(256):c[i][j];
}

生成效果:

3. Some swirly pointy things

by cjfaure,162 票。

代码:

unsigned char RD(int i, int j)
{
	unsigned short n = (sqrt(_sq(73.-i)+_sq(609-j))+1)/(sqrt(fabs(sin((sqrt(_sq(860.-i)+_sq(162-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
unsigned char GR(int i, int j)
{
	unsigned short n = (sqrt(_sq(160.-i)+_sq(60-j))+1)/(sqrt(fabs(sin((sqrt(_sq(86.-i)+_sq(860-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
unsigned char BL(int i, int j)
{
	unsigned short n = (sqrt(_sq(844.-i)+_sq(200-j))+1)/(sqrt(fabs(sin((sqrt(_sq(250.-i)+_sq(20-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
// 译者注:原作者用的 abs,我将其修改为了 fabs 才能得到目标效果

生成效果:

可以很容易地更改参考点以获得不同的图片。例如更改为如下代码(译者注:我将原文中的 abs 修改为了 fabs 才能得到正确效果):

unsigned char RD(int i, int j)
{
	unsigned short n = (sqrt(_sq(148.-i)+_sq(1000-j))+1)/(sqrt(fabs(sin((sqrt(_sq(500.-i)+_sq(400-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
unsigned char GR(int i, int j)
{
	unsigned short n = (sqrt(_sq(610.-i)+_sq(60-j))+1)/(sqrt(fabs(sin((sqrt(_sq(864.-i)+_sq(860-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
unsigned char BL(int i, int j)
{
	unsigned short n = (sqrt(_sq(180.-i)+_sq(100-j))+1)/(sqrt(fabs(sin((sqrt(_sq(503.-i)+_sq(103-j)))/115.0)))+1)/200;
	n &= DM1;
	return (n >> 8 | n << 8) * 255 / 1023;
}
// 译者注:原作者用的 abs,我将其修改为了 fabs 才能得到目标效果

生成效果:

添加评论