10
\$\begingroup\$

I saw this question on https://mathematica.stackexchange.com/ and I think it's pretty cool. Let's make the snowflake with other programming languages.

This is a quote from the original question:

'Tis the season... And it's about time I posed my first question on Mathematica Stack Exchange. So, here's an holiday quest for you Graphics (and P-Chem?) gurus.

What is your best code for generating a (random) snowflake? By random I mean with different shapes that will mimic the diversity exhibited by real snowflakes. Here's a link to have an idea: http://www.its.caltech.edu/~atomic/snowcrystals/ , more specifically here are the different types of snowflakes: http://www.its.caltech.edu/~atomic/snowcrystals/class/class.htm . Here we are trying to generate a single snowflake (possibly with different parameters to tune its shape), the more realistic, the better. Three dimensional renderings, for adding translucency and colors are also welcome. Unleash your fantasy, go beyond the usual fractals!

Rules:

  • Generate a random single snowflake.
  • The flake should be six-fold radial symmetry.
  • It doesn't need to be realistic. (But prefer)
  • Single character answers, like *, ⚹, ❅, ❄, ❆ are not allowed.
  • Most upvotes wins!
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Better disallow single character outputs like '*⚹❅❄❆'[Math.floor(Math.random()*5)]. \$\endgroup\$
    – manatwork
    Commented Dec 30, 2013 at 16:06
  • 1
    \$\begingroup\$ @nitro2k01: you realize that he referenced that exact mathematica.SE site in the very first sentence of the posting, right? \$\endgroup\$
    – Kyle Kanos
    Commented Dec 30, 2013 at 19:09
  • \$\begingroup\$ Oops, sorry. I honestly skipped right to the rules. \$\endgroup\$
    – nitro2k01
    Commented Dec 30, 2013 at 19:28

3 Answers 3

15
\$\begingroup\$

Bash and ImageMagick

#!/bin/bash

third=()
x=90
y=90
while (( x>10 )); do
  (( dx=RANDOM%10 ))
  while :; do (( dy=RANDOM%21-10 )); (( y-dy<95 )) && (( y-dy>(x-dx)/2 )) && break; done
  third+=(
    -draw "line $x,$y $(( x-dx )),$(( y-dy ))"
    -draw "line $x,$(( 200-y )) $(( x-dx )),$(( 200-y+dy ))"
    -draw "line $(( 200-x )),$y $(( 200-x+dx )),$(( y-dy ))"
    -draw "line $(( 200-x )),$(( 200-y )) $(( 200-x+dx )),$(( 200-y+dy ))"
  )
  (( x-=dx ))
  (( y-=dy ))
done

third+=(
  -draw "line 90,90 90,110"
  -draw "line $x,$y 15,100"
  -draw "line $x,$(( 200-y )) 15,100"
  -draw "line 110,90 110,110"
  -draw "line $(( 200-x )),$y 185,100"
  -draw "line $(( 200-x )),$(( 200-y )) 185,100"
  -draw 'color 20,100 filltoborder'
  -draw 'color 180,100 filltoborder'
)

convert \
  -size '200x200' \
  xc:skyblue \
  -background skyblue \
  -stroke 'white' \
  -strokewidth 1 \
  -fill 'white' \
  -bordercolor 'white' \
  -fuzz 10% \
  "${third[@]}" \
  -rotate 120 \
  -crop '200x200' \
  "${third[@]}" \
  -rotate 120 \
  -crop '200x200' \
  "${third[@]}" \
  -draw 'ellipse 100,100 15,15 0,360' \
  x:

Sample run:

bash-4.1$ for i in {1..30}; do ./showflake.sh "showflake-$i.png"; done

bash-4.1$ montage showflake-*.png x:

snowflake montage

\$\endgroup\$
5
\$\begingroup\$

Javascript

Fiddle located here

More fancy Fiddle located here

It's not golfed, not by a long shot. Also required are the Perlin Noise function and seeded Random (both included in Fiddle, seeded random needed for Perlin). Fiddle also displays the current seed for keeping track of favorites ;)

function DoFlake(canvas){
    var width = canvas.width;
    var height = canvas.height;

    var ctx = canvas.getContext('2d');
    var thing = document.createElement('canvas'); thing.width = 128; thing.height = 32;
    var thingctx = thing.getContext('2d');
    var noise = new ImprovedPerlin((new Date()).getTime());

    var wDiv = 1/64;
    var y = 7/32;
    var z = 2/11;

    for(var x = 0; x < 128; x++){
        var h = 32 - (x * 32 / 128);
        h += 16 * noise.Noise(4 * x * wDiv, y, z);
        h += 8 * noise.Noise(8 * x * wDiv, y, z);
        h += 4 * noise.Noise(16 * x * wDiv, y, z);
        h += 2 * noise.Noise(32 * x * wDiv, y, z);
        h += 1 * noise.Noise(64 * x * wDiv, y, z);

        thingctx.fillRect(x, 0, 1, h);
    }

    ctx.translate(128,128);
    var angle = Math.PI / 3;
    for(var i = 0; i < 6; i++){
        ctx.rotate(angle);
        ctx.drawImage(thing, 0, 0);
        ctx.scale(1, -1)
        ctx.drawImage(thing, 0, 0);
        ctx.scale(1, -1);
    }
}
\$\endgroup\$
0
\$\begingroup\$

ZXSpectrum Basic, 21

Well, I Can't do the 6 fold symmetry, but I can get all sorts of randomness

using the ZX Spectrum: Emulator Here

Remember that keywords are a single character in the ZX Spectrum

OVER 1
PLOT 40,40
DRAW 40,40,RND*5000

To enter these commands on the emulator:

TAB ,1 ENTER
q 40,40 ENTER
w 40,40,TAB tCTRL+B5000ENTER

(Don't you just love the spectrum keyboard)

\$\endgroup\$
2
  • \$\begingroup\$ This does not work. It either outputs "B Integer out of range, 0:1" or renders some strange donut shape. \$\endgroup\$ Commented Aug 8, 2014 at 9:48
  • \$\begingroup\$ the bad thing about spectrum code is that plots sometimes exceed the minimal amount of screen space. alter the 3rd number in the draw to get different patterns and shapes \$\endgroup\$
    – SeanC
    Commented Aug 8, 2014 at 12:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.