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
    \$\begingroup\$ Better disallow single character outputs like '*⚹❅❄❆'[Math.floor(Math.random()*5)]. \$\endgroup\$ – manatwork Dec 30 '13 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 Dec 30 '13 at 19:09
  • \$\begingroup\$ Oops, sorry. I honestly skipped right to the rules. \$\endgroup\$ – nitro2k01 Dec 30 '13 at 19:28
14
\$\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

| improve this answer | |
\$\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);
    }
}
| improve this answer | |
\$\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)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This does not work. It either outputs "B Integer out of range, 0:1" or renders some strange donut shape. \$\endgroup\$ – Lars Ebert Aug 8 '14 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 Aug 8 '14 at 12:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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