Simulemos un copo de nieve al azar

10

Vi esta pregunta en https://mathematica.stackexchange.com/ y creo que es genial. Hagamos el copo de nieve con otros lenguajes de programación.

Esta es una cita de la pregunta original:

Es la temporada ... Y ya es hora de que haga mi primera pregunta en Mathematica Stack Exchange. Entonces, aquí hay una búsqueda de vacaciones para tus gurús de Gráficos (y P-Chem?)

¿Cuál es su mejor código para generar un copo de nieve (aleatorio)? Por azar quiero decir con diferentes formas que imitarán la diversidad exhibida por los copos de nieve reales. Aquí hay un enlace para tener una idea: http://www.its.caltech.edu/~atomic/snowcrystals/ , más específicamente aquí están los diferentes tipos de copos de nieve: http://www.its.caltech.edu/~atomic /snowcrystals/class/class.htm . Aquí estamos tratando de generar un solo copo de nieve (posiblemente con diferentes parámetros para ajustar su forma), cuanto más realista, mejor. Las representaciones tridimensionales, para agregar translucidez y colores, también son bienvenidas. ¡Desata tu fantasía, ve más allá de los fractales habituales!

Reglas:

  • Genera un solo copo de nieve al azar.
  • La escama debe tener una simetría radial de seis veces.
  • No necesita ser realista. (Pero prefiero)
  • Las respuestas de un solo carácter, como *, ⚹, ❅, ❄, ❆ no están permitidas.
  • ¡La mayoría de los votos positivos gana!
pt2121
fuente
3
Mejor no permitir salidas de un solo carácter como '*⚹❅❄❆'[Math.floor(Math.random()*5)].
manatwork
1
@ nitro2k01: te das cuenta de que hizo referencia al sitio exacto de Mathica.SE en la primera oración de la publicación, ¿verdad?
Kyle Kanos
Ups, lo siento. Honestamente salte directamente a las reglas.
nitro2k01

Respuestas:

14

Bash e 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:

Ejecución de muestra:

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

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

montaje de copo de nieve

hombre trabajando
fuente
5

Javascript

Violín ubicado aquí

Fiddle más elegante ubicado aquí

No es golf, ni por asomo. También se requiere la función de ruido Perlin y aleatorio sembrado (ambos incluidos en Fiddle, sembrado aleatorio necesario para Perlin). Fiddle también muestra la semilla actual para realizar un seguimiento de los favoritos;)

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);
    }
}
XNargaCazadora
fuente
0

ZXSpectrum Basic, 21

Bueno, no puedo hacer la simetría de 6 veces, pero puedo obtener todo tipo de aleatoriedad

usando el ZX Spectrum: Emulator Here

Recuerde que las palabras clave son un solo carácter en el ZX Spectrum

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

Para ingresar estos comandos en el emulador:

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

(No te encanta el teclado de espectro)

SeanC
fuente
Esto no funciona. Produce "B Integer fuera de rango, 0: 1" o genera una extraña forma de rosquilla.
Lars Ebert
Lo malo del código de espectro es que las tramas a veces exceden la cantidad mínima de espacio en la pantalla. alterar el tercer número en el sorteo para obtener diferentes patrones y formas
SeanC