画雪花


18

乔住在巴哈马。现在是冬天。他的孩子对没有雪感到失望。乔需要为他的孩子们造雪。幸运的是,他有一台3D打印机。他计划用它制作雪花。不幸的是,他不知道雪花会是什么样。实际上,他从未见过雪花!让我们通过创建一个为他自动生成雪花的2d图像的程序来帮助他。

输入值

图片的直径(以像素为单位),实际上是雪花的图片的百分比。

输出量

雪花的图像具有所需的直径。它可以保存到文件或显示给用户。

技术指标

创建一个具有30度角的楔形。用楔形点的初始种子创建布朗树。将楔形围绕图像中心反射12次,以生成其余图像。雪花的颜色为白色。背景颜色为黑色。

计分

由于存在生成布朗树的方法不同,因此得分为10 *投票数-高尔夫得分。

高尔夫球成绩定义为程序中具有以下奖励的字节数:

-20%可以任意指定雪花的对称性。

-50%可以指定雪花的形状。(通过能够指定楔形边的长度之比。)

最高分获胜。

这是一张图片,楔形的比例约为2:

楔

计分板:

马丁·巴特纳:10 * 14-409 = -269

妮米(Nimi):10 * 1-733 * .5 = -356.5

优化器:10 * 5-648 = -598

获胜者是得分为-269的马丁!



9
我不明白为什么,如果据称我们要帮助从未看过雪花的人知道它们的外观,我们应该使它们具有4阶旋转对称性。我们应该在诱骗那个可怜的家伙吗?
彼得·泰勒

1
@Conor“分数是10 *投票数-golfscore。” 该程序的得分为-300000000。那太低了。
TheNumberOne 2014年

1
6x60deg楔形!在@PeterTaylor发表评论时说的内容有所改进,但实际上您需要12x30deg的楔形。.6个点中的每个右侧为6个,每个点的左侧为6个反射的。顺便说一句,我不明白第二个奖励
Level River St

2
@Optimizer完成,现在应该更清楚了。
TheNumberOne 2014年

Answers:


16

Mathematica,409个字节

{n,p}=Input[];m=999;Clear@f;_~f~_=0;0~f~0=1;r=RandomInteger;For[i=0,i<m,++i,For[x=m;y=0,f[x+1,y]+f[x-1,y]+f[x,y+1]+f[x,y-1]<1,a=b=-m;While[x+a<0||y+b<0||(y+b)/(x+a)>Tan[Pi/6],a=-r@1;b=r@2-1];x+=a;y+=b];x~f~y=1];Graphics[{White,g=Point/@Join@@{c=Cases[Join@@Table[{i,j}-1,{i,m},{j,m}],{i_,j_}/;i~f~j>0],c.{{1,0},{0,-1}}},Array[Rotate[g,Pi#/3,{0,0}]&,6]},Background->Black,ImageSize->n*p,ImageMargins->n(1-p)/2]

取消高尔夫:

{n,p}=Input[];
m = 999;
ClearAll@f;
_~f~_ = 0;
0~f~0 = 1;
r = RandomInteger;
For[i = 0, i < m, ++i,
  For[x = m; y = 0, 
   f[x + 1, y] + f[x - 1, y] + f[x, y + 1] + f[x, y - 1] < 1,
   a = b = -m;
   While[x + a < 0 || y + b < 0 || (y + b)/(x + a) > Tan[Pi/6],
    a = -r@1;
    b = r@2 - 1
    ];
   x += a;
   y += b
   ];
  x~f~y = 1
  ];
Graphics[
 {White, g = 
   Point /@ 
    Join @@ {c = 
       Cases[Join @@ Table[{i, j} - 1, {i, m}, {j, m}], {i_, j_} /;
          i~f~j > 0], c.{{1, 0}, {0, -1}}}, 
  Array[Rotate[g, Pi #/3, {0, 0}] &, 6]},
 Background -> Black,
 ImageSize -> n*p,
 ImageMargins -> n (1 - p)/2
 ]

这需要输入形式{n,p},其中n是以像素为单位的图像大小,p是雪花所覆盖图像的百分比。

用给定的参数生成雪花大约需要半分钟的时间。您可以通过改变价值加速它m99999,但随后的结果看起来有点稀疏。同样,您可以使用较大的数字来提高质量,但是这将花费很长时间。

我正在一个整数网格上形成布朗树,在处放置新粒子{999, 0},然后将其随机向左或向上或向下移动(而不是向右移动),直到它们碰到现有粒子。我还将运动限制在0到30度之间。最后,我在x轴上反射该楔形,并显示其5圈旋转。

以下是一些结果(点击查看大图):

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

这是布朗树生长的两个动画(每帧每楔形10个粒子):

在此处输入图片说明在此处输入图片说明


2
哇,我真的很喜欢。结果不错!
Sp3000

6

JavaScript,ES6,799 740 695 658 648

我只在f下面的代码片段中计算两个画布标签和函数,作为字节计数的一部分。其余的部分用于现场演示

要观看它的运行,只需在最新的Firefox中运行以下代码段,并通过输入框提供大小和比率

请注意,您将必须隐藏结果,然后在连续的雪花之前再次显示

f=(N,P)=>{E.width=E.height=D.width=D.height=N
E.style.background="#000"
C=D.getContext("2d"),F=E.getContext("2d")
C.strokeStyle='#fff'
M=Math,r=M.random,I=0,n=N/2
C.beginPath()
C.rect(n,n,2,2)
C.fill()
B=_=>{x=n*P/100,y=0,w=[]
do{w.push([x,y])
do{X=2*((r()*2)|0)
Y=2*(((r()*3)|0)-1)
}while(x-X<0||y-Y<0||(y-Y)/(x-X)>.577)
x-=X,y-=Y}while(!C.isPointInPath(n+x,n+y))
I++
w=w.slice(-4)
x=w[0]
C.moveTo(x[0]+n,x[1]+n)
w.map(x=>C.lineTo(n+x[0],n+x[1]))
C.stroke()
E.width=E.height=N
for(i=0;i<12;i++){F.translate(n,n)
i||F.rotate(M.PI/6)
i-6?F.rotate(M.PI/3):F.scale(1,-1)
F.translate(-n,-n)
F.drawImage(D,0,0)}
I<(n*n*P*.22/100)&&setTimeout(B,15)}
B()}
<input placeholder="Input N" id=X /><input placeholder="Input percentage" id=Y /><button onclick="f(~~X.value,~~Y.value)">Create snowflake</button><br>
<canvas id=E><canvas id=D>

以下是一些具有不同大小和百分比的渲染示例。最好的是SkullFlake(在列表中排名第一)。单击图像以全分辨率查看它们。

在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明

Martin和githubphagocyte提供了大量帮助和意见。


这不会将填充图像的百分比作为输入。
TheNumberOne 2015年

@TheBestOne现在将百分比考虑在内。请注意,由于这是基于布朗树的雪花,因此楔形长度的百分比或比率都不能准确,因为随机性在起作用。
Optimizer

现在,这符合条件。
TheNumberOne 2015年

1

Haskell,781733字节

该程序具有“指定楔形边的长度之比”选项的功能,因此您必须使用三个命令行参数来调用它:

./sf 150 50 40

参数#1是图像的大小,#2是楔形中像素的百分比,#3是楔形较短边的长度(%)。图像保存在名为“ o.png”的文件中。

150-50-40: 150-50-40

我的程序会产生带有截止尖峰的雪花,这是因为新像素开始于楔形的中轴(绿点,见下文),并且倾向于停留在此,因为它们向左,上或下均等地随机移动。随着楔形外部的像素被丢弃,在楔形边界上会出现直线(绿色箭头)。我懒得尝试其他的像素路径。

150-50-40: 150-40-40e

当楔形足够大时(第三个参数100),中轴上的尖峰会增大,然后有12个。

150-40-100: 150-40-100

很少有像素会变成圆形(左:150-5-20;右150-20-90)。

150-5-20 150-20-90

该程序:

import System.Environment;import System.Random;import Graphics.GD
d=round;e=fromIntegral;h=concatMap;q=0.2588
j a(x,y)=[(x,y),(d$c*e x-s*e y,d$s*e x+c*e y)] where c=cos$pi/a;s=sin$pi/a
go s f w p@(x,y)((m,n):o)|x<1=go s f w(s,0)o|abs(e$y+n)>q*e x=go s f w p o|elem(x-m,y+n)f&&(v*z-z)*(b-q*z)-(-v*q*z-q*z)*(a-z)<0=p:go s(p:f)w(s,0)o|1<2=go s f w(x-m,y+n)o where z=e s;a=e x;b=e y;v=e w/100
main = do 
 k<-getArgs;g<-getStdGen;let(s:p:w:_)=map read k
 i<-newImage(2*s,2*s);let t=h(j 3)$h(\(x,y)->[(x,y),(d$0.866*e x+0.5*e y,d$0.5*e x-0.866*e y)])$take(s*d(q*e s)*p`div`100)$go s[(0,0)]w(s,0)$map(\r->((1+r)`mod`2,r))(randomRs(-1,1)g)
 mapM(\(x,y)->setPixel(x+s,y+s)(rgb 255 255 255)i)((h(j(-3/2))t)++(h(j(3/2))t));savePngFile "o.png" i

@Optimizer:峰值位于楔形的中轴上。楔形相对于x轴上下15度。在*-*-100图像中,其两侧都到达图像的左边界(有关楔形的位置,请参见第二个图像)。大约一半的侧面上都有像素-其他一半是空的。
nimi 2014年

1
使用此计数器,程序长度为841个字节。
TheNumberOne 2015年

@TheBestOne:缩进时的制表符与空格。当为新增4个空格时,我将它们混在一起code style。我已经编辑了帖子并设置了“标签”,但它们仍显示为空格。有谁知道如何修理它?
nimi 2015年

@nimi在TheBestOne网站上#链接,您可以单击一个小哈希链接。您可以在其中粘贴选项卡式代码并将其链接。
Sp3000

您可能可以链接到某个地方的代码。您可以使用空格而不是制表符来缩进。您可以code style通过每行缩进4个空格来手动获取。
TheNumberOne 2015年

0

处理2-575个字符

接收文件f,文件的第一行是图像大小,第二行是薄片半径。每次放置新点时,都会将其绕中心旋转12次。这会产生与旋转楔块非常相似的效果,但并不完全相同。

  int d,w,h,k,l,o,p,x,y;
  String n[] = loadStrings("f.txt");
  d=Integer.parseInt(n[0]);
  h=Integer.parseInt(n[1]);
  size(d,d);
  w=d/2;
  k=l=(int)random(d); 
  background(0);
  loadPixels();
  o=p=0;
  pixels[w*w*2+w]=color(255);
  while(true)
  {
    o=k+(int)random(-2,2);
    p=l+(int)random(-2,2);
    if(p*d+o>d*d-1 || p*d+o<0 || o<0 || o>d){
      k=l=(int)random(d);
    }
    else
    {
      if(pixels[p*d+o]==color(255))
      {
        p=l-w;
        o=k-w;
        if(o*o+p*p>h*h){break;}
        float s,c;
        for(int j=0;j<12;j++)
        {
          s=sin(PI*j/6);
          c=cos(PI*j/6);         
          x=(int)((o*c)-(p*s));
          y=(int)(((p*c)+(o*s)));
          pixels[(int)(d*y+x+w+(w*d))]=color(255);
        }
        k=l=(int)random(d);  
      }
      else
      {
        k=o;
        l=p;
      }
    }
  }
  updatePixels(); 

在此处输入图片说明 在此处输入图片说明

你可以在这里得到处理


3
这不太符合规范。如果您将点围绕中心反射而不是旋转,则将符合条件。
TheNumberOne 2014年

color(255)可以color(-1)节省一个字节
Kritixi Lithos'Apri
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.