[收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

Computer Graphics, Animaition, OpenGL, DirectX, OpenCL
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 523066680 »

图片

test: 0.048911, rtx: 0.901808
unsigned char RD(int i, int j)
{
int x = j ;
int y = i ;
return sqrt(x) * sqrt(y) * pow( tan((float) (x%100/2) /(float) y ), test) / rtx;
}

unsigned char GR(int i, int j)
{
int x = j/2 ;
int y = i/2 ;
return sqrt(x) * sqrt(y) * pow( tan((float) (x%100/2) /(float) y ), test) / rtx;
}
24game
渐入佳境
渐入佳境
帖子: 54
注册时间: 2016年09月02日 22:09
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 24game »

求破: 五角星

我用了很大劲, 只把代码整到 300 字节以内, 哪位能用 140 以内字节绘出五角星

我想到一个方案还能减少大概 三 四十左右字节, 但离减到 140 以内还差得远

最后
我到了 21 楼 http://www.code-by.org/viewtopic.php?p=519#p519 用了 523066680 的三角形思路 , 才真的自己破了这个

图片

我能达到的最短方案, 主代码 206 字节: 回旋镖方案
RD:
#define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
i-=512;j-=512;float P=acos(-1),r=500,t=(2-(int)((!i&&!j?0:atan2(i,j)+P)/.4/P))*.4*P;return W(t-.9*P,t+.3*P)&&W(t-1.3*P,t-.1*P)?0:255;

GR:
return 0;

BL:
return 0;
回旋镖方案原理:
将五角星分成方向角依次相差 Pi*2/5 的五个回旋镖形状
图片

上图中的回旋镖是正下方位置的, 绘图代码如下
return W(-.9*P,.3*P)&&W(-1.3*P,-.1*P)?0:255;
其他四个镖相对于上图的角度偏移分别是 左上: 0.8*Pi; 左下: 0.4*Pi; 右上: -0.8*Pi; 右下: -0.4*Pi;

下图将5个镖形用深浅不同的红色拼在一起

图片

t 的计算将绘图平面区域按相对于平面中心的角度分成 5 个区域, 5 个分界角度分别是 -1.3*Pi, -.9*Pi, -.5*Pi, -.1*Pi, .3*Pi
5 个分界角度 映射为 与 -.5*Pi 的差值 就是: -0.8*Pi, -0.4*Pi, 0, 0.4*Pi, 0.8*Pi; 全除以 (0.4*Pi) 得 [-2,-1,0,1,2], 这 5 个整数由下面的代码计算得出
(2-(int)((!i&&!j?0:atan2(i,j)+P)/.4/P))
而宏函数 W(u,v) 则是求一条直线西侧区域的逻辑函数, 一条直线由 2 个点来确定, 这两个点在绘图平面中心为圆心的同一个圆周上, 它们在圆周上的角度由 u 和 v 来指定
它们的坐标是 {r*cos(u),r*sin(u)} 和 {r*cos(v),r*sin(v)}, {r*cos(u),r*sin(u)} 所在的方向定义为 北, {r*cos(v),r*sin(v)} 所在的方向定义为 南,
如果 {i,j} 在上述直线的西侧, W(u,v) 返回真值, 否则返回假.

在直线一侧的判定原理:
直线 (x1, y1-- x2, y2) 的方程 :  ;
(y - y2) (x1 - x2) == (x - x2) (y1 - y2);
直线 (a, b-- c, d) 的方程 : ;
(y - d) (a - c) == (x - c) (b - d);

直线 (a, b-- c, d) 的西侧: (a,b) 为北, (c,d) 为南
#define _W(a,b,c,d) ((j-d)*(a-c)<(i-c)*(b-d))

设 (a,b) = (r*cos(u),r*sin(u)), (c,d) = (r*cos(v),r*sin(v))
直线 (u,v) 的西侧
#define W(u,v) ((j-r*sin(v))*(r*cos(u)-r*cos(v))<(i-r*cos(v))*(r*sin(u)-r*sin(v)))


四边形箭头方案, 稍长
RD:
#define W(u,v) ((j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v)))
i-=512;j-=512;
float P=acos(-1),r=500,t=-(((int)((!i&&!j?0:fmod(atan2(i,j)+P,2*P))/(.2*P))+1)/2)*.4*P;
return W(t-P/2,t+.3*P)&&W(t-1.3*P,t-P/2)&&W(t+.3*P,t-.9*P)&&W(t-.1*P,t-1.3*P)?255:0;

GR:
return 0;

BL:
return 0;
上次由 24game 在 2016年10月16日 19:44,总共编辑 3 次。
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 523066680 »

24game 写了:求破: 五角星...
想起来昨天翻了那个网站的各种作品,有个图是米国国旗 http://codegolf.stackexchange.com/posts/35595/revisions
我先试试五角星不管字数
24game
渐入佳境
渐入佳境
帖子: 54
注册时间: 2016年09月02日 22:09
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 24game »

我要自己破掉啦, 1. 用另一种方案减少 40 字节左右; 2. 将一部分代码转移到 GR 里去. 我觉得马上就破掉啦

我到了 21 楼 http://www.code-by.org/viewtopic.php?p=519#p519 用了 523066680 的三角形思路 , 才真的自己破了这个
上次由 24game 在 2016年10月16日 19:42,总共编辑 1 次。
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 523066680 »

24game 写了:我要自己破掉啦, 1. 用另一种方案减少 40 字节左右; 2. 将一部分代码转移到 GR 里去. 我觉得马上就破掉啦
也想到了 放到 GR 和 BL用分段函数区分返回 。不过我还在折腾论坛的东西
想弄个自动发帖的脚本一下午没搞定,原来论坛会在发帖时生成 form_token,脚本提交的时候如果不匹配则视为重复或者多余操作无法提交。
24game
渐入佳境
渐入佳境
帖子: 54
注册时间: 2016年09月02日 22:09
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 24game »

523066680 写了: 也想到了 放到 GR 和 BL用分段函数区分返回 。不过我还在折腾论坛的东西
想弄个自动发帖的脚本一下午没搞定,原来论坛会在发帖时生成 form_token,脚本提交的时候如果不匹配则视为重复或者多余操作无法提交。
我高兴早了, 还是没能破掉, 因为其中一部分想转移走的代码即使全转走不计, 也没能减到 140 字节以内

另外, 三个色分量函数的类型是 unsigned char 只有 8 位可用, 如果把其他代码转入其中, 将无法不产生副作用, 噪色.

最终, 换了第二种方案, 我的洪荒之力也只能达到 206 字节

另外, 我以前开发过 ASP 的进销存, 有一个表单录入的界面, 开始用户在提交表单时, 总有用户双击(小白用户总能把你代码的漏洞暴露很多出来)提交按钮, 造成表单重复提交, 我苦思后, 也是用了 类似 form_token 的方式才把那问题解决了, 会话中会生成一个表单唯一的标识(例如用户ID+时间戳), 接受提交时, 如果那个标识没有被提交, 没有被处理, 才会提交成功, 否则就忽略重复的提交
24game
渐入佳境
渐入佳境
帖子: 54
注册时间: 2016年09月02日 22:09
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 24game »

太极

图片
RD:
// 无外廓圆, 不到 140 字节
#define T(r) i*i+_sq(j-(j>>31|1)*150)<r*r
i-=512;j-=512;int k=j>>31&1;
return (T(40)?k^1:T(150)?k:i*i+j*j<90000?i>>31&1:.95)*255;

// 有外廓圆, 长于 140 字节
// #define S(r) i*i+j*j<r*r
// #define T(r) i*i+_sq(j-(j>>31|1)*150)<r*r
// i-=512;j-=512;int k=j>>31&1;
// return (T(40)?k^1:T(150)?k:S(300)?i>>31&1:S(303)?0:1)*255;


// 太极绘图原理
// return (在小圆内?(上?0:1):(在中圆内?(上?1:0):(在大圆内?(左?1:0):(在廓圆内?0:1))))*255;
// 廓圆半径: 303; 大圆半径: 300; 中圆半径: 150 中心 0, +-150; 小圆半径: 40 中心 0, +-150

GR:
return RD(i,j);

BL:
return RD(i,j);
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 523066680 »

我打算用三个三角形,拼凑,先不管代码量
penta.png
(2.46 KiB) 已下载 1914 次
先用直观的方式写了有重复的代码,有待整理
unsigned char RD(int i, int j)
{
float x, y;
float ang = 0/360.0*6.28;
i = i-500;
j = j-500;
x = i * cos(ang) + j * sin(ang);
y = -i * sin(ang) + j * cos(ang) + 110.557;

if ( (y/x > 0.7265425 || y/x < -0.7265425) && y < 200 && y > 0 )
{
return 254;
}
else
{
return 0;
}
}
GR 和 BL 内容一样,不过旋转角的设定(ang = 0/360.0*6.28) 分别是 -72° 和 72°
110.557 是用计算出来的,R+R*cos(36°) = 200,求出旋转中心的高度约为110.557
良心绘图:
如果中心移动到 x=0,y=100处,对两个副本分别旋转-72° 和 72°,效果是这样的:
wrong.png
(40.56 KiB) 已下载 1875 次
所以应该找到一个离顶点等距离的中心
center.png
24game
渐入佳境
渐入佳境
帖子: 54
注册时间: 2016年09月02日 22:09
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 24game »

和你画了一样的, 就换了个配色
图片
unsigned char RD(int i,int j)
{
/* 五个角的角度值除以 PI 后的商

1.5
1.1 1.9

.7 .3
*/
#define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
i-=512;j-=512;float P=acos(-1),r=300;
return W(1.5*P,+.3*P)&&W(1.9*P,.7*P)&&W(.7*P,1.5*P)?255:0;
}
unsigned char GR(int i,int j)
{
#define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
i-=512;j-=512;float P=acos(-1),r=300;
return W(1.9*P,+.7*P)&&W(.3*P,1.1*P)&&W(1.1*P,1.9*P)?255:0;
}
unsigned char BL(int i,int j)
{
#define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
i-=512;j-=512;float P=acos(-1),r=300;
return W(.3*P,+1.1*P)&&W(.7*P,1.5*P)&&W(1.5*P,.3*P)?255:0;
}
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Re: [收集]用三段 140 字符以内的代码生成一张 1024×1024 的图片

帖子 523066680 »

红色五角星
我想尝试把其中一个#define 放到 GR函数中去,结果不行,即使是提前调用GR()。不知道有没有什么编译指令可以支持这种方式?
包括转行,RD内大约194个字符。
unsigned char RD(int i, int j)
{
#define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
#define F if ((y/x>0.726||y/x<-0.726)&&y<200&&y>0) return 254;
float x,y,g;
i-=500;j-=500;X(0.0);F;X(-1.256);F;X(1.256);F;
GR(0,0);
}

unsigned char GR(int i, int j)
{
return 0;
}
相应的,如果是绿色五角星,就好办了;
unsigned char RD(int i, int j)
{
#define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
#define F if((y/x>0.72||y/x<-0.72)&&y<200&&y>0)return 254;
BL(0,0);
}

unsigned char GR(int i, int j)
{
float x,y,g;
i-=500;j-=500;X(0.0);F;X(-1.256);F;X(1.256);F;
BL(0,0);
}

unsigned char BL(int i,int j)
{
return 0;
}
分割线
基于第二段代码,我想到了,要让上面的代码变成显示红色,完全可以让RD获取GR函数的结果。GR内做判断,
如果是被RD调用,则执行RD需要的代码并返回,其他情况,返回0。RD内135个字符,GR内82个字符,包括换行。
unsigned char RD(int i, int j)
{
#define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
#define F if((y/x>0.72||y/x<-0.72)&&y<200&&y>0)return 254;
GR(i,j+1000);
}

unsigned char GR(int i, int j)
{
float x,y,g;
if (j>DIM) {i-=500;j-=1500;X(0.0);F;X(-1.256);F;X(1.256);F;}
BL(0,0);
}

unsigned char BL(int i,int j)
{
return 0;
}
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客