求破: 五角星
我用了很大劲, 只把代码整到 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;