1votos

Movimiento de particulas en JavaScript

por josejuan hace 5 años

Se puede lanzar directamente en la consola (probado FireFox 29). Se muestra el movimiento browniano en tiempo real en diferentes gráficas (si lo ejecutas, estará debajo del todo del documento). Permite definir si la bola es cerrada o abierta y si se incrementa sobre un único eje o pueden ser los dos.

Simular el movimiento de una particula dentro de una circunferencia

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// copiat y pegar en la consola y mirar al final del documento 
 
      function Brown(options) { 
        // config 
        options = options || {}; 
        options.radius = options.radius || 2.5;               // radio 
        if(!options.container)                              // contenedor del canvas 
          options.container = document.body; 
        options.openBall = options.openBall || false;       // bola abierta o cerrada 
        options.incOneAxis = options.incOneAxis || false;    // inc sólo un eje a la vez 
        options.sizePx = options.sizePx || 250;             // tamaño viewport 
         
        // init canvas 
        var canvas = document.createElement('canvas'); 
        canvas.width = canvas.height = options.sizePx; 
        options.container.appendChild(canvas); 
        var ctx = canvas.getContext('2d'); 
        ctx.translate(options.sizePx >> 1, options.sizePx >> 1); 
        var vwSize = 2.2 * options.radius; 
        var s = options.sizePx / vwSize; 
        ctx.scale(s, s); 
        var x, y, n; 
         
        var path = function (points, linewidth, color) { 
            ctx.beginPath(); 
            ctx.lineWidth = linewidth / s; 
            ctx.strokeStyle = color; 
            ctx.moveTo(points[0][0], points[0][1]); 
            points.forEach(function (p) { ctx.lineTo(p[0], p[1]) }); 
            ctx.stroke(); 
        }; 
        var paths = function (paths, linewidth, color) { 
            paths.forEach(function (p) { path(p, linewidth, color) }); 
        }; 
        var reset = function () { 
            ctx.clearRect(-vwSize * 0.5, -vwSize * 0.5, vwSize, vwSize); 
            paths([[[0, -vwSize], [0, vwSize]], [[-vwSize, 0], [vwSize, 0]]], 2.0, 'black'); 
                var p = []; 
                for(var row = -Math.ceil(vwSize); row < Math.ceil(vwSize); row++) { 
                  p.push([[row, -vwSize], [row, vwSize]]); 
                  p.push([[-vwSize, row], [vwSize, row]]); 
                paths(p, 1.0, 'lightgray'); 
            ctx.beginPath(); 
            ctx.lineWidth = 2.0 / s; 
            ctx.strokeStyle = 'red'; 
            ctx.arc(0, 0, options.radius, 0, 6.29); 
            ctx.stroke(); 
            ctx.lineWidth = 1.0 / s; 
            ctx.strokeStyle = 'green'; 
            n = x = y = 0; 
        }; 
         
        var next = function () { 
          var xx = x, yy = y, c = Math.random() < 0.5; 
          if(!options.incOneAxis ||  c) xx += Math.random() < 0.5 ? 1 : -1; 
          if(!options.incOneAxis || !c) yy += Math.random() < 0.5 ? 1 : -1; 
          path([[x  + Math.random() * 0.03, y  + Math.random() * 0.03], 
                [xx + Math.random() * 0.03, yy + Math.random() * 0.03]], 1.0, 'blue'); 
          x = xx; y = yy; n++; 
          var d = Math.sqrt(x * x + y * y); 
          if(d < options.radius) return false; 
          return options.openBall || (d > options.radius); 
        }; 
        var auto = function (interval, resultCallBack /* (n) */) { 
          if(next()) resultCallBack(n); 
          else       window.setTimeout(function () { auto(interval, resultCallBack) }, interval); 
        }; 
        var runner = function (interval1, interval2, statisticsCallBack /* (sumN, countN) */) { 
            var sumN = 0, countN = 0; 
            var runForEver = function () { 
              reset(); 
              auto(interval1, function (n) { 
                sumN += n; 
                statisticsCallBack(sumN, ++countN); 
                window.setTimeout(runForEver, interval2); 
              }); 
            }; 
            runForEver(); 
        }; 
        reset(); 
         
        return { 
            reset: reset, 
            next: next, 
            auto: auto, 
            runner: runner 
        }; 
       
      function Experiment(radius, timer1, timer2) { 
        var c = document.createElement('div'); 
        c.style = 'float: left; width: auto; display: inline; border: 1px solid lightblue; margin: 20px'; 
        document.body.appendChild(c); 
        var s = document.createElement('div'); 
        c.appendChild(s); 
        var b = new Brown({container: c, radius: radius}); 
        b.runner(timer1, timer2, function (N, C) { s.innerHTML = "Tests: " + C + "; Avg. jumps: " + Math.round(N / C) });         
 
      function load() { 
        Experiment(5  ,  20, 1000); 
        Experiment(  2, 200, 1000); 
        Experiment( 20,  10, 2000); 
        Experiment(100,  10, 2000); 
       
      load() 
2 comentarios
0votos

Escrito por carlosjm4 hace 5 años

hola josejuan, Gracias por responder al desafio, el recorrido de la particula se ve buenisimo en tiempo real.
Se que en go, se puede hacer, pero aun no aprendo a manejar los paquetes graficos.Si algun experto lee este mensaje y sabe como hacerlo agradeceria un ejemplo.
+1 a tu solucion

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.