Galton box animation: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: elided two separator lines for two one-line subroutines.) |
(Add Factor example) |
||
Line 1,063: | Line 1,063: | ||
Link to live demo: http://dc25.github.io/galtonBoxAnimationElm/ . Follow the link, enter a number and press the GO button. |
Link to live demo: http://dc25.github.io/galtonBoxAnimationElm/ . Follow the link, enter a number and press the GO button. |
||
=={{header|Factor}}== |
|||
{{works with|Factor|0.99 development release 2019-03-17}} |
|||
<lang factor>USING: accessors arrays calendar colors combinators |
|||
combinators.short-circuit fonts fry generalizations kernel |
|||
literals locals math math.ranges math.vectors namespaces opengl |
|||
random sequences timers ui ui.commands ui.gadgets |
|||
ui.gadgets.worlds ui.gestures ui.pens.solid ui.render ui.text ; |
|||
IN: rosetta-code.galton-box-animation |
|||
CONSTANT: pegs $[ 20 300 40 <range> ] |
|||
CONSTANT: speed 90 |
|||
CONSTANT: balls 140 |
|||
CONSTANT: peg-color T{ rgba f 0.60 0.4 0.60 1.0 } |
|||
CONSTANT: ball-color T{ rgba f 0.80 1.0 0.20 1.0 } |
|||
CONSTANT: slot-color T{ rgba f 0.00 0.2 0.40 1.0 } |
|||
CONSTANT: bg-color T{ rgba f 0.02 0.0 0.02 1.0 } |
|||
CONSTANT: font $[ |
|||
monospace-font |
|||
t >>bold? |
|||
T{ rgba f 0.80 1.0 0.20 1.0 } >>foreground |
|||
T{ rgba f 0.02 0.0 0.02 1.0 } >>background |
|||
] |
|||
TUPLE: galton < gadget balls { frame initial: 1 } ; |
|||
DEFER: on-tick |
|||
: <galton-gadget> ( -- gadget ) |
|||
galton new bg-color <solid> >>interior V{ } clone >>balls |
|||
dup [ on-tick ] curry f speed milliseconds <timer> |
|||
start-timer ; |
|||
: add-ball ( gadget -- ) |
|||
dup frame>> balls < |
|||
[ { 250 -20 } swap balls>> [ push ] keep ] when drop ; |
|||
: draw-msg ( -- ) |
|||
{ 10 10 } |
|||
[ font "Press <space> for new animation" draw-text ] |
|||
with-translation ; |
|||
: draw-slots ( -- ) |
|||
slot-color gl-color { 70 350 } { 70 871 } |
|||
10 [ 2dup gl-line [ { 40 0 } v+ ] bi@ ] times 2drop |
|||
{ 70 871 } { 430 871 } gl-line ; |
|||
: diamond-side ( loc1 loc2 loc3 -- ) |
|||
[ v+ dup ] [ v+ gl-line ] bi* ; |
|||
: draw-diamond ( loc color -- ) |
|||
gl-color { |
|||
[ { 0 -10 } { 10 10 } ] |
|||
[ { 10 0 } { -10 10 } ] |
|||
[ { 0 10 } { -10 -10 } ] |
|||
[ { -10 0 } { 10 -10 } ] |
|||
} [ diamond-side ] map-compose cleave ; |
|||
: draw-peg-row ( loc n -- ) |
|||
<iota> [ 40 * 0 2array v+ peg-color draw-diamond ] with |
|||
each ; |
|||
: draw-peg-triangle ( -- ) |
|||
{ 250 40 } 1 |
|||
8 [ 2dup draw-peg-row [ { -20 40 } v+ ] dip 1 + ] times |
|||
2drop ; |
|||
: draw-balls ( gadget -- ) |
|||
balls>> [ ball-color draw-diamond ] each ; |
|||
: rand-side ( loc -- loc' ) { { 20 20 } { -20 20 } } random v+ ; |
|||
:: collide? ( GADGET BALL -- ? ) |
|||
BALL second :> y |
|||
BALL { 0 20 } v+ :> tentative |
|||
{ [ y 860 = ] [ tentative GADGET balls>> member? ] } 0|| ; |
|||
:: update-ball ( GADGET BALL -- BALL' ) |
|||
{ |
|||
{ [ BALL second pegs member? ] [ BALL rand-side ] } |
|||
{ [ GADGET BALL collide? ] [ BALL ] } |
|||
[ BALL { 0 20 } v+ ] |
|||
} cond ; |
|||
: update-balls ( gadget -- ) |
|||
dup '[ [ _ swap update-ball ] map ] change-balls drop ; |
|||
: on-tick ( gadget -- ) |
|||
{ |
|||
[ dup frame>> odd? [ add-ball ] [ drop ] if ] |
|||
[ relayout-1 ] [ update-balls ] |
|||
[ [ 1 + ] change-frame drop ] |
|||
} cleave ; |
|||
M: galton pref-dim* drop { 500 900 } ; |
|||
M: galton draw-gadget* |
|||
draw-peg-triangle draw-msg draw-slots draw-balls ; |
|||
: com-new ( gadget -- ) V{ } clone >>balls 1 >>frame drop ; |
|||
galton "gestures" f { |
|||
{ T{ key-down { sym " " } } com-new } |
|||
} define-command-map |
|||
MAIN-WINDOW: galton-box-animation |
|||
{ |
|||
{ title "Galton Box Animation" } |
|||
{ window-controls |
|||
{ normal-title-bar close-button minimize-button } } |
|||
} <galton-gadget> >>gadgets ;</lang> |
|||
{{out}} |
|||
Image taken from the program mid-animation: [https://i.imgur.com/E2ge7LE.png] |
|||
=={{header|Go}}== |
=={{header|Go}}== |