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

Computer Graphics, Animaition, OpenGL, DirectX, OpenCL
头像
523066680
Administrator
Administrator
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

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

帖子 #11 523066680 » 2016年10月15日 09:53

图片

test: 0.048911, rtx: 0.901808
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. unsigned char RD(int i, int j)
  2. {
  3.     int x = j ;
  4.     int y = i ;
  5.     return sqrt(x) * sqrt(y) * pow( tan((float) (x%100/2)  /(float) y ), test) / rtx;
  6. }
  7.  
  8. unsigned char GR(int i, int j)
  9. {
  10.     int x = j/2 ;
  11.     int y = i/2 ;
  12.     return sqrt(x) * sqrt(y) * pow( tan((float) (x%100/2)  /(float) y ), test) / rtx;
  13. }

24game
渐入佳境
渐入佳境
帖子: 42
注册时间: 2016年09月02日 22:09
拥有现金: 锁定
Has thanked: 3 times
Been thanked: 15 times
联系:

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

帖子 #12 24game » 2016年10月15日 16:17

求破: 五角星

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

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

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

图片

我能达到的最短方案, 主代码 206 字节: 回旋镖方案
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. RD:
  2. #define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
  3. 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;
  4.  
  5. GR:
  6. return 0;
  7.  
  8. BL:
  9. return 0;


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

上图中的回旋镖是正下方位置的, 绘图代码如下
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. 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 个整数由下面的代码计算得出
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. (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) 返回真值, 否则返回假.

在直线一侧的判定原理:
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. 直线 (x1, y1-- x2, y2) 的方程 :  ;
  2. (y - y2) (x1 - x2) == (x - x2) (y1 - y2);
  3. 直线 (a, b-- c, d) 的方程 :  ;
  4. (y - d) (a - c) == (x - c) (b - d);
  5.  
  6. 直线 (a, b-- c, d) 的西侧: (a,b) 为北, (c,d) 为南
  7. #define _W(a,b,c,d) ((j-d)*(a-c)<(i-c)*(b-d))
  8.  
  9. (a,b) = (r*cos(u),r*sin(u)), (c,d) = (r*cos(v),r*sin(v))
  10. 直线 (u,v) 的西侧
  11. #define W(u,v) ((j-r*sin(v))*(r*cos(u)-r*cos(v))<(i-r*cos(v))*(r*sin(u)-r*sin(v)))




四边形箭头方案, 稍长
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. RD:
  2. #define W(u,v) ((j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v)))
  3. i-=512;j-=512;
  4. float P=acos(-1),r=500,t=-(((int)((!i&&!j?0:fmod(atan2(i,j)+P,2*P))/(.2*P))+1)/2)*.4*P;
  5. 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;
  6.  
  7. GR:
  8. return 0;
  9.  
  10. BL:
  11. return 0;
上次由 24game 在 2016年10月16日 19:44,总共编辑 3 次。

头像
523066680
Administrator
Administrator
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

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

帖子 #13 523066680 » 2016年10月15日 16:54

24game 写了:求破: 五角星...


想起来昨天翻了那个网站的各种作品,有个图是米国国旗 http://codegolf.stackexchange.com/posts/35595/revisions
我先试试五角星不管字数

24game
渐入佳境
渐入佳境
帖子: 42
注册时间: 2016年09月02日 22:09
拥有现金: 锁定
Has thanked: 3 times
Been thanked: 15 times
联系:

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

帖子 #14 24game » 2016年10月15日 18:21

我要自己破掉啦, 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
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

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

帖子 #15 523066680 » 2016年10月15日 18:23

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


也想到了 放到 GR 和 BL用分段函数区分返回 。不过我还在折腾论坛的东西
想弄个自动发帖的脚本一下午没搞定,原来论坛会在发帖时生成 form_token,脚本提交的时候如果不匹配则视为重复或者多余操作无法提交。

24game
渐入佳境
渐入佳境
帖子: 42
注册时间: 2016年09月02日 22:09
拥有现金: 锁定
Has thanked: 3 times
Been thanked: 15 times
联系:

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

帖子 #16 24game » 2016年10月15日 19:05

523066680 写了:也想到了 放到 GR 和 BL用分段函数区分返回 。不过我还在折腾论坛的东西
想弄个自动发帖的脚本一下午没搞定,原来论坛会在发帖时生成 form_token,脚本提交的时候如果不匹配则视为重复或者多余操作无法提交。


我高兴早了, 还是没能破掉, 因为其中一部分想转移走的代码即使全转走不计, 也没能减到 140 字节以内

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

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

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

24game
渐入佳境
渐入佳境
帖子: 42
注册时间: 2016年09月02日 22:09
拥有现金: 锁定
Has thanked: 3 times
Been thanked: 15 times
联系:

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

帖子 #17 24game » 2016年10月15日 23:40

太极

图片

Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. RD:
  2. // 无外廓圆, 不到 140 字节
  3. #define T(r) i*i+_sq(j-(j>>31|1)*150)<r*r
  4. i-=512;j-=512;int k=j>>31&1;
  5. return (T(40)?k^1:T(150)?k:i*i+j*j<90000?i>>31&1:.95)*255;
  6.  
  7. // 有外廓圆, 长于 140 字节
  8. // #define S(r) i*i+j*j<r*r
  9. // #define T(r) i*i+_sq(j-(j>>31|1)*150)<r*r
  10. // i-=512;j-=512;int k=j>>31&1;
  11. // return (T(40)?k^1:T(150)?k:S(300)?i>>31&1:S(303)?0:1)*255;
  12.  
  13.  
  14. // 太极绘图原理
  15. // return (在小圆内?(上?0:1):(在中圆内?(上?1:0):(在大圆内?(左?1:0):(在廓圆内?0:1))))*255;
  16. // 廓圆半径: 303; 大圆半径: 300; 中圆半径: 150 中心 0, +-150; 小圆半径: 40  中心 0, +-150
  17.  
  18. GR:
  19. return RD(i,j);
  20.  
  21. BL:
  22. return RD(i,j);

头像
523066680
Administrator
Administrator
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

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

帖子 #18 523066680 » 2016年10月16日 00:33

我打算用三个三角形,拼凑,先不管代码量
penta.png
penta.png (2.46 KiB) 查看 719 次
penta.png
penta.png (2.46 KiB) 查看 719 次


先用直观的方式写了有重复的代码,有待整理
Code: [全选] [展开/收缩] [Download] (Untitled.c)
  1. unsigned char RD(int i, int j)
  2. {
  3.     float x, y;
  4.     float ang = 0/360.0*6.28;
  5.     i = i-500;
  6.     j = j-500;
  7.     x = i * cos(ang) + j * sin(ang);
  8.     y = -i * sin(ang) + j * cos(ang) + 110.557;
  9.  
  10.     if ( (y/x > 0.7265425 || y/x < -0.7265425) && y < 200 && y > 0 )
  11.     {
  12.         return 254;
  13.     }
  14.     else
  15.     {
  16.         return 0;
  17.     }
  18. }


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
wrong.png (40.56 KiB) 查看 680 次
wrong.png
wrong.png (40.56 KiB) 查看 680 次


所以应该找到一个离顶点等距离的中心
center.png

24game
渐入佳境
渐入佳境
帖子: 42
注册时间: 2016年09月02日 22:09
拥有现金: 锁定
Has thanked: 3 times
Been thanked: 15 times
联系:

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

帖子 #19 24game » 2016年10月16日 13:49

和你画了一样的, 就换了个配色
图片

Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. unsigned char RD(int i,int j)
  2. {
  3. /* 五个角的角度值除以 PI 后的商
  4.  
  5.       1.5
  6.   1.1    1.9
  7.  
  8.     .7  .3
  9. */
  10. #define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
  11. i-=512;j-=512;float P=acos(-1),r=300;
  12. return W(1.5*P,+.3*P)&&W(1.9*P,.7*P)&&W(.7*P,1.5*P)?255:0;
  13. }
  14. unsigned char GR(int i,int j)
  15. {
  16. #define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
  17. i-=512;j-=512;float P=acos(-1),r=300;
  18. return W(1.9*P,+.7*P)&&W(.3*P,1.1*P)&&W(1.1*P,1.9*P)?255:0;
  19. }
  20. unsigned char BL(int i,int j)
  21. {
  22. #define W(u,v) (j-r*sin(v))*(cos(u)-cos(v))<(i-r*cos(v))*(sin(u)-sin(v))
  23. i-=512;j-=512;float P=acos(-1),r=300;
  24. return W(.3*P,+1.1*P)&&W(.7*P,1.5*P)&&W(1.5*P,.3*P)?255:0;
  25. }

头像
523066680
Administrator
Administrator
帖子: 340
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 30 times
Been thanked: 27 times
联系:

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

帖子 #20 523066680 » 2016年10月16日 14:50

红色五角星
我想尝试把其中一个#define 放到 GR函数中去,结果不行,即使是提前调用GR()。不知道有没有什么编译指令可以支持这种方式?
包括转行,RD内大约194个字符。
Code: [全选] [展开/收缩] [Download] (Untitled.c)
  1. unsigned char RD(int i, int j)
  2. {
  3. #define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
  4. #define F if ((y/x>0.726||y/x<-0.726)&&y<200&&y>0) return 254;
  5. float x,y,g;
  6. i-=500;j-=500;X(0.0);F;X(-1.256);F;X(1.256);F;
  7. GR(0,0);
  8. }
  9.  
  10. unsigned char GR(int i, int j)
  11. {
  12.     return 0;
  13. }

相应的,如果是绿色五角星,就好办了;
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. unsigned char RD(int i, int j)
  2. {
  3. #define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
  4. #define F if((y/x>0.72||y/x<-0.72)&&y<200&&y>0)return 254;
  5. BL(0,0);
  6. }
  7.  
  8. unsigned char GR(int i, int j)
  9. {
  10. float x,y,g;
  11. i-=500;j-=500;X(0.0);F;X(-1.256);F;X(1.256);F;
  12. BL(0,0);
  13. }
  14.  
  15. unsigned char BL(int i,int j)
  16. {
  17. return 0;
  18. }

分割线

基于第二段代码,我想到了,要让上面的代码变成显示红色,完全可以让RD获取GR函数的结果。GR内做判断,
如果是被RD调用,则执行RD需要的代码并返回,其他情况,返回0。RD内135个字符,GR内82个字符,包括换行。
Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
  1. unsigned char RD(int i, int j)
  2. {
  3. #define X(g) x=i*cos(g)+j*sin(g);y=-i*sin(g)+j*cos(g)+110.557;
  4. #define F if((y/x>0.72||y/x<-0.72)&&y<200&&y>0)return 254;
  5. GR(i,j+1000);
  6. }
  7.  
  8. unsigned char GR(int i, int j)
  9. {
  10. float x,y,g;
  11. if (j>DIM) {i-=500;j-=1500;X(0.0);F;X(-1.256);F;X(1.256);F;}
  12. BL(0,0);
  13. }
  14.  
  15. unsigned char BL(int i,int j)
  16. {
  17. return 0;
  18. }


回到 “计算机图形”

在线用户

用户浏览此论坛: 没有注册用户 和 0 访客