[{"data":1,"prerenderedAt":4199},["Reactive",2],{"content-query-MqgBDbRubH":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"published":10,"slug":11,"body":12,"_type":4193,"_id":4194,"_source":4195,"_file":4196,"_stem":4197,"_extension":4198},"/articles/optimizing-the-particle-life-javascript-quadtree","articles",false,"","Optimizing the Particle Life: Spatial Partitioning with QuadTree (Part 2)","Let's implement JavaScript Particle Life and optimize it using QuadTree.","2024/03/06","optimizing-the-particle-life-javascript-quadtree",{"type":13,"children":14,"toc":4186},"root",[15,24,30,50,66,79,3956,3962,3967,3980,3985,3990,3995,3999,4004,4009,4052,4057,4080,4100,4106,4111,4123,4129,4134,4139,4145,4166,4171,4180],{"type":16,"tag":17,"props":18,"children":20},"element","h2",{"id":19},"typescript-particle-life",[21],{"type":22,"value":23},"text","TypeScript Particle Life",{"type":16,"tag":25,"props":26,"children":27},"p",{},[28],{"type":22,"value":29},"Now that the decision is made, let’s get to work. I’ll start with writing a basic JavaScript (or, to be precise, TypeScript that will later compile to JS) implementation based on the Python code I created in the previous part. To improve the code, I’ll need to add the following:",{"type":16,"tag":31,"props":32,"children":33},"ol",{},[34,40,45],{"type":16,"tag":35,"props":36,"children":37},"li",{},[38],{"type":22,"value":39},"Space wrapping around the edges.",{"type":16,"tag":35,"props":41,"children":42},{},[43],{"type":22,"value":44},"Space partitioning for optimization purposes.",{"type":16,"tag":35,"props":46,"children":47},{},[48],{"type":22,"value":49},"Allowing the user to adjust the parameters.",{"type":16,"tag":25,"props":51,"children":52},{},[53,55,64],{"type":22,"value":54},"The code below is part of a Vue component. VueJS is great when you need a lightweight, simple, and robust tool for rapid development. While the whole application structure is out of the scope of this article, please have a look at ",{"type":16,"tag":56,"props":57,"children":61},"a",{"href":58,"rel":59},"https://github.com/Caranea/gpulife",[60],"nofollow",[62],{"type":22,"value":63},"this GitHub repo",{"type":22,"value":65}," to see how I organized my project.",{"type":16,"tag":25,"props":67,"children":68},{},[69,71,77],{"type":22,"value":70},"I will only explain in detail the parts not covered in the ",{"type":16,"tag":56,"props":72,"children":74},{"href":73},"/articles/optimizing-the-article-life-from-a-thousand-to-a-milion-particles",[75],{"type":22,"value":76},"previous article",{"type":22,"value":78},", so make sure you read it first. A very important disclaimer: comments regarding optimization (e.g. typed vs regular arrays) only refer to code running in Chrome browser. Performance will vary from environment to environment, and it would have to be taken into consideration in real-life products.",{"type":16,"tag":80,"props":81,"children":85},"pre",{"className":82,"code":83,"language":84,"meta":7,"style":7},"language-js shiki shiki-themes github-dark","  const canvas = document.getElementById(\"pl\") as HTMLCanvasElement; //Grab a reference to Canvas element and cast its type as HTMLCanvasElement to have access to all its properties and methods\n  const context = (canvas).getContext(\"2d\"); //Create 2D rendering context for our canvas\n  //Make our canvas full-screen\n  canvas!.width = document.documentElement.clientWidth\n  canvas!.height = document.documentElement.clientHeight\n  //Since our x,y coordinates have values between (0,1), we need screenRatio when drawing particles, so that we don't render stretched/distorted animation.\n  const screenRatio = canvas!.width / canvas!.height\n  //Let's store our systems parameters in localStorage, so that they persist between user's session. If no 'parameters' object is in localStorage, fallback to default config. \n  const parameters = window.localStorage.getItem('parameters') ? JSON.parse(window.localStorage.getItem('parameters')!) : defaultConfig\n  const m = parameters.colorsNumber;\n  const n = parameters.particlesCountJS;\n  const radius = parameters.interactionRadiusJS;\n  const fr = Math.pow(0.5, 20);\n\n  const matrix = createRandomMatrix(m);\n\n  //using typed arrays would give us no performance advantage\n  let colors: number[] = [];\n  let positionsX: number[] = [];\n  let positionsY: number[] = [];\n  let velocitiesX: any[] = [];\n  let velocitiesY: any[] = [];\n\n  for (let i = 0; i \u003C n; i++) {\n    colors[i] = Math.floor(Math.random() * m);\n    positionsX[i] = Math.random();\n    positionsY[i] = Math.random();\n    velocitiesX[i] = 0;\n    velocitiesY[i] = 0;\n  }\n\n  renderFrame();\n\n  function renderFrame() {\n    //Clear previous positions on every frame\n    context!.fillStyle = \"black\";\n    context!.fillRect(0, 0, canvas!.clientWidth, canvas!.clientHeight);\n\n    for (let i = 0; i \u003C n; i++) {\n      //beginPath() method is called before drawing every particle, so that they may be filled with different colors.\n      context!.beginPath();\n      let x = positionsX[i] * canvas!.clientWidth;\n      let y = positionsY[i] * canvas!.clientHeight\n      //Adjusting position for two cases:\n      //a) mobile screens -> x\u003Cy\n      //b) desktops -> x>y\n      x = screenRatio \u003C 1 ? x * (1 / screenRatio) : x;\n      y = screenRatio > 1 ? y * screenRatio : y;\n      if (!(x \u003C 1) && !(y \u003C 1) && !(x > canvas!.clientWidth - 1) && !(y > canvas!.clientHeight - 1)) { //avoid blinking at edges due to how space wrapping is done\n        //Drawing the actual particle\n        context!.arc(x, y, 1, 0, 2 * Math.PI); //js compilers are smart enough for me not to have to move math.pi to var\n        context!.fillStyle = `hsl(${360 * (colors[i] / m)},100%,50%)`;\n        context!.fill();\n      }\n    }\n\n    updateParticles();\n    // Native window method to request animation frame. Note: The frequency of calls aims to match the display refresh rate.\n    // This method passes DOMHighResTimeStamp as an argument to callback, so that we can calculate how much our animation should progress in one frame\n    // Otherwise there will be different speed for animation on screens with different refresh rates\n    requestAnimationFrame(renderFrame);\n  }\n\n  function updateParticles() {\n    for (let i = 0; i \u003C n; i++) {\n      let totalForceX = 0;\n      let totalForceY = 0;\n      for (let j = 0; j \u003C n; j++) {\n        if (i === j) continue;\n        let x = positionsX[j] - positionsX[i];\n        let y = positionsY[j] - positionsY[i];\n        let d = Math.sqrt(x * x + y * y); // No performance advantage in removing math.sqrt. 10x faster than math.hypot.\n        if (d \u003C radius) {\n          let f = force(\n            d / radius,\n            matrix[colors[i]][colors[j]])\n          totalForceX += (x / d) * f;\n          totalForceY += (y / d) * f;\n        }\n        velocitiesX[i] += totalForceX;\n        velocitiesY[i] += totalForceY;\n\n        velocitiesX[i] *= fr;\n        velocitiesY[i] *= fr;\n\n        positionsX[i] += velocitiesX[i];\n        positionsY[i] += velocitiesY[i];\n\n        x = positionsX[i];\n        y = positionsY[i];\n\n        // Prevent particles from running away from the viewport. \n        // If x or y is > 1, substract 1 from it, so that it moves to other part of the screen\n        // This only handles particle position - it's not interacting with \n        // particles from the other side of the screen. In other words, particle at position (0,0) with radius of 0.1\n        // will not interact with particle at position (1.0,1.0). This gives us interesting visual effect (see for GPU.js examples screenshots)\n        // but also causes some issues, like particles aggregating at the edges\n\n        x = x > 1 ? x - 1 : x;\n        y = y > 1 ? y - 1 : y;\n        x = x \u003C 0 ? x + 1 : x;\n        y = y \u003C 0 ? y + 1 : y;\n\n        positionsX[i] = x;\n        positionsY[i] = y;\n      }\n    }\n  }\n\n  //Instead of using one force function allow user to choose from several options. \n  //Graphs of every function (assuming the force value between two particles to be 1.0 and a repulsive radius of 1/4 of the max radius)\n  //available on live site of the project\n\n  function force(d: number, f: number): number {\n    let repRadius = parameters.repulsiveRadius;\n    switch (parameters.forceFunction) {\n      case '1':\n        return forceVariantI(d, f, repRadius);\n      case '2':\n        return forceVariantII(d, f, repRadius);\n      case '3':\n        return forceVariantIII(d, f, repRadius);\n      default:\n        return defaultForce(d, f, repRadius)\n    }\n  }\n\n  function forceVariantI(d: number, f: number, repRadius: number): number {\n    if (d \u003C= repRadius) {\n          return d / repRadius - 1\n        } else {\n          return f * (1 - Math.abs(2 * d - 1 - repRadius) / 1 - repRadius);\n        }\n  }\n\n  function forceVariantII(d: number, f: number, repRadius: number): number {\n    if (d \u003C= repRadius) {\n          return (d / repRadius - 1) + (f * (1 - d))\n        } else {\n          return f * (1 - d)\n        }\n  }\n\n  function forceVariantIII(d: number, f: number, repRadius: number): number {\n   return defaultForce(d,f,repRadius)\n  }\n\n  function defaultForce(d: number, f: number, repRadius: number): number {\n    if (d \u003C= repRadius) {\n      return d / repRadius - 1\n    } else {\n      return f * (1 - d)\n    }\n  }\n","js",[86],{"type":16,"tag":87,"props":88,"children":89},"code",{"__ignoreMap":7},[90,162,208,217,246,272,281,328,337,437,459,481,503,554,564,591,599,608,645,678,711,745,778,786,844,891,917,942,964,985,994,1002,1015,1023,1042,1051,1082,1143,1151,1200,1209,1235,1275,1314,1323,1332,1341,1409,1460,1610,1619,1690,1769,1794,1803,1812,1820,1833,1842,1851,1860,1874,1882,1890,1907,1955,1980,2005,2057,2090,2121,2151,2212,2234,2262,2280,2289,2326,2360,2369,2387,2405,2413,2431,2447,2455,2473,2491,2499,2516,2533,2541,2550,2559,2568,2577,2586,2595,2603,2652,2700,2748,2796,2804,2820,2836,2844,2852,2860,2868,2877,2886,2895,2903,2967,2990,3004,3023,3042,3059,3076,3093,3110,3123,3141,3149,3157,3165,3242,3265,3295,3313,3401,3409,3417,3425,3501,3521,3583,3599,3632,3640,3648,3656,3732,3750,3758,3766,3842,3862,3891,3908,3940,3948],{"type":16,"tag":91,"props":92,"children":95},"span",{"class":93,"line":94},"line",1,[96,102,108,113,119,125,130,136,141,146,151,156],{"type":16,"tag":91,"props":97,"children":99},{"style":98},"--shiki-default:#F97583",[100],{"type":22,"value":101},"  const",{"type":16,"tag":91,"props":103,"children":105},{"style":104},"--shiki-default:#79B8FF",[106],{"type":22,"value":107}," canvas",{"type":16,"tag":91,"props":109,"children":110},{"style":98},[111],{"type":22,"value":112}," =",{"type":16,"tag":91,"props":114,"children":116},{"style":115},"--shiki-default:#E1E4E8",[117],{"type":22,"value":118}," document.",{"type":16,"tag":91,"props":120,"children":122},{"style":121},"--shiki-default:#B392F0",[123],{"type":22,"value":124},"getElementById",{"type":16,"tag":91,"props":126,"children":127},{"style":115},[128],{"type":22,"value":129},"(",{"type":16,"tag":91,"props":131,"children":133},{"style":132},"--shiki-default:#9ECBFF",[134],{"type":22,"value":135},"\"pl\"",{"type":16,"tag":91,"props":137,"children":138},{"style":115},[139],{"type":22,"value":140},") ",{"type":16,"tag":91,"props":142,"children":143},{"style":98},[144],{"type":22,"value":145},"as",{"type":16,"tag":91,"props":147,"children":148},{"style":121},[149],{"type":22,"value":150}," HTMLCanvasElement",{"type":16,"tag":91,"props":152,"children":153},{"style":115},[154],{"type":22,"value":155},"; ",{"type":16,"tag":91,"props":157,"children":159},{"style":158},"--shiki-default:#6A737D",[160],{"type":22,"value":161},"//Grab a reference to Canvas element and cast its type as HTMLCanvasElement to have access to all its properties and methods\n",{"type":16,"tag":91,"props":163,"children":165},{"class":93,"line":164},2,[166,170,175,179,184,189,193,198,203],{"type":16,"tag":91,"props":167,"children":168},{"style":98},[169],{"type":22,"value":101},{"type":16,"tag":91,"props":171,"children":172},{"style":104},[173],{"type":22,"value":174}," context",{"type":16,"tag":91,"props":176,"children":177},{"style":98},[178],{"type":22,"value":112},{"type":16,"tag":91,"props":180,"children":181},{"style":115},[182],{"type":22,"value":183}," (canvas).",{"type":16,"tag":91,"props":185,"children":186},{"style":121},[187],{"type":22,"value":188},"getContext",{"type":16,"tag":91,"props":190,"children":191},{"style":115},[192],{"type":22,"value":129},{"type":16,"tag":91,"props":194,"children":195},{"style":132},[196],{"type":22,"value":197},"\"2d\"",{"type":16,"tag":91,"props":199,"children":200},{"style":115},[201],{"type":22,"value":202},"); ",{"type":16,"tag":91,"props":204,"children":205},{"style":158},[206],{"type":22,"value":207},"//Create 2D rendering context for our canvas\n",{"type":16,"tag":91,"props":209,"children":211},{"class":93,"line":210},3,[212],{"type":16,"tag":91,"props":213,"children":214},{"style":158},[215],{"type":22,"value":216},"  //Make our canvas full-screen\n",{"type":16,"tag":91,"props":218,"children":220},{"class":93,"line":219},4,[221,226,231,236,241],{"type":16,"tag":91,"props":222,"children":223},{"style":115},[224],{"type":22,"value":225},"  canvas",{"type":16,"tag":91,"props":227,"children":228},{"style":98},[229],{"type":22,"value":230},"!",{"type":16,"tag":91,"props":232,"children":233},{"style":115},[234],{"type":22,"value":235},".width ",{"type":16,"tag":91,"props":237,"children":238},{"style":98},[239],{"type":22,"value":240},"=",{"type":16,"tag":91,"props":242,"children":243},{"style":115},[244],{"type":22,"value":245}," document.documentElement.clientWidth\n",{"type":16,"tag":91,"props":247,"children":249},{"class":93,"line":248},5,[250,254,258,263,267],{"type":16,"tag":91,"props":251,"children":252},{"style":115},[253],{"type":22,"value":225},{"type":16,"tag":91,"props":255,"children":256},{"style":98},[257],{"type":22,"value":230},{"type":16,"tag":91,"props":259,"children":260},{"style":115},[261],{"type":22,"value":262},".height ",{"type":16,"tag":91,"props":264,"children":265},{"style":98},[266],{"type":22,"value":240},{"type":16,"tag":91,"props":268,"children":269},{"style":115},[270],{"type":22,"value":271}," document.documentElement.clientHeight\n",{"type":16,"tag":91,"props":273,"children":275},{"class":93,"line":274},6,[276],{"type":16,"tag":91,"props":277,"children":278},{"style":158},[279],{"type":22,"value":280},"  //Since our x,y coordinates have values between (0,1), we need screenRatio when drawing particles, so that we don't render stretched/distorted animation.\n",{"type":16,"tag":91,"props":282,"children":284},{"class":93,"line":283},7,[285,289,294,298,302,306,310,315,319,323],{"type":16,"tag":91,"props":286,"children":287},{"style":98},[288],{"type":22,"value":101},{"type":16,"tag":91,"props":290,"children":291},{"style":104},[292],{"type":22,"value":293}," screenRatio",{"type":16,"tag":91,"props":295,"children":296},{"style":98},[297],{"type":22,"value":112},{"type":16,"tag":91,"props":299,"children":300},{"style":115},[301],{"type":22,"value":107},{"type":16,"tag":91,"props":303,"children":304},{"style":98},[305],{"type":22,"value":230},{"type":16,"tag":91,"props":307,"children":308},{"style":115},[309],{"type":22,"value":235},{"type":16,"tag":91,"props":311,"children":312},{"style":98},[313],{"type":22,"value":314},"/",{"type":16,"tag":91,"props":316,"children":317},{"style":115},[318],{"type":22,"value":107},{"type":16,"tag":91,"props":320,"children":321},{"style":98},[322],{"type":22,"value":230},{"type":16,"tag":91,"props":324,"children":325},{"style":115},[326],{"type":22,"value":327},".height\n",{"type":16,"tag":91,"props":329,"children":331},{"class":93,"line":330},8,[332],{"type":16,"tag":91,"props":333,"children":334},{"style":158},[335],{"type":22,"value":336},"  //Let's store our systems parameters in localStorage, so that they persist between user's session. If no 'parameters' object is in localStorage, fallback to default config. \n",{"type":16,"tag":91,"props":338,"children":340},{"class":93,"line":339},9,[341,345,350,354,359,364,368,373,377,382,387,392,397,402,406,410,414,419,423,427,432],{"type":16,"tag":91,"props":342,"children":343},{"style":98},[344],{"type":22,"value":101},{"type":16,"tag":91,"props":346,"children":347},{"style":104},[348],{"type":22,"value":349}," parameters",{"type":16,"tag":91,"props":351,"children":352},{"style":98},[353],{"type":22,"value":112},{"type":16,"tag":91,"props":355,"children":356},{"style":115},[357],{"type":22,"value":358}," window.localStorage.",{"type":16,"tag":91,"props":360,"children":361},{"style":121},[362],{"type":22,"value":363},"getItem",{"type":16,"tag":91,"props":365,"children":366},{"style":115},[367],{"type":22,"value":129},{"type":16,"tag":91,"props":369,"children":370},{"style":132},[371],{"type":22,"value":372},"'parameters'",{"type":16,"tag":91,"props":374,"children":375},{"style":115},[376],{"type":22,"value":140},{"type":16,"tag":91,"props":378,"children":379},{"style":98},[380],{"type":22,"value":381},"?",{"type":16,"tag":91,"props":383,"children":384},{"style":104},[385],{"type":22,"value":386}," JSON",{"type":16,"tag":91,"props":388,"children":389},{"style":115},[390],{"type":22,"value":391},".",{"type":16,"tag":91,"props":393,"children":394},{"style":121},[395],{"type":22,"value":396},"parse",{"type":16,"tag":91,"props":398,"children":399},{"style":115},[400],{"type":22,"value":401},"(window.localStorage.",{"type":16,"tag":91,"props":403,"children":404},{"style":121},[405],{"type":22,"value":363},{"type":16,"tag":91,"props":407,"children":408},{"style":115},[409],{"type":22,"value":129},{"type":16,"tag":91,"props":411,"children":412},{"style":132},[413],{"type":22,"value":372},{"type":16,"tag":91,"props":415,"children":416},{"style":115},[417],{"type":22,"value":418},")",{"type":16,"tag":91,"props":420,"children":421},{"style":98},[422],{"type":22,"value":230},{"type":16,"tag":91,"props":424,"children":425},{"style":115},[426],{"type":22,"value":140},{"type":16,"tag":91,"props":428,"children":429},{"style":98},[430],{"type":22,"value":431},":",{"type":16,"tag":91,"props":433,"children":434},{"style":115},[435],{"type":22,"value":436}," defaultConfig\n",{"type":16,"tag":91,"props":438,"children":440},{"class":93,"line":439},10,[441,445,450,454],{"type":16,"tag":91,"props":442,"children":443},{"style":98},[444],{"type":22,"value":101},{"type":16,"tag":91,"props":446,"children":447},{"style":104},[448],{"type":22,"value":449}," m",{"type":16,"tag":91,"props":451,"children":452},{"style":98},[453],{"type":22,"value":112},{"type":16,"tag":91,"props":455,"children":456},{"style":115},[457],{"type":22,"value":458}," parameters.colorsNumber;\n",{"type":16,"tag":91,"props":460,"children":462},{"class":93,"line":461},11,[463,467,472,476],{"type":16,"tag":91,"props":464,"children":465},{"style":98},[466],{"type":22,"value":101},{"type":16,"tag":91,"props":468,"children":469},{"style":104},[470],{"type":22,"value":471}," n",{"type":16,"tag":91,"props":473,"children":474},{"style":98},[475],{"type":22,"value":112},{"type":16,"tag":91,"props":477,"children":478},{"style":115},[479],{"type":22,"value":480}," parameters.particlesCountJS;\n",{"type":16,"tag":91,"props":482,"children":484},{"class":93,"line":483},12,[485,489,494,498],{"type":16,"tag":91,"props":486,"children":487},{"style":98},[488],{"type":22,"value":101},{"type":16,"tag":91,"props":490,"children":491},{"style":104},[492],{"type":22,"value":493}," radius",{"type":16,"tag":91,"props":495,"children":496},{"style":98},[497],{"type":22,"value":112},{"type":16,"tag":91,"props":499,"children":500},{"style":115},[501],{"type":22,"value":502}," parameters.interactionRadiusJS;\n",{"type":16,"tag":91,"props":504,"children":506},{"class":93,"line":505},13,[507,511,516,520,525,530,534,539,544,549],{"type":16,"tag":91,"props":508,"children":509},{"style":98},[510],{"type":22,"value":101},{"type":16,"tag":91,"props":512,"children":513},{"style":104},[514],{"type":22,"value":515}," fr",{"type":16,"tag":91,"props":517,"children":518},{"style":98},[519],{"type":22,"value":112},{"type":16,"tag":91,"props":521,"children":522},{"style":115},[523],{"type":22,"value":524}," Math.",{"type":16,"tag":91,"props":526,"children":527},{"style":121},[528],{"type":22,"value":529},"pow",{"type":16,"tag":91,"props":531,"children":532},{"style":115},[533],{"type":22,"value":129},{"type":16,"tag":91,"props":535,"children":536},{"style":104},[537],{"type":22,"value":538},"0.5",{"type":16,"tag":91,"props":540,"children":541},{"style":115},[542],{"type":22,"value":543},", ",{"type":16,"tag":91,"props":545,"children":546},{"style":104},[547],{"type":22,"value":548},"20",{"type":16,"tag":91,"props":550,"children":551},{"style":115},[552],{"type":22,"value":553},");\n",{"type":16,"tag":91,"props":555,"children":557},{"class":93,"line":556},14,[558],{"type":16,"tag":91,"props":559,"children":561},{"emptyLinePlaceholder":560},true,[562],{"type":22,"value":563},"\n",{"type":16,"tag":91,"props":565,"children":567},{"class":93,"line":566},15,[568,572,577,581,586],{"type":16,"tag":91,"props":569,"children":570},{"style":98},[571],{"type":22,"value":101},{"type":16,"tag":91,"props":573,"children":574},{"style":104},[575],{"type":22,"value":576}," matrix",{"type":16,"tag":91,"props":578,"children":579},{"style":98},[580],{"type":22,"value":112},{"type":16,"tag":91,"props":582,"children":583},{"style":121},[584],{"type":22,"value":585}," createRandomMatrix",{"type":16,"tag":91,"props":587,"children":588},{"style":115},[589],{"type":22,"value":590},"(m);\n",{"type":16,"tag":91,"props":592,"children":594},{"class":93,"line":593},16,[595],{"type":16,"tag":91,"props":596,"children":597},{"emptyLinePlaceholder":560},[598],{"type":22,"value":563},{"type":16,"tag":91,"props":600,"children":602},{"class":93,"line":601},17,[603],{"type":16,"tag":91,"props":604,"children":605},{"style":158},[606],{"type":22,"value":607},"  //using typed arrays would give us no performance advantage\n",{"type":16,"tag":91,"props":609,"children":611},{"class":93,"line":610},18,[612,617,622,626,631,636,640],{"type":16,"tag":91,"props":613,"children":614},{"style":98},[615],{"type":22,"value":616},"  let",{"type":16,"tag":91,"props":618,"children":619},{"style":115},[620],{"type":22,"value":621}," colors",{"type":16,"tag":91,"props":623,"children":624},{"style":98},[625],{"type":22,"value":431},{"type":16,"tag":91,"props":627,"children":628},{"style":104},[629],{"type":22,"value":630}," number",{"type":16,"tag":91,"props":632,"children":633},{"style":115},[634],{"type":22,"value":635},"[] ",{"type":16,"tag":91,"props":637,"children":638},{"style":98},[639],{"type":22,"value":240},{"type":16,"tag":91,"props":641,"children":642},{"style":115},[643],{"type":22,"value":644}," [];\n",{"type":16,"tag":91,"props":646,"children":648},{"class":93,"line":647},19,[649,653,658,662,666,670,674],{"type":16,"tag":91,"props":650,"children":651},{"style":98},[652],{"type":22,"value":616},{"type":16,"tag":91,"props":654,"children":655},{"style":115},[656],{"type":22,"value":657}," positionsX",{"type":16,"tag":91,"props":659,"children":660},{"style":98},[661],{"type":22,"value":431},{"type":16,"tag":91,"props":663,"children":664},{"style":104},[665],{"type":22,"value":630},{"type":16,"tag":91,"props":667,"children":668},{"style":115},[669],{"type":22,"value":635},{"type":16,"tag":91,"props":671,"children":672},{"style":98},[673],{"type":22,"value":240},{"type":16,"tag":91,"props":675,"children":676},{"style":115},[677],{"type":22,"value":644},{"type":16,"tag":91,"props":679,"children":681},{"class":93,"line":680},20,[682,686,691,695,699,703,707],{"type":16,"tag":91,"props":683,"children":684},{"style":98},[685],{"type":22,"value":616},{"type":16,"tag":91,"props":687,"children":688},{"style":115},[689],{"type":22,"value":690}," positionsY",{"type":16,"tag":91,"props":692,"children":693},{"style":98},[694],{"type":22,"value":431},{"type":16,"tag":91,"props":696,"children":697},{"style":104},[698],{"type":22,"value":630},{"type":16,"tag":91,"props":700,"children":701},{"style":115},[702],{"type":22,"value":635},{"type":16,"tag":91,"props":704,"children":705},{"style":98},[706],{"type":22,"value":240},{"type":16,"tag":91,"props":708,"children":709},{"style":115},[710],{"type":22,"value":644},{"type":16,"tag":91,"props":712,"children":714},{"class":93,"line":713},21,[715,719,724,728,733,737,741],{"type":16,"tag":91,"props":716,"children":717},{"style":98},[718],{"type":22,"value":616},{"type":16,"tag":91,"props":720,"children":721},{"style":115},[722],{"type":22,"value":723}," velocitiesX",{"type":16,"tag":91,"props":725,"children":726},{"style":98},[727],{"type":22,"value":431},{"type":16,"tag":91,"props":729,"children":730},{"style":104},[731],{"type":22,"value":732}," any",{"type":16,"tag":91,"props":734,"children":735},{"style":115},[736],{"type":22,"value":635},{"type":16,"tag":91,"props":738,"children":739},{"style":98},[740],{"type":22,"value":240},{"type":16,"tag":91,"props":742,"children":743},{"style":115},[744],{"type":22,"value":644},{"type":16,"tag":91,"props":746,"children":748},{"class":93,"line":747},22,[749,753,758,762,766,770,774],{"type":16,"tag":91,"props":750,"children":751},{"style":98},[752],{"type":22,"value":616},{"type":16,"tag":91,"props":754,"children":755},{"style":115},[756],{"type":22,"value":757}," velocitiesY",{"type":16,"tag":91,"props":759,"children":760},{"style":98},[761],{"type":22,"value":431},{"type":16,"tag":91,"props":763,"children":764},{"style":104},[765],{"type":22,"value":732},{"type":16,"tag":91,"props":767,"children":768},{"style":115},[769],{"type":22,"value":635},{"type":16,"tag":91,"props":771,"children":772},{"style":98},[773],{"type":22,"value":240},{"type":16,"tag":91,"props":775,"children":776},{"style":115},[777],{"type":22,"value":644},{"type":16,"tag":91,"props":779,"children":781},{"class":93,"line":780},23,[782],{"type":16,"tag":91,"props":783,"children":784},{"emptyLinePlaceholder":560},[785],{"type":22,"value":563},{"type":16,"tag":91,"props":787,"children":789},{"class":93,"line":788},24,[790,795,800,805,810,814,819,824,829,834,839],{"type":16,"tag":91,"props":791,"children":792},{"style":98},[793],{"type":22,"value":794},"  for",{"type":16,"tag":91,"props":796,"children":797},{"style":115},[798],{"type":22,"value":799}," (",{"type":16,"tag":91,"props":801,"children":802},{"style":98},[803],{"type":22,"value":804},"let",{"type":16,"tag":91,"props":806,"children":807},{"style":115},[808],{"type":22,"value":809}," i ",{"type":16,"tag":91,"props":811,"children":812},{"style":98},[813],{"type":22,"value":240},{"type":16,"tag":91,"props":815,"children":816},{"style":104},[817],{"type":22,"value":818}," 0",{"type":16,"tag":91,"props":820,"children":821},{"style":115},[822],{"type":22,"value":823},"; i ",{"type":16,"tag":91,"props":825,"children":826},{"style":98},[827],{"type":22,"value":828},"\u003C",{"type":16,"tag":91,"props":830,"children":831},{"style":115},[832],{"type":22,"value":833}," n; i",{"type":16,"tag":91,"props":835,"children":836},{"style":98},[837],{"type":22,"value":838},"++",{"type":16,"tag":91,"props":840,"children":841},{"style":115},[842],{"type":22,"value":843},") {\n",{"type":16,"tag":91,"props":845,"children":847},{"class":93,"line":846},25,[848,853,857,861,866,871,876,881,886],{"type":16,"tag":91,"props":849,"children":850},{"style":115},[851],{"type":22,"value":852},"    colors[i] ",{"type":16,"tag":91,"props":854,"children":855},{"style":98},[856],{"type":22,"value":240},{"type":16,"tag":91,"props":858,"children":859},{"style":115},[860],{"type":22,"value":524},{"type":16,"tag":91,"props":862,"children":863},{"style":121},[864],{"type":22,"value":865},"floor",{"type":16,"tag":91,"props":867,"children":868},{"style":115},[869],{"type":22,"value":870},"(Math.",{"type":16,"tag":91,"props":872,"children":873},{"style":121},[874],{"type":22,"value":875},"random",{"type":16,"tag":91,"props":877,"children":878},{"style":115},[879],{"type":22,"value":880},"() ",{"type":16,"tag":91,"props":882,"children":883},{"style":98},[884],{"type":22,"value":885},"*",{"type":16,"tag":91,"props":887,"children":888},{"style":115},[889],{"type":22,"value":890}," m);\n",{"type":16,"tag":91,"props":892,"children":894},{"class":93,"line":893},26,[895,900,904,908,912],{"type":16,"tag":91,"props":896,"children":897},{"style":115},[898],{"type":22,"value":899},"    positionsX[i] ",{"type":16,"tag":91,"props":901,"children":902},{"style":98},[903],{"type":22,"value":240},{"type":16,"tag":91,"props":905,"children":906},{"style":115},[907],{"type":22,"value":524},{"type":16,"tag":91,"props":909,"children":910},{"style":121},[911],{"type":22,"value":875},{"type":16,"tag":91,"props":913,"children":914},{"style":115},[915],{"type":22,"value":916},"();\n",{"type":16,"tag":91,"props":918,"children":920},{"class":93,"line":919},27,[921,926,930,934,938],{"type":16,"tag":91,"props":922,"children":923},{"style":115},[924],{"type":22,"value":925},"    positionsY[i] ",{"type":16,"tag":91,"props":927,"children":928},{"style":98},[929],{"type":22,"value":240},{"type":16,"tag":91,"props":931,"children":932},{"style":115},[933],{"type":22,"value":524},{"type":16,"tag":91,"props":935,"children":936},{"style":121},[937],{"type":22,"value":875},{"type":16,"tag":91,"props":939,"children":940},{"style":115},[941],{"type":22,"value":916},{"type":16,"tag":91,"props":943,"children":945},{"class":93,"line":944},28,[946,951,955,959],{"type":16,"tag":91,"props":947,"children":948},{"style":115},[949],{"type":22,"value":950},"    velocitiesX[i] ",{"type":16,"tag":91,"props":952,"children":953},{"style":98},[954],{"type":22,"value":240},{"type":16,"tag":91,"props":956,"children":957},{"style":104},[958],{"type":22,"value":818},{"type":16,"tag":91,"props":960,"children":961},{"style":115},[962],{"type":22,"value":963},";\n",{"type":16,"tag":91,"props":965,"children":967},{"class":93,"line":966},29,[968,973,977,981],{"type":16,"tag":91,"props":969,"children":970},{"style":115},[971],{"type":22,"value":972},"    velocitiesY[i] ",{"type":16,"tag":91,"props":974,"children":975},{"style":98},[976],{"type":22,"value":240},{"type":16,"tag":91,"props":978,"children":979},{"style":104},[980],{"type":22,"value":818},{"type":16,"tag":91,"props":982,"children":983},{"style":115},[984],{"type":22,"value":963},{"type":16,"tag":91,"props":986,"children":988},{"class":93,"line":987},30,[989],{"type":16,"tag":91,"props":990,"children":991},{"style":115},[992],{"type":22,"value":993},"  }\n",{"type":16,"tag":91,"props":995,"children":997},{"class":93,"line":996},31,[998],{"type":16,"tag":91,"props":999,"children":1000},{"emptyLinePlaceholder":560},[1001],{"type":22,"value":563},{"type":16,"tag":91,"props":1003,"children":1005},{"class":93,"line":1004},32,[1006,1011],{"type":16,"tag":91,"props":1007,"children":1008},{"style":121},[1009],{"type":22,"value":1010},"  renderFrame",{"type":16,"tag":91,"props":1012,"children":1013},{"style":115},[1014],{"type":22,"value":916},{"type":16,"tag":91,"props":1016,"children":1018},{"class":93,"line":1017},33,[1019],{"type":16,"tag":91,"props":1020,"children":1021},{"emptyLinePlaceholder":560},[1022],{"type":22,"value":563},{"type":16,"tag":91,"props":1024,"children":1026},{"class":93,"line":1025},34,[1027,1032,1037],{"type":16,"tag":91,"props":1028,"children":1029},{"style":98},[1030],{"type":22,"value":1031},"  function",{"type":16,"tag":91,"props":1033,"children":1034},{"style":121},[1035],{"type":22,"value":1036}," renderFrame",{"type":16,"tag":91,"props":1038,"children":1039},{"style":115},[1040],{"type":22,"value":1041},"() {\n",{"type":16,"tag":91,"props":1043,"children":1045},{"class":93,"line":1044},35,[1046],{"type":16,"tag":91,"props":1047,"children":1048},{"style":158},[1049],{"type":22,"value":1050},"    //Clear previous positions on every frame\n",{"type":16,"tag":91,"props":1052,"children":1054},{"class":93,"line":1053},36,[1055,1060,1064,1069,1073,1078],{"type":16,"tag":91,"props":1056,"children":1057},{"style":115},[1058],{"type":22,"value":1059},"    context",{"type":16,"tag":91,"props":1061,"children":1062},{"style":98},[1063],{"type":22,"value":230},{"type":16,"tag":91,"props":1065,"children":1066},{"style":115},[1067],{"type":22,"value":1068},".fillStyle ",{"type":16,"tag":91,"props":1070,"children":1071},{"style":98},[1072],{"type":22,"value":240},{"type":16,"tag":91,"props":1074,"children":1075},{"style":132},[1076],{"type":22,"value":1077}," \"black\"",{"type":16,"tag":91,"props":1079,"children":1080},{"style":115},[1081],{"type":22,"value":963},{"type":16,"tag":91,"props":1083,"children":1085},{"class":93,"line":1084},37,[1086,1090,1094,1098,1103,1107,1112,1116,1120,1125,1129,1134,1138],{"type":16,"tag":91,"props":1087,"children":1088},{"style":115},[1089],{"type":22,"value":1059},{"type":16,"tag":91,"props":1091,"children":1092},{"style":98},[1093],{"type":22,"value":230},{"type":16,"tag":91,"props":1095,"children":1096},{"style":115},[1097],{"type":22,"value":391},{"type":16,"tag":91,"props":1099,"children":1100},{"style":121},[1101],{"type":22,"value":1102},"fillRect",{"type":16,"tag":91,"props":1104,"children":1105},{"style":115},[1106],{"type":22,"value":129},{"type":16,"tag":91,"props":1108,"children":1109},{"style":104},[1110],{"type":22,"value":1111},"0",{"type":16,"tag":91,"props":1113,"children":1114},{"style":115},[1115],{"type":22,"value":543},{"type":16,"tag":91,"props":1117,"children":1118},{"style":104},[1119],{"type":22,"value":1111},{"type":16,"tag":91,"props":1121,"children":1122},{"style":115},[1123],{"type":22,"value":1124},", canvas",{"type":16,"tag":91,"props":1126,"children":1127},{"style":98},[1128],{"type":22,"value":230},{"type":16,"tag":91,"props":1130,"children":1131},{"style":115},[1132],{"type":22,"value":1133},".clientWidth, canvas",{"type":16,"tag":91,"props":1135,"children":1136},{"style":98},[1137],{"type":22,"value":230},{"type":16,"tag":91,"props":1139,"children":1140},{"style":115},[1141],{"type":22,"value":1142},".clientHeight);\n",{"type":16,"tag":91,"props":1144,"children":1146},{"class":93,"line":1145},38,[1147],{"type":16,"tag":91,"props":1148,"children":1149},{"emptyLinePlaceholder":560},[1150],{"type":22,"value":563},{"type":16,"tag":91,"props":1152,"children":1154},{"class":93,"line":1153},39,[1155,1160,1164,1168,1172,1176,1180,1184,1188,1192,1196],{"type":16,"tag":91,"props":1156,"children":1157},{"style":98},[1158],{"type":22,"value":1159},"    for",{"type":16,"tag":91,"props":1161,"children":1162},{"style":115},[1163],{"type":22,"value":799},{"type":16,"tag":91,"props":1165,"children":1166},{"style":98},[1167],{"type":22,"value":804},{"type":16,"tag":91,"props":1169,"children":1170},{"style":115},[1171],{"type":22,"value":809},{"type":16,"tag":91,"props":1173,"children":1174},{"style":98},[1175],{"type":22,"value":240},{"type":16,"tag":91,"props":1177,"children":1178},{"style":104},[1179],{"type":22,"value":818},{"type":16,"tag":91,"props":1181,"children":1182},{"style":115},[1183],{"type":22,"value":823},{"type":16,"tag":91,"props":1185,"children":1186},{"style":98},[1187],{"type":22,"value":828},{"type":16,"tag":91,"props":1189,"children":1190},{"style":115},[1191],{"type":22,"value":833},{"type":16,"tag":91,"props":1193,"children":1194},{"style":98},[1195],{"type":22,"value":838},{"type":16,"tag":91,"props":1197,"children":1198},{"style":115},[1199],{"type":22,"value":843},{"type":16,"tag":91,"props":1201,"children":1203},{"class":93,"line":1202},40,[1204],{"type":16,"tag":91,"props":1205,"children":1206},{"style":158},[1207],{"type":22,"value":1208},"      //beginPath() method is called before drawing every particle, so that they may be filled with different colors.\n",{"type":16,"tag":91,"props":1210,"children":1212},{"class":93,"line":1211},41,[1213,1218,1222,1226,1231],{"type":16,"tag":91,"props":1214,"children":1215},{"style":115},[1216],{"type":22,"value":1217},"      context",{"type":16,"tag":91,"props":1219,"children":1220},{"style":98},[1221],{"type":22,"value":230},{"type":16,"tag":91,"props":1223,"children":1224},{"style":115},[1225],{"type":22,"value":391},{"type":16,"tag":91,"props":1227,"children":1228},{"style":121},[1229],{"type":22,"value":1230},"beginPath",{"type":16,"tag":91,"props":1232,"children":1233},{"style":115},[1234],{"type":22,"value":916},{"type":16,"tag":91,"props":1236,"children":1238},{"class":93,"line":1237},42,[1239,1244,1249,1253,1258,1262,1266,1270],{"type":16,"tag":91,"props":1240,"children":1241},{"style":98},[1242],{"type":22,"value":1243},"      let",{"type":16,"tag":91,"props":1245,"children":1246},{"style":115},[1247],{"type":22,"value":1248}," x ",{"type":16,"tag":91,"props":1250,"children":1251},{"style":98},[1252],{"type":22,"value":240},{"type":16,"tag":91,"props":1254,"children":1255},{"style":115},[1256],{"type":22,"value":1257}," positionsX[i] ",{"type":16,"tag":91,"props":1259,"children":1260},{"style":98},[1261],{"type":22,"value":885},{"type":16,"tag":91,"props":1263,"children":1264},{"style":115},[1265],{"type":22,"value":107},{"type":16,"tag":91,"props":1267,"children":1268},{"style":98},[1269],{"type":22,"value":230},{"type":16,"tag":91,"props":1271,"children":1272},{"style":115},[1273],{"type":22,"value":1274},".clientWidth;\n",{"type":16,"tag":91,"props":1276,"children":1278},{"class":93,"line":1277},43,[1279,1283,1288,1292,1297,1301,1305,1309],{"type":16,"tag":91,"props":1280,"children":1281},{"style":98},[1282],{"type":22,"value":1243},{"type":16,"tag":91,"props":1284,"children":1285},{"style":115},[1286],{"type":22,"value":1287}," y ",{"type":16,"tag":91,"props":1289,"children":1290},{"style":98},[1291],{"type":22,"value":240},{"type":16,"tag":91,"props":1293,"children":1294},{"style":115},[1295],{"type":22,"value":1296}," positionsY[i] ",{"type":16,"tag":91,"props":1298,"children":1299},{"style":98},[1300],{"type":22,"value":885},{"type":16,"tag":91,"props":1302,"children":1303},{"style":115},[1304],{"type":22,"value":107},{"type":16,"tag":91,"props":1306,"children":1307},{"style":98},[1308],{"type":22,"value":230},{"type":16,"tag":91,"props":1310,"children":1311},{"style":115},[1312],{"type":22,"value":1313},".clientHeight\n",{"type":16,"tag":91,"props":1315,"children":1317},{"class":93,"line":1316},44,[1318],{"type":16,"tag":91,"props":1319,"children":1320},{"style":158},[1321],{"type":22,"value":1322},"      //Adjusting position for two cases:\n",{"type":16,"tag":91,"props":1324,"children":1326},{"class":93,"line":1325},45,[1327],{"type":16,"tag":91,"props":1328,"children":1329},{"style":158},[1330],{"type":22,"value":1331},"      //a) mobile screens -> x\u003Cy\n",{"type":16,"tag":91,"props":1333,"children":1335},{"class":93,"line":1334},46,[1336],{"type":16,"tag":91,"props":1337,"children":1338},{"style":158},[1339],{"type":22,"value":1340},"      //b) desktops -> x>y\n",{"type":16,"tag":91,"props":1342,"children":1344},{"class":93,"line":1343},47,[1345,1350,1354,1359,1363,1368,1373,1377,1381,1385,1390,1395,1400,1404],{"type":16,"tag":91,"props":1346,"children":1347},{"style":115},[1348],{"type":22,"value":1349},"      x ",{"type":16,"tag":91,"props":1351,"children":1352},{"style":98},[1353],{"type":22,"value":240},{"type":16,"tag":91,"props":1355,"children":1356},{"style":115},[1357],{"type":22,"value":1358}," screenRatio ",{"type":16,"tag":91,"props":1360,"children":1361},{"style":98},[1362],{"type":22,"value":828},{"type":16,"tag":91,"props":1364,"children":1365},{"style":104},[1366],{"type":22,"value":1367}," 1",{"type":16,"tag":91,"props":1369,"children":1370},{"style":98},[1371],{"type":22,"value":1372}," ?",{"type":16,"tag":91,"props":1374,"children":1375},{"style":115},[1376],{"type":22,"value":1248},{"type":16,"tag":91,"props":1378,"children":1379},{"style":98},[1380],{"type":22,"value":885},{"type":16,"tag":91,"props":1382,"children":1383},{"style":115},[1384],{"type":22,"value":799},{"type":16,"tag":91,"props":1386,"children":1387},{"style":104},[1388],{"type":22,"value":1389},"1",{"type":16,"tag":91,"props":1391,"children":1392},{"style":98},[1393],{"type":22,"value":1394}," /",{"type":16,"tag":91,"props":1396,"children":1397},{"style":115},[1398],{"type":22,"value":1399}," screenRatio) ",{"type":16,"tag":91,"props":1401,"children":1402},{"style":98},[1403],{"type":22,"value":431},{"type":16,"tag":91,"props":1405,"children":1406},{"style":115},[1407],{"type":22,"value":1408}," x;\n",{"type":16,"tag":91,"props":1410,"children":1412},{"class":93,"line":1411},48,[1413,1418,1422,1426,1431,1435,1439,1443,1447,1451,1455],{"type":16,"tag":91,"props":1414,"children":1415},{"style":115},[1416],{"type":22,"value":1417},"      y ",{"type":16,"tag":91,"props":1419,"children":1420},{"style":98},[1421],{"type":22,"value":240},{"type":16,"tag":91,"props":1423,"children":1424},{"style":115},[1425],{"type":22,"value":1358},{"type":16,"tag":91,"props":1427,"children":1428},{"style":98},[1429],{"type":22,"value":1430},">",{"type":16,"tag":91,"props":1432,"children":1433},{"style":104},[1434],{"type":22,"value":1367},{"type":16,"tag":91,"props":1436,"children":1437},{"style":98},[1438],{"type":22,"value":1372},{"type":16,"tag":91,"props":1440,"children":1441},{"style":115},[1442],{"type":22,"value":1287},{"type":16,"tag":91,"props":1444,"children":1445},{"style":98},[1446],{"type":22,"value":885},{"type":16,"tag":91,"props":1448,"children":1449},{"style":115},[1450],{"type":22,"value":1358},{"type":16,"tag":91,"props":1452,"children":1453},{"style":98},[1454],{"type":22,"value":431},{"type":16,"tag":91,"props":1456,"children":1457},{"style":115},[1458],{"type":22,"value":1459}," y;\n",{"type":16,"tag":91,"props":1461,"children":1463},{"class":93,"line":1462},49,[1464,1469,1473,1477,1482,1486,1490,1494,1499,1504,1509,1513,1517,1521,1525,1529,1533,1537,1541,1545,1550,1555,1559,1563,1567,1571,1575,1579,1583,1587,1592,1596,1600,1605],{"type":16,"tag":91,"props":1465,"children":1466},{"style":98},[1467],{"type":22,"value":1468},"      if",{"type":16,"tag":91,"props":1470,"children":1471},{"style":115},[1472],{"type":22,"value":799},{"type":16,"tag":91,"props":1474,"children":1475},{"style":98},[1476],{"type":22,"value":230},{"type":16,"tag":91,"props":1478,"children":1479},{"style":115},[1480],{"type":22,"value":1481},"(x ",{"type":16,"tag":91,"props":1483,"children":1484},{"style":98},[1485],{"type":22,"value":828},{"type":16,"tag":91,"props":1487,"children":1488},{"style":104},[1489],{"type":22,"value":1367},{"type":16,"tag":91,"props":1491,"children":1492},{"style":115},[1493],{"type":22,"value":140},{"type":16,"tag":91,"props":1495,"children":1496},{"style":98},[1497],{"type":22,"value":1498},"&&",{"type":16,"tag":91,"props":1500,"children":1501},{"style":98},[1502],{"type":22,"value":1503}," !",{"type":16,"tag":91,"props":1505,"children":1506},{"style":115},[1507],{"type":22,"value":1508},"(y ",{"type":16,"tag":91,"props":1510,"children":1511},{"style":98},[1512],{"type":22,"value":828},{"type":16,"tag":91,"props":1514,"children":1515},{"style":104},[1516],{"type":22,"value":1367},{"type":16,"tag":91,"props":1518,"children":1519},{"style":115},[1520],{"type":22,"value":140},{"type":16,"tag":91,"props":1522,"children":1523},{"style":98},[1524],{"type":22,"value":1498},{"type":16,"tag":91,"props":1526,"children":1527},{"style":98},[1528],{"type":22,"value":1503},{"type":16,"tag":91,"props":1530,"children":1531},{"style":115},[1532],{"type":22,"value":1481},{"type":16,"tag":91,"props":1534,"children":1535},{"style":98},[1536],{"type":22,"value":1430},{"type":16,"tag":91,"props":1538,"children":1539},{"style":115},[1540],{"type":22,"value":107},{"type":16,"tag":91,"props":1542,"children":1543},{"style":98},[1544],{"type":22,"value":230},{"type":16,"tag":91,"props":1546,"children":1547},{"style":115},[1548],{"type":22,"value":1549},".clientWidth ",{"type":16,"tag":91,"props":1551,"children":1552},{"style":98},[1553],{"type":22,"value":1554},"-",{"type":16,"tag":91,"props":1556,"children":1557},{"style":104},[1558],{"type":22,"value":1367},{"type":16,"tag":91,"props":1560,"children":1561},{"style":115},[1562],{"type":22,"value":140},{"type":16,"tag":91,"props":1564,"children":1565},{"style":98},[1566],{"type":22,"value":1498},{"type":16,"tag":91,"props":1568,"children":1569},{"style":98},[1570],{"type":22,"value":1503},{"type":16,"tag":91,"props":1572,"children":1573},{"style":115},[1574],{"type":22,"value":1508},{"type":16,"tag":91,"props":1576,"children":1577},{"style":98},[1578],{"type":22,"value":1430},{"type":16,"tag":91,"props":1580,"children":1581},{"style":115},[1582],{"type":22,"value":107},{"type":16,"tag":91,"props":1584,"children":1585},{"style":98},[1586],{"type":22,"value":230},{"type":16,"tag":91,"props":1588,"children":1589},{"style":115},[1590],{"type":22,"value":1591},".clientHeight ",{"type":16,"tag":91,"props":1593,"children":1594},{"style":98},[1595],{"type":22,"value":1554},{"type":16,"tag":91,"props":1597,"children":1598},{"style":104},[1599],{"type":22,"value":1367},{"type":16,"tag":91,"props":1601,"children":1602},{"style":115},[1603],{"type":22,"value":1604},")) { ",{"type":16,"tag":91,"props":1606,"children":1607},{"style":158},[1608],{"type":22,"value":1609},"//avoid blinking at edges due to how space wrapping is done\n",{"type":16,"tag":91,"props":1611,"children":1613},{"class":93,"line":1612},50,[1614],{"type":16,"tag":91,"props":1615,"children":1616},{"style":158},[1617],{"type":22,"value":1618},"        //Drawing the actual particle\n",{"type":16,"tag":91,"props":1620,"children":1622},{"class":93,"line":1621},51,[1623,1628,1632,1636,1641,1646,1650,1654,1658,1662,1667,1672,1676,1681,1685],{"type":16,"tag":91,"props":1624,"children":1625},{"style":115},[1626],{"type":22,"value":1627},"        context",{"type":16,"tag":91,"props":1629,"children":1630},{"style":98},[1631],{"type":22,"value":230},{"type":16,"tag":91,"props":1633,"children":1634},{"style":115},[1635],{"type":22,"value":391},{"type":16,"tag":91,"props":1637,"children":1638},{"style":121},[1639],{"type":22,"value":1640},"arc",{"type":16,"tag":91,"props":1642,"children":1643},{"style":115},[1644],{"type":22,"value":1645},"(x, y, ",{"type":16,"tag":91,"props":1647,"children":1648},{"style":104},[1649],{"type":22,"value":1389},{"type":16,"tag":91,"props":1651,"children":1652},{"style":115},[1653],{"type":22,"value":543},{"type":16,"tag":91,"props":1655,"children":1656},{"style":104},[1657],{"type":22,"value":1111},{"type":16,"tag":91,"props":1659,"children":1660},{"style":115},[1661],{"type":22,"value":543},{"type":16,"tag":91,"props":1663,"children":1664},{"style":104},[1665],{"type":22,"value":1666},"2",{"type":16,"tag":91,"props":1668,"children":1669},{"style":98},[1670],{"type":22,"value":1671}," *",{"type":16,"tag":91,"props":1673,"children":1674},{"style":115},[1675],{"type":22,"value":524},{"type":16,"tag":91,"props":1677,"children":1678},{"style":104},[1679],{"type":22,"value":1680},"PI",{"type":16,"tag":91,"props":1682,"children":1683},{"style":115},[1684],{"type":22,"value":202},{"type":16,"tag":91,"props":1686,"children":1687},{"style":158},[1688],{"type":22,"value":1689},"//js compilers are smart enough for me not to have to move math.pi to var\n",{"type":16,"tag":91,"props":1691,"children":1693},{"class":93,"line":1692},52,[1694,1698,1702,1706,1710,1715,1720,1724,1728,1733,1738,1743,1748,1752,1756,1760,1765],{"type":16,"tag":91,"props":1695,"children":1696},{"style":115},[1697],{"type":22,"value":1627},{"type":16,"tag":91,"props":1699,"children":1700},{"style":98},[1701],{"type":22,"value":230},{"type":16,"tag":91,"props":1703,"children":1704},{"style":115},[1705],{"type":22,"value":1068},{"type":16,"tag":91,"props":1707,"children":1708},{"style":98},[1709],{"type":22,"value":240},{"type":16,"tag":91,"props":1711,"children":1712},{"style":132},[1713],{"type":22,"value":1714}," `hsl(${",{"type":16,"tag":91,"props":1716,"children":1717},{"style":104},[1718],{"type":22,"value":1719},"360",{"type":16,"tag":91,"props":1721,"children":1722},{"style":98},[1723],{"type":22,"value":1671},{"type":16,"tag":91,"props":1725,"children":1726},{"style":132},[1727],{"type":22,"value":799},{"type":16,"tag":91,"props":1729,"children":1730},{"style":115},[1731],{"type":22,"value":1732},"colors",{"type":16,"tag":91,"props":1734,"children":1735},{"style":132},[1736],{"type":22,"value":1737},"[",{"type":16,"tag":91,"props":1739,"children":1740},{"style":115},[1741],{"type":22,"value":1742},"i",{"type":16,"tag":91,"props":1744,"children":1745},{"style":132},[1746],{"type":22,"value":1747},"] ",{"type":16,"tag":91,"props":1749,"children":1750},{"style":98},[1751],{"type":22,"value":314},{"type":16,"tag":91,"props":1753,"children":1754},{"style":115},[1755],{"type":22,"value":449},{"type":16,"tag":91,"props":1757,"children":1758},{"style":132},[1759],{"type":22,"value":418},{"type":16,"tag":91,"props":1761,"children":1762},{"style":132},[1763],{"type":22,"value":1764},"},100%,50%)`",{"type":16,"tag":91,"props":1766,"children":1767},{"style":115},[1768],{"type":22,"value":963},{"type":16,"tag":91,"props":1770,"children":1772},{"class":93,"line":1771},53,[1773,1777,1781,1785,1790],{"type":16,"tag":91,"props":1774,"children":1775},{"style":115},[1776],{"type":22,"value":1627},{"type":16,"tag":91,"props":1778,"children":1779},{"style":98},[1780],{"type":22,"value":230},{"type":16,"tag":91,"props":1782,"children":1783},{"style":115},[1784],{"type":22,"value":391},{"type":16,"tag":91,"props":1786,"children":1787},{"style":121},[1788],{"type":22,"value":1789},"fill",{"type":16,"tag":91,"props":1791,"children":1792},{"style":115},[1793],{"type":22,"value":916},{"type":16,"tag":91,"props":1795,"children":1797},{"class":93,"line":1796},54,[1798],{"type":16,"tag":91,"props":1799,"children":1800},{"style":115},[1801],{"type":22,"value":1802},"      }\n",{"type":16,"tag":91,"props":1804,"children":1806},{"class":93,"line":1805},55,[1807],{"type":16,"tag":91,"props":1808,"children":1809},{"style":115},[1810],{"type":22,"value":1811},"    }\n",{"type":16,"tag":91,"props":1813,"children":1815},{"class":93,"line":1814},56,[1816],{"type":16,"tag":91,"props":1817,"children":1818},{"emptyLinePlaceholder":560},[1819],{"type":22,"value":563},{"type":16,"tag":91,"props":1821,"children":1823},{"class":93,"line":1822},57,[1824,1829],{"type":16,"tag":91,"props":1825,"children":1826},{"style":121},[1827],{"type":22,"value":1828},"    updateParticles",{"type":16,"tag":91,"props":1830,"children":1831},{"style":115},[1832],{"type":22,"value":916},{"type":16,"tag":91,"props":1834,"children":1836},{"class":93,"line":1835},58,[1837],{"type":16,"tag":91,"props":1838,"children":1839},{"style":158},[1840],{"type":22,"value":1841},"    // Native window method to request animation frame. Note: The frequency of calls aims to match the display refresh rate.\n",{"type":16,"tag":91,"props":1843,"children":1845},{"class":93,"line":1844},59,[1846],{"type":16,"tag":91,"props":1847,"children":1848},{"style":158},[1849],{"type":22,"value":1850},"    // This method passes DOMHighResTimeStamp as an argument to callback, so that we can calculate how much our animation should progress in one frame\n",{"type":16,"tag":91,"props":1852,"children":1854},{"class":93,"line":1853},60,[1855],{"type":16,"tag":91,"props":1856,"children":1857},{"style":158},[1858],{"type":22,"value":1859},"    // Otherwise there will be different speed for animation on screens with different refresh rates\n",{"type":16,"tag":91,"props":1861,"children":1863},{"class":93,"line":1862},61,[1864,1869],{"type":16,"tag":91,"props":1865,"children":1866},{"style":121},[1867],{"type":22,"value":1868},"    requestAnimationFrame",{"type":16,"tag":91,"props":1870,"children":1871},{"style":115},[1872],{"type":22,"value":1873},"(renderFrame);\n",{"type":16,"tag":91,"props":1875,"children":1877},{"class":93,"line":1876},62,[1878],{"type":16,"tag":91,"props":1879,"children":1880},{"style":115},[1881],{"type":22,"value":993},{"type":16,"tag":91,"props":1883,"children":1885},{"class":93,"line":1884},63,[1886],{"type":16,"tag":91,"props":1887,"children":1888},{"emptyLinePlaceholder":560},[1889],{"type":22,"value":563},{"type":16,"tag":91,"props":1891,"children":1893},{"class":93,"line":1892},64,[1894,1898,1903],{"type":16,"tag":91,"props":1895,"children":1896},{"style":98},[1897],{"type":22,"value":1031},{"type":16,"tag":91,"props":1899,"children":1900},{"style":121},[1901],{"type":22,"value":1902}," updateParticles",{"type":16,"tag":91,"props":1904,"children":1905},{"style":115},[1906],{"type":22,"value":1041},{"type":16,"tag":91,"props":1908,"children":1910},{"class":93,"line":1909},65,[1911,1915,1919,1923,1927,1931,1935,1939,1943,1947,1951],{"type":16,"tag":91,"props":1912,"children":1913},{"style":98},[1914],{"type":22,"value":1159},{"type":16,"tag":91,"props":1916,"children":1917},{"style":115},[1918],{"type":22,"value":799},{"type":16,"tag":91,"props":1920,"children":1921},{"style":98},[1922],{"type":22,"value":804},{"type":16,"tag":91,"props":1924,"children":1925},{"style":115},[1926],{"type":22,"value":809},{"type":16,"tag":91,"props":1928,"children":1929},{"style":98},[1930],{"type":22,"value":240},{"type":16,"tag":91,"props":1932,"children":1933},{"style":104},[1934],{"type":22,"value":818},{"type":16,"tag":91,"props":1936,"children":1937},{"style":115},[1938],{"type":22,"value":823},{"type":16,"tag":91,"props":1940,"children":1941},{"style":98},[1942],{"type":22,"value":828},{"type":16,"tag":91,"props":1944,"children":1945},{"style":115},[1946],{"type":22,"value":833},{"type":16,"tag":91,"props":1948,"children":1949},{"style":98},[1950],{"type":22,"value":838},{"type":16,"tag":91,"props":1952,"children":1953},{"style":115},[1954],{"type":22,"value":843},{"type":16,"tag":91,"props":1956,"children":1958},{"class":93,"line":1957},66,[1959,1963,1968,1972,1976],{"type":16,"tag":91,"props":1960,"children":1961},{"style":98},[1962],{"type":22,"value":1243},{"type":16,"tag":91,"props":1964,"children":1965},{"style":115},[1966],{"type":22,"value":1967}," totalForceX ",{"type":16,"tag":91,"props":1969,"children":1970},{"style":98},[1971],{"type":22,"value":240},{"type":16,"tag":91,"props":1973,"children":1974},{"style":104},[1975],{"type":22,"value":818},{"type":16,"tag":91,"props":1977,"children":1978},{"style":115},[1979],{"type":22,"value":963},{"type":16,"tag":91,"props":1981,"children":1983},{"class":93,"line":1982},67,[1984,1988,1993,1997,2001],{"type":16,"tag":91,"props":1985,"children":1986},{"style":98},[1987],{"type":22,"value":1243},{"type":16,"tag":91,"props":1989,"children":1990},{"style":115},[1991],{"type":22,"value":1992}," totalForceY ",{"type":16,"tag":91,"props":1994,"children":1995},{"style":98},[1996],{"type":22,"value":240},{"type":16,"tag":91,"props":1998,"children":1999},{"style":104},[2000],{"type":22,"value":818},{"type":16,"tag":91,"props":2002,"children":2003},{"style":115},[2004],{"type":22,"value":963},{"type":16,"tag":91,"props":2006,"children":2008},{"class":93,"line":2007},68,[2009,2014,2018,2022,2027,2031,2035,2040,2044,2049,2053],{"type":16,"tag":91,"props":2010,"children":2011},{"style":98},[2012],{"type":22,"value":2013},"      for",{"type":16,"tag":91,"props":2015,"children":2016},{"style":115},[2017],{"type":22,"value":799},{"type":16,"tag":91,"props":2019,"children":2020},{"style":98},[2021],{"type":22,"value":804},{"type":16,"tag":91,"props":2023,"children":2024},{"style":115},[2025],{"type":22,"value":2026}," j ",{"type":16,"tag":91,"props":2028,"children":2029},{"style":98},[2030],{"type":22,"value":240},{"type":16,"tag":91,"props":2032,"children":2033},{"style":104},[2034],{"type":22,"value":818},{"type":16,"tag":91,"props":2036,"children":2037},{"style":115},[2038],{"type":22,"value":2039},"; j ",{"type":16,"tag":91,"props":2041,"children":2042},{"style":98},[2043],{"type":22,"value":828},{"type":16,"tag":91,"props":2045,"children":2046},{"style":115},[2047],{"type":22,"value":2048}," n; j",{"type":16,"tag":91,"props":2050,"children":2051},{"style":98},[2052],{"type":22,"value":838},{"type":16,"tag":91,"props":2054,"children":2055},{"style":115},[2056],{"type":22,"value":843},{"type":16,"tag":91,"props":2058,"children":2060},{"class":93,"line":2059},69,[2061,2066,2071,2076,2081,2086],{"type":16,"tag":91,"props":2062,"children":2063},{"style":98},[2064],{"type":22,"value":2065},"        if",{"type":16,"tag":91,"props":2067,"children":2068},{"style":115},[2069],{"type":22,"value":2070}," (i ",{"type":16,"tag":91,"props":2072,"children":2073},{"style":98},[2074],{"type":22,"value":2075},"===",{"type":16,"tag":91,"props":2077,"children":2078},{"style":115},[2079],{"type":22,"value":2080}," j) ",{"type":16,"tag":91,"props":2082,"children":2083},{"style":98},[2084],{"type":22,"value":2085},"continue",{"type":16,"tag":91,"props":2087,"children":2088},{"style":115},[2089],{"type":22,"value":963},{"type":16,"tag":91,"props":2091,"children":2093},{"class":93,"line":2092},70,[2094,2099,2103,2107,2112,2116],{"type":16,"tag":91,"props":2095,"children":2096},{"style":98},[2097],{"type":22,"value":2098},"        let",{"type":16,"tag":91,"props":2100,"children":2101},{"style":115},[2102],{"type":22,"value":1248},{"type":16,"tag":91,"props":2104,"children":2105},{"style":98},[2106],{"type":22,"value":240},{"type":16,"tag":91,"props":2108,"children":2109},{"style":115},[2110],{"type":22,"value":2111}," positionsX[j] ",{"type":16,"tag":91,"props":2113,"children":2114},{"style":98},[2115],{"type":22,"value":1554},{"type":16,"tag":91,"props":2117,"children":2118},{"style":115},[2119],{"type":22,"value":2120}," positionsX[i];\n",{"type":16,"tag":91,"props":2122,"children":2124},{"class":93,"line":2123},71,[2125,2129,2133,2137,2142,2146],{"type":16,"tag":91,"props":2126,"children":2127},{"style":98},[2128],{"type":22,"value":2098},{"type":16,"tag":91,"props":2130,"children":2131},{"style":115},[2132],{"type":22,"value":1287},{"type":16,"tag":91,"props":2134,"children":2135},{"style":98},[2136],{"type":22,"value":240},{"type":16,"tag":91,"props":2138,"children":2139},{"style":115},[2140],{"type":22,"value":2141}," positionsY[j] ",{"type":16,"tag":91,"props":2143,"children":2144},{"style":98},[2145],{"type":22,"value":1554},{"type":16,"tag":91,"props":2147,"children":2148},{"style":115},[2149],{"type":22,"value":2150}," positionsY[i];\n",{"type":16,"tag":91,"props":2152,"children":2154},{"class":93,"line":2153},72,[2155,2159,2164,2168,2172,2177,2181,2185,2189,2194,2198,2202,2207],{"type":16,"tag":91,"props":2156,"children":2157},{"style":98},[2158],{"type":22,"value":2098},{"type":16,"tag":91,"props":2160,"children":2161},{"style":115},[2162],{"type":22,"value":2163}," d ",{"type":16,"tag":91,"props":2165,"children":2166},{"style":98},[2167],{"type":22,"value":240},{"type":16,"tag":91,"props":2169,"children":2170},{"style":115},[2171],{"type":22,"value":524},{"type":16,"tag":91,"props":2173,"children":2174},{"style":121},[2175],{"type":22,"value":2176},"sqrt",{"type":16,"tag":91,"props":2178,"children":2179},{"style":115},[2180],{"type":22,"value":1481},{"type":16,"tag":91,"props":2182,"children":2183},{"style":98},[2184],{"type":22,"value":885},{"type":16,"tag":91,"props":2186,"children":2187},{"style":115},[2188],{"type":22,"value":1248},{"type":16,"tag":91,"props":2190,"children":2191},{"style":98},[2192],{"type":22,"value":2193},"+",{"type":16,"tag":91,"props":2195,"children":2196},{"style":115},[2197],{"type":22,"value":1287},{"type":16,"tag":91,"props":2199,"children":2200},{"style":98},[2201],{"type":22,"value":885},{"type":16,"tag":91,"props":2203,"children":2204},{"style":115},[2205],{"type":22,"value":2206}," y); ",{"type":16,"tag":91,"props":2208,"children":2209},{"style":158},[2210],{"type":22,"value":2211},"// No performance advantage in removing math.sqrt. 10x faster than math.hypot.\n",{"type":16,"tag":91,"props":2213,"children":2215},{"class":93,"line":2214},73,[2216,2220,2225,2229],{"type":16,"tag":91,"props":2217,"children":2218},{"style":98},[2219],{"type":22,"value":2065},{"type":16,"tag":91,"props":2221,"children":2222},{"style":115},[2223],{"type":22,"value":2224}," (d ",{"type":16,"tag":91,"props":2226,"children":2227},{"style":98},[2228],{"type":22,"value":828},{"type":16,"tag":91,"props":2230,"children":2231},{"style":115},[2232],{"type":22,"value":2233}," radius) {\n",{"type":16,"tag":91,"props":2235,"children":2237},{"class":93,"line":2236},74,[2238,2243,2248,2252,2257],{"type":16,"tag":91,"props":2239,"children":2240},{"style":98},[2241],{"type":22,"value":2242},"          let",{"type":16,"tag":91,"props":2244,"children":2245},{"style":115},[2246],{"type":22,"value":2247}," f ",{"type":16,"tag":91,"props":2249,"children":2250},{"style":98},[2251],{"type":22,"value":240},{"type":16,"tag":91,"props":2253,"children":2254},{"style":121},[2255],{"type":22,"value":2256}," force",{"type":16,"tag":91,"props":2258,"children":2259},{"style":115},[2260],{"type":22,"value":2261},"(\n",{"type":16,"tag":91,"props":2263,"children":2265},{"class":93,"line":2264},75,[2266,2271,2275],{"type":16,"tag":91,"props":2267,"children":2268},{"style":115},[2269],{"type":22,"value":2270},"            d ",{"type":16,"tag":91,"props":2272,"children":2273},{"style":98},[2274],{"type":22,"value":314},{"type":16,"tag":91,"props":2276,"children":2277},{"style":115},[2278],{"type":22,"value":2279}," radius,\n",{"type":16,"tag":91,"props":2281,"children":2283},{"class":93,"line":2282},76,[2284],{"type":16,"tag":91,"props":2285,"children":2286},{"style":115},[2287],{"type":22,"value":2288},"            matrix[colors[i]][colors[j]])\n",{"type":16,"tag":91,"props":2290,"children":2292},{"class":93,"line":2291},77,[2293,2298,2303,2308,2312,2317,2321],{"type":16,"tag":91,"props":2294,"children":2295},{"style":115},[2296],{"type":22,"value":2297},"          totalForceX ",{"type":16,"tag":91,"props":2299,"children":2300},{"style":98},[2301],{"type":22,"value":2302},"+=",{"type":16,"tag":91,"props":2304,"children":2305},{"style":115},[2306],{"type":22,"value":2307}," (x ",{"type":16,"tag":91,"props":2309,"children":2310},{"style":98},[2311],{"type":22,"value":314},{"type":16,"tag":91,"props":2313,"children":2314},{"style":115},[2315],{"type":22,"value":2316}," d) ",{"type":16,"tag":91,"props":2318,"children":2319},{"style":98},[2320],{"type":22,"value":885},{"type":16,"tag":91,"props":2322,"children":2323},{"style":115},[2324],{"type":22,"value":2325}," f;\n",{"type":16,"tag":91,"props":2327,"children":2329},{"class":93,"line":2328},78,[2330,2335,2339,2344,2348,2352,2356],{"type":16,"tag":91,"props":2331,"children":2332},{"style":115},[2333],{"type":22,"value":2334},"          totalForceY ",{"type":16,"tag":91,"props":2336,"children":2337},{"style":98},[2338],{"type":22,"value":2302},{"type":16,"tag":91,"props":2340,"children":2341},{"style":115},[2342],{"type":22,"value":2343}," (y ",{"type":16,"tag":91,"props":2345,"children":2346},{"style":98},[2347],{"type":22,"value":314},{"type":16,"tag":91,"props":2349,"children":2350},{"style":115},[2351],{"type":22,"value":2316},{"type":16,"tag":91,"props":2353,"children":2354},{"style":98},[2355],{"type":22,"value":885},{"type":16,"tag":91,"props":2357,"children":2358},{"style":115},[2359],{"type":22,"value":2325},{"type":16,"tag":91,"props":2361,"children":2363},{"class":93,"line":2362},79,[2364],{"type":16,"tag":91,"props":2365,"children":2366},{"style":115},[2367],{"type":22,"value":2368},"        }\n",{"type":16,"tag":91,"props":2370,"children":2372},{"class":93,"line":2371},80,[2373,2378,2382],{"type":16,"tag":91,"props":2374,"children":2375},{"style":115},[2376],{"type":22,"value":2377},"        velocitiesX[i] ",{"type":16,"tag":91,"props":2379,"children":2380},{"style":98},[2381],{"type":22,"value":2302},{"type":16,"tag":91,"props":2383,"children":2384},{"style":115},[2385],{"type":22,"value":2386}," totalForceX;\n",{"type":16,"tag":91,"props":2388,"children":2390},{"class":93,"line":2389},81,[2391,2396,2400],{"type":16,"tag":91,"props":2392,"children":2393},{"style":115},[2394],{"type":22,"value":2395},"        velocitiesY[i] ",{"type":16,"tag":91,"props":2397,"children":2398},{"style":98},[2399],{"type":22,"value":2302},{"type":16,"tag":91,"props":2401,"children":2402},{"style":115},[2403],{"type":22,"value":2404}," totalForceY;\n",{"type":16,"tag":91,"props":2406,"children":2408},{"class":93,"line":2407},82,[2409],{"type":16,"tag":91,"props":2410,"children":2411},{"emptyLinePlaceholder":560},[2412],{"type":22,"value":563},{"type":16,"tag":91,"props":2414,"children":2416},{"class":93,"line":2415},83,[2417,2421,2426],{"type":16,"tag":91,"props":2418,"children":2419},{"style":115},[2420],{"type":22,"value":2377},{"type":16,"tag":91,"props":2422,"children":2423},{"style":98},[2424],{"type":22,"value":2425},"*=",{"type":16,"tag":91,"props":2427,"children":2428},{"style":115},[2429],{"type":22,"value":2430}," fr;\n",{"type":16,"tag":91,"props":2432,"children":2434},{"class":93,"line":2433},84,[2435,2439,2443],{"type":16,"tag":91,"props":2436,"children":2437},{"style":115},[2438],{"type":22,"value":2395},{"type":16,"tag":91,"props":2440,"children":2441},{"style":98},[2442],{"type":22,"value":2425},{"type":16,"tag":91,"props":2444,"children":2445},{"style":115},[2446],{"type":22,"value":2430},{"type":16,"tag":91,"props":2448,"children":2450},{"class":93,"line":2449},85,[2451],{"type":16,"tag":91,"props":2452,"children":2453},{"emptyLinePlaceholder":560},[2454],{"type":22,"value":563},{"type":16,"tag":91,"props":2456,"children":2458},{"class":93,"line":2457},86,[2459,2464,2468],{"type":16,"tag":91,"props":2460,"children":2461},{"style":115},[2462],{"type":22,"value":2463},"        positionsX[i] ",{"type":16,"tag":91,"props":2465,"children":2466},{"style":98},[2467],{"type":22,"value":2302},{"type":16,"tag":91,"props":2469,"children":2470},{"style":115},[2471],{"type":22,"value":2472}," velocitiesX[i];\n",{"type":16,"tag":91,"props":2474,"children":2476},{"class":93,"line":2475},87,[2477,2482,2486],{"type":16,"tag":91,"props":2478,"children":2479},{"style":115},[2480],{"type":22,"value":2481},"        positionsY[i] ",{"type":16,"tag":91,"props":2483,"children":2484},{"style":98},[2485],{"type":22,"value":2302},{"type":16,"tag":91,"props":2487,"children":2488},{"style":115},[2489],{"type":22,"value":2490}," velocitiesY[i];\n",{"type":16,"tag":91,"props":2492,"children":2494},{"class":93,"line":2493},88,[2495],{"type":16,"tag":91,"props":2496,"children":2497},{"emptyLinePlaceholder":560},[2498],{"type":22,"value":563},{"type":16,"tag":91,"props":2500,"children":2502},{"class":93,"line":2501},89,[2503,2508,2512],{"type":16,"tag":91,"props":2504,"children":2505},{"style":115},[2506],{"type":22,"value":2507},"        x ",{"type":16,"tag":91,"props":2509,"children":2510},{"style":98},[2511],{"type":22,"value":240},{"type":16,"tag":91,"props":2513,"children":2514},{"style":115},[2515],{"type":22,"value":2120},{"type":16,"tag":91,"props":2517,"children":2519},{"class":93,"line":2518},90,[2520,2525,2529],{"type":16,"tag":91,"props":2521,"children":2522},{"style":115},[2523],{"type":22,"value":2524},"        y ",{"type":16,"tag":91,"props":2526,"children":2527},{"style":98},[2528],{"type":22,"value":240},{"type":16,"tag":91,"props":2530,"children":2531},{"style":115},[2532],{"type":22,"value":2150},{"type":16,"tag":91,"props":2534,"children":2536},{"class":93,"line":2535},91,[2537],{"type":16,"tag":91,"props":2538,"children":2539},{"emptyLinePlaceholder":560},[2540],{"type":22,"value":563},{"type":16,"tag":91,"props":2542,"children":2544},{"class":93,"line":2543},92,[2545],{"type":16,"tag":91,"props":2546,"children":2547},{"style":158},[2548],{"type":22,"value":2549},"        // Prevent particles from running away from the viewport. \n",{"type":16,"tag":91,"props":2551,"children":2553},{"class":93,"line":2552},93,[2554],{"type":16,"tag":91,"props":2555,"children":2556},{"style":158},[2557],{"type":22,"value":2558},"        // If x or y is > 1, substract 1 from it, so that it moves to other part of the screen\n",{"type":16,"tag":91,"props":2560,"children":2562},{"class":93,"line":2561},94,[2563],{"type":16,"tag":91,"props":2564,"children":2565},{"style":158},[2566],{"type":22,"value":2567},"        // This only handles particle position - it's not interacting with \n",{"type":16,"tag":91,"props":2569,"children":2571},{"class":93,"line":2570},95,[2572],{"type":16,"tag":91,"props":2573,"children":2574},{"style":158},[2575],{"type":22,"value":2576},"        // particles from the other side of the screen. In other words, particle at position (0,0) with radius of 0.1\n",{"type":16,"tag":91,"props":2578,"children":2580},{"class":93,"line":2579},96,[2581],{"type":16,"tag":91,"props":2582,"children":2583},{"style":158},[2584],{"type":22,"value":2585},"        // will not interact with particle at position (1.0,1.0). This gives us interesting visual effect (see for GPU.js examples screenshots)\n",{"type":16,"tag":91,"props":2587,"children":2589},{"class":93,"line":2588},97,[2590],{"type":16,"tag":91,"props":2591,"children":2592},{"style":158},[2593],{"type":22,"value":2594},"        // but also causes some issues, like particles aggregating at the edges\n",{"type":16,"tag":91,"props":2596,"children":2598},{"class":93,"line":2597},98,[2599],{"type":16,"tag":91,"props":2600,"children":2601},{"emptyLinePlaceholder":560},[2602],{"type":22,"value":563},{"type":16,"tag":91,"props":2604,"children":2606},{"class":93,"line":2605},99,[2607,2611,2615,2619,2623,2627,2631,2635,2639,2643,2648],{"type":16,"tag":91,"props":2608,"children":2609},{"style":115},[2610],{"type":22,"value":2507},{"type":16,"tag":91,"props":2612,"children":2613},{"style":98},[2614],{"type":22,"value":240},{"type":16,"tag":91,"props":2616,"children":2617},{"style":115},[2618],{"type":22,"value":1248},{"type":16,"tag":91,"props":2620,"children":2621},{"style":98},[2622],{"type":22,"value":1430},{"type":16,"tag":91,"props":2624,"children":2625},{"style":104},[2626],{"type":22,"value":1367},{"type":16,"tag":91,"props":2628,"children":2629},{"style":98},[2630],{"type":22,"value":1372},{"type":16,"tag":91,"props":2632,"children":2633},{"style":115},[2634],{"type":22,"value":1248},{"type":16,"tag":91,"props":2636,"children":2637},{"style":98},[2638],{"type":22,"value":1554},{"type":16,"tag":91,"props":2640,"children":2641},{"style":104},[2642],{"type":22,"value":1367},{"type":16,"tag":91,"props":2644,"children":2645},{"style":98},[2646],{"type":22,"value":2647}," :",{"type":16,"tag":91,"props":2649,"children":2650},{"style":115},[2651],{"type":22,"value":1408},{"type":16,"tag":91,"props":2653,"children":2655},{"class":93,"line":2654},100,[2656,2660,2664,2668,2672,2676,2680,2684,2688,2692,2696],{"type":16,"tag":91,"props":2657,"children":2658},{"style":115},[2659],{"type":22,"value":2524},{"type":16,"tag":91,"props":2661,"children":2662},{"style":98},[2663],{"type":22,"value":240},{"type":16,"tag":91,"props":2665,"children":2666},{"style":115},[2667],{"type":22,"value":1287},{"type":16,"tag":91,"props":2669,"children":2670},{"style":98},[2671],{"type":22,"value":1430},{"type":16,"tag":91,"props":2673,"children":2674},{"style":104},[2675],{"type":22,"value":1367},{"type":16,"tag":91,"props":2677,"children":2678},{"style":98},[2679],{"type":22,"value":1372},{"type":16,"tag":91,"props":2681,"children":2682},{"style":115},[2683],{"type":22,"value":1287},{"type":16,"tag":91,"props":2685,"children":2686},{"style":98},[2687],{"type":22,"value":1554},{"type":16,"tag":91,"props":2689,"children":2690},{"style":104},[2691],{"type":22,"value":1367},{"type":16,"tag":91,"props":2693,"children":2694},{"style":98},[2695],{"type":22,"value":2647},{"type":16,"tag":91,"props":2697,"children":2698},{"style":115},[2699],{"type":22,"value":1459},{"type":16,"tag":91,"props":2701,"children":2703},{"class":93,"line":2702},101,[2704,2708,2712,2716,2720,2724,2728,2732,2736,2740,2744],{"type":16,"tag":91,"props":2705,"children":2706},{"style":115},[2707],{"type":22,"value":2507},{"type":16,"tag":91,"props":2709,"children":2710},{"style":98},[2711],{"type":22,"value":240},{"type":16,"tag":91,"props":2713,"children":2714},{"style":115},[2715],{"type":22,"value":1248},{"type":16,"tag":91,"props":2717,"children":2718},{"style":98},[2719],{"type":22,"value":828},{"type":16,"tag":91,"props":2721,"children":2722},{"style":104},[2723],{"type":22,"value":818},{"type":16,"tag":91,"props":2725,"children":2726},{"style":98},[2727],{"type":22,"value":1372},{"type":16,"tag":91,"props":2729,"children":2730},{"style":115},[2731],{"type":22,"value":1248},{"type":16,"tag":91,"props":2733,"children":2734},{"style":98},[2735],{"type":22,"value":2193},{"type":16,"tag":91,"props":2737,"children":2738},{"style":104},[2739],{"type":22,"value":1367},{"type":16,"tag":91,"props":2741,"children":2742},{"style":98},[2743],{"type":22,"value":2647},{"type":16,"tag":91,"props":2745,"children":2746},{"style":115},[2747],{"type":22,"value":1408},{"type":16,"tag":91,"props":2749,"children":2751},{"class":93,"line":2750},102,[2752,2756,2760,2764,2768,2772,2776,2780,2784,2788,2792],{"type":16,"tag":91,"props":2753,"children":2754},{"style":115},[2755],{"type":22,"value":2524},{"type":16,"tag":91,"props":2757,"children":2758},{"style":98},[2759],{"type":22,"value":240},{"type":16,"tag":91,"props":2761,"children":2762},{"style":115},[2763],{"type":22,"value":1287},{"type":16,"tag":91,"props":2765,"children":2766},{"style":98},[2767],{"type":22,"value":828},{"type":16,"tag":91,"props":2769,"children":2770},{"style":104},[2771],{"type":22,"value":818},{"type":16,"tag":91,"props":2773,"children":2774},{"style":98},[2775],{"type":22,"value":1372},{"type":16,"tag":91,"props":2777,"children":2778},{"style":115},[2779],{"type":22,"value":1287},{"type":16,"tag":91,"props":2781,"children":2782},{"style":98},[2783],{"type":22,"value":2193},{"type":16,"tag":91,"props":2785,"children":2786},{"style":104},[2787],{"type":22,"value":1367},{"type":16,"tag":91,"props":2789,"children":2790},{"style":98},[2791],{"type":22,"value":2647},{"type":16,"tag":91,"props":2793,"children":2794},{"style":115},[2795],{"type":22,"value":1459},{"type":16,"tag":91,"props":2797,"children":2799},{"class":93,"line":2798},103,[2800],{"type":16,"tag":91,"props":2801,"children":2802},{"emptyLinePlaceholder":560},[2803],{"type":22,"value":563},{"type":16,"tag":91,"props":2805,"children":2807},{"class":93,"line":2806},104,[2808,2812,2816],{"type":16,"tag":91,"props":2809,"children":2810},{"style":115},[2811],{"type":22,"value":2463},{"type":16,"tag":91,"props":2813,"children":2814},{"style":98},[2815],{"type":22,"value":240},{"type":16,"tag":91,"props":2817,"children":2818},{"style":115},[2819],{"type":22,"value":1408},{"type":16,"tag":91,"props":2821,"children":2823},{"class":93,"line":2822},105,[2824,2828,2832],{"type":16,"tag":91,"props":2825,"children":2826},{"style":115},[2827],{"type":22,"value":2481},{"type":16,"tag":91,"props":2829,"children":2830},{"style":98},[2831],{"type":22,"value":240},{"type":16,"tag":91,"props":2833,"children":2834},{"style":115},[2835],{"type":22,"value":1459},{"type":16,"tag":91,"props":2837,"children":2839},{"class":93,"line":2838},106,[2840],{"type":16,"tag":91,"props":2841,"children":2842},{"style":115},[2843],{"type":22,"value":1802},{"type":16,"tag":91,"props":2845,"children":2847},{"class":93,"line":2846},107,[2848],{"type":16,"tag":91,"props":2849,"children":2850},{"style":115},[2851],{"type":22,"value":1811},{"type":16,"tag":91,"props":2853,"children":2855},{"class":93,"line":2854},108,[2856],{"type":16,"tag":91,"props":2857,"children":2858},{"style":115},[2859],{"type":22,"value":993},{"type":16,"tag":91,"props":2861,"children":2863},{"class":93,"line":2862},109,[2864],{"type":16,"tag":91,"props":2865,"children":2866},{"emptyLinePlaceholder":560},[2867],{"type":22,"value":563},{"type":16,"tag":91,"props":2869,"children":2871},{"class":93,"line":2870},110,[2872],{"type":16,"tag":91,"props":2873,"children":2874},{"style":158},[2875],{"type":22,"value":2876},"  //Instead of using one force function allow user to choose from several options. \n",{"type":16,"tag":91,"props":2878,"children":2880},{"class":93,"line":2879},111,[2881],{"type":16,"tag":91,"props":2882,"children":2883},{"style":158},[2884],{"type":22,"value":2885},"  //Graphs of every function (assuming the force value between two particles to be 1.0 and a repulsive radius of 1/4 of the max radius)\n",{"type":16,"tag":91,"props":2887,"children":2889},{"class":93,"line":2888},112,[2890],{"type":16,"tag":91,"props":2891,"children":2892},{"style":158},[2893],{"type":22,"value":2894},"  //available on live site of the project\n",{"type":16,"tag":91,"props":2896,"children":2898},{"class":93,"line":2897},113,[2899],{"type":16,"tag":91,"props":2900,"children":2901},{"emptyLinePlaceholder":560},[2902],{"type":22,"value":563},{"type":16,"tag":91,"props":2904,"children":2906},{"class":93,"line":2905},114,[2907,2911,2915,2919,2925,2929,2933,2937,2942,2946,2950,2954,2958,2962],{"type":16,"tag":91,"props":2908,"children":2909},{"style":98},[2910],{"type":22,"value":1031},{"type":16,"tag":91,"props":2912,"children":2913},{"style":121},[2914],{"type":22,"value":2256},{"type":16,"tag":91,"props":2916,"children":2917},{"style":115},[2918],{"type":22,"value":129},{"type":16,"tag":91,"props":2920,"children":2922},{"style":2921},"--shiki-default:#FFAB70",[2923],{"type":22,"value":2924},"d",{"type":16,"tag":91,"props":2926,"children":2927},{"style":98},[2928],{"type":22,"value":431},{"type":16,"tag":91,"props":2930,"children":2931},{"style":104},[2932],{"type":22,"value":630},{"type":16,"tag":91,"props":2934,"children":2935},{"style":115},[2936],{"type":22,"value":543},{"type":16,"tag":91,"props":2938,"children":2939},{"style":2921},[2940],{"type":22,"value":2941},"f",{"type":16,"tag":91,"props":2943,"children":2944},{"style":98},[2945],{"type":22,"value":431},{"type":16,"tag":91,"props":2947,"children":2948},{"style":104},[2949],{"type":22,"value":630},{"type":16,"tag":91,"props":2951,"children":2952},{"style":115},[2953],{"type":22,"value":418},{"type":16,"tag":91,"props":2955,"children":2956},{"style":98},[2957],{"type":22,"value":431},{"type":16,"tag":91,"props":2959,"children":2960},{"style":104},[2961],{"type":22,"value":630},{"type":16,"tag":91,"props":2963,"children":2964},{"style":115},[2965],{"type":22,"value":2966}," {\n",{"type":16,"tag":91,"props":2968,"children":2970},{"class":93,"line":2969},115,[2971,2976,2981,2985],{"type":16,"tag":91,"props":2972,"children":2973},{"style":98},[2974],{"type":22,"value":2975},"    let",{"type":16,"tag":91,"props":2977,"children":2978},{"style":115},[2979],{"type":22,"value":2980}," repRadius ",{"type":16,"tag":91,"props":2982,"children":2983},{"style":98},[2984],{"type":22,"value":240},{"type":16,"tag":91,"props":2986,"children":2987},{"style":115},[2988],{"type":22,"value":2989}," parameters.repulsiveRadius;\n",{"type":16,"tag":91,"props":2991,"children":2993},{"class":93,"line":2992},116,[2994,2999],{"type":16,"tag":91,"props":2995,"children":2996},{"style":98},[2997],{"type":22,"value":2998},"    switch",{"type":16,"tag":91,"props":3000,"children":3001},{"style":115},[3002],{"type":22,"value":3003}," (parameters.forceFunction) {\n",{"type":16,"tag":91,"props":3005,"children":3007},{"class":93,"line":3006},117,[3008,3013,3018],{"type":16,"tag":91,"props":3009,"children":3010},{"style":98},[3011],{"type":22,"value":3012},"      case",{"type":16,"tag":91,"props":3014,"children":3015},{"style":132},[3016],{"type":22,"value":3017}," '1'",{"type":16,"tag":91,"props":3019,"children":3020},{"style":115},[3021],{"type":22,"value":3022},":\n",{"type":16,"tag":91,"props":3024,"children":3026},{"class":93,"line":3025},118,[3027,3032,3037],{"type":16,"tag":91,"props":3028,"children":3029},{"style":98},[3030],{"type":22,"value":3031},"        return",{"type":16,"tag":91,"props":3033,"children":3034},{"style":121},[3035],{"type":22,"value":3036}," forceVariantI",{"type":16,"tag":91,"props":3038,"children":3039},{"style":115},[3040],{"type":22,"value":3041},"(d, f, repRadius);\n",{"type":16,"tag":91,"props":3043,"children":3045},{"class":93,"line":3044},119,[3046,3050,3055],{"type":16,"tag":91,"props":3047,"children":3048},{"style":98},[3049],{"type":22,"value":3012},{"type":16,"tag":91,"props":3051,"children":3052},{"style":132},[3053],{"type":22,"value":3054}," '2'",{"type":16,"tag":91,"props":3056,"children":3057},{"style":115},[3058],{"type":22,"value":3022},{"type":16,"tag":91,"props":3060,"children":3062},{"class":93,"line":3061},120,[3063,3067,3072],{"type":16,"tag":91,"props":3064,"children":3065},{"style":98},[3066],{"type":22,"value":3031},{"type":16,"tag":91,"props":3068,"children":3069},{"style":121},[3070],{"type":22,"value":3071}," forceVariantII",{"type":16,"tag":91,"props":3073,"children":3074},{"style":115},[3075],{"type":22,"value":3041},{"type":16,"tag":91,"props":3077,"children":3079},{"class":93,"line":3078},121,[3080,3084,3089],{"type":16,"tag":91,"props":3081,"children":3082},{"style":98},[3083],{"type":22,"value":3012},{"type":16,"tag":91,"props":3085,"children":3086},{"style":132},[3087],{"type":22,"value":3088}," '3'",{"type":16,"tag":91,"props":3090,"children":3091},{"style":115},[3092],{"type":22,"value":3022},{"type":16,"tag":91,"props":3094,"children":3096},{"class":93,"line":3095},122,[3097,3101,3106],{"type":16,"tag":91,"props":3098,"children":3099},{"style":98},[3100],{"type":22,"value":3031},{"type":16,"tag":91,"props":3102,"children":3103},{"style":121},[3104],{"type":22,"value":3105}," forceVariantIII",{"type":16,"tag":91,"props":3107,"children":3108},{"style":115},[3109],{"type":22,"value":3041},{"type":16,"tag":91,"props":3111,"children":3113},{"class":93,"line":3112},123,[3114,3119],{"type":16,"tag":91,"props":3115,"children":3116},{"style":98},[3117],{"type":22,"value":3118},"      default",{"type":16,"tag":91,"props":3120,"children":3121},{"style":115},[3122],{"type":22,"value":3022},{"type":16,"tag":91,"props":3124,"children":3126},{"class":93,"line":3125},124,[3127,3131,3136],{"type":16,"tag":91,"props":3128,"children":3129},{"style":98},[3130],{"type":22,"value":3031},{"type":16,"tag":91,"props":3132,"children":3133},{"style":121},[3134],{"type":22,"value":3135}," defaultForce",{"type":16,"tag":91,"props":3137,"children":3138},{"style":115},[3139],{"type":22,"value":3140},"(d, f, repRadius)\n",{"type":16,"tag":91,"props":3142,"children":3144},{"class":93,"line":3143},125,[3145],{"type":16,"tag":91,"props":3146,"children":3147},{"style":115},[3148],{"type":22,"value":1811},{"type":16,"tag":91,"props":3150,"children":3152},{"class":93,"line":3151},126,[3153],{"type":16,"tag":91,"props":3154,"children":3155},{"style":115},[3156],{"type":22,"value":993},{"type":16,"tag":91,"props":3158,"children":3160},{"class":93,"line":3159},127,[3161],{"type":16,"tag":91,"props":3162,"children":3163},{"emptyLinePlaceholder":560},[3164],{"type":22,"value":563},{"type":16,"tag":91,"props":3166,"children":3168},{"class":93,"line":3167},128,[3169,3173,3177,3181,3185,3189,3193,3197,3201,3205,3209,3213,3218,3222,3226,3230,3234,3238],{"type":16,"tag":91,"props":3170,"children":3171},{"style":98},[3172],{"type":22,"value":1031},{"type":16,"tag":91,"props":3174,"children":3175},{"style":121},[3176],{"type":22,"value":3036},{"type":16,"tag":91,"props":3178,"children":3179},{"style":115},[3180],{"type":22,"value":129},{"type":16,"tag":91,"props":3182,"children":3183},{"style":2921},[3184],{"type":22,"value":2924},{"type":16,"tag":91,"props":3186,"children":3187},{"style":98},[3188],{"type":22,"value":431},{"type":16,"tag":91,"props":3190,"children":3191},{"style":104},[3192],{"type":22,"value":630},{"type":16,"tag":91,"props":3194,"children":3195},{"style":115},[3196],{"type":22,"value":543},{"type":16,"tag":91,"props":3198,"children":3199},{"style":2921},[3200],{"type":22,"value":2941},{"type":16,"tag":91,"props":3202,"children":3203},{"style":98},[3204],{"type":22,"value":431},{"type":16,"tag":91,"props":3206,"children":3207},{"style":104},[3208],{"type":22,"value":630},{"type":16,"tag":91,"props":3210,"children":3211},{"style":115},[3212],{"type":22,"value":543},{"type":16,"tag":91,"props":3214,"children":3215},{"style":2921},[3216],{"type":22,"value":3217},"repRadius",{"type":16,"tag":91,"props":3219,"children":3220},{"style":98},[3221],{"type":22,"value":431},{"type":16,"tag":91,"props":3223,"children":3224},{"style":104},[3225],{"type":22,"value":630},{"type":16,"tag":91,"props":3227,"children":3228},{"style":115},[3229],{"type":22,"value":418},{"type":16,"tag":91,"props":3231,"children":3232},{"style":98},[3233],{"type":22,"value":431},{"type":16,"tag":91,"props":3235,"children":3236},{"style":104},[3237],{"type":22,"value":630},{"type":16,"tag":91,"props":3239,"children":3240},{"style":115},[3241],{"type":22,"value":2966},{"type":16,"tag":91,"props":3243,"children":3245},{"class":93,"line":3244},129,[3246,3251,3255,3260],{"type":16,"tag":91,"props":3247,"children":3248},{"style":98},[3249],{"type":22,"value":3250},"    if",{"type":16,"tag":91,"props":3252,"children":3253},{"style":115},[3254],{"type":22,"value":2224},{"type":16,"tag":91,"props":3256,"children":3257},{"style":98},[3258],{"type":22,"value":3259},"\u003C=",{"type":16,"tag":91,"props":3261,"children":3262},{"style":115},[3263],{"type":22,"value":3264}," repRadius) {\n",{"type":16,"tag":91,"props":3266,"children":3268},{"class":93,"line":3267},130,[3269,3274,3278,3282,3286,3290],{"type":16,"tag":91,"props":3270,"children":3271},{"style":98},[3272],{"type":22,"value":3273},"          return",{"type":16,"tag":91,"props":3275,"children":3276},{"style":115},[3277],{"type":22,"value":2163},{"type":16,"tag":91,"props":3279,"children":3280},{"style":98},[3281],{"type":22,"value":314},{"type":16,"tag":91,"props":3283,"children":3284},{"style":115},[3285],{"type":22,"value":2980},{"type":16,"tag":91,"props":3287,"children":3288},{"style":98},[3289],{"type":22,"value":1554},{"type":16,"tag":91,"props":3291,"children":3292},{"style":104},[3293],{"type":22,"value":3294}," 1\n",{"type":16,"tag":91,"props":3296,"children":3298},{"class":93,"line":3297},131,[3299,3304,3309],{"type":16,"tag":91,"props":3300,"children":3301},{"style":115},[3302],{"type":22,"value":3303},"        } ",{"type":16,"tag":91,"props":3305,"children":3306},{"style":98},[3307],{"type":22,"value":3308},"else",{"type":16,"tag":91,"props":3310,"children":3311},{"style":115},[3312],{"type":22,"value":2966},{"type":16,"tag":91,"props":3314,"children":3316},{"class":93,"line":3315},132,[3317,3321,3325,3329,3333,3337,3342,3346,3351,3355,3359,3363,3367,3371,3375,3379,3384,3388,3392,3396],{"type":16,"tag":91,"props":3318,"children":3319},{"style":98},[3320],{"type":22,"value":3273},{"type":16,"tag":91,"props":3322,"children":3323},{"style":115},[3324],{"type":22,"value":2247},{"type":16,"tag":91,"props":3326,"children":3327},{"style":98},[3328],{"type":22,"value":885},{"type":16,"tag":91,"props":3330,"children":3331},{"style":115},[3332],{"type":22,"value":799},{"type":16,"tag":91,"props":3334,"children":3335},{"style":104},[3336],{"type":22,"value":1389},{"type":16,"tag":91,"props":3338,"children":3339},{"style":98},[3340],{"type":22,"value":3341}," -",{"type":16,"tag":91,"props":3343,"children":3344},{"style":115},[3345],{"type":22,"value":524},{"type":16,"tag":91,"props":3347,"children":3348},{"style":121},[3349],{"type":22,"value":3350},"abs",{"type":16,"tag":91,"props":3352,"children":3353},{"style":115},[3354],{"type":22,"value":129},{"type":16,"tag":91,"props":3356,"children":3357},{"style":104},[3358],{"type":22,"value":1666},{"type":16,"tag":91,"props":3360,"children":3361},{"style":98},[3362],{"type":22,"value":1671},{"type":16,"tag":91,"props":3364,"children":3365},{"style":115},[3366],{"type":22,"value":2163},{"type":16,"tag":91,"props":3368,"children":3369},{"style":98},[3370],{"type":22,"value":1554},{"type":16,"tag":91,"props":3372,"children":3373},{"style":104},[3374],{"type":22,"value":1367},{"type":16,"tag":91,"props":3376,"children":3377},{"style":98},[3378],{"type":22,"value":3341},{"type":16,"tag":91,"props":3380,"children":3381},{"style":115},[3382],{"type":22,"value":3383}," repRadius) ",{"type":16,"tag":91,"props":3385,"children":3386},{"style":98},[3387],{"type":22,"value":314},{"type":16,"tag":91,"props":3389,"children":3390},{"style":104},[3391],{"type":22,"value":1367},{"type":16,"tag":91,"props":3393,"children":3394},{"style":98},[3395],{"type":22,"value":3341},{"type":16,"tag":91,"props":3397,"children":3398},{"style":115},[3399],{"type":22,"value":3400}," repRadius);\n",{"type":16,"tag":91,"props":3402,"children":3404},{"class":93,"line":3403},133,[3405],{"type":16,"tag":91,"props":3406,"children":3407},{"style":115},[3408],{"type":22,"value":2368},{"type":16,"tag":91,"props":3410,"children":3412},{"class":93,"line":3411},134,[3413],{"type":16,"tag":91,"props":3414,"children":3415},{"style":115},[3416],{"type":22,"value":993},{"type":16,"tag":91,"props":3418,"children":3420},{"class":93,"line":3419},135,[3421],{"type":16,"tag":91,"props":3422,"children":3423},{"emptyLinePlaceholder":560},[3424],{"type":22,"value":563},{"type":16,"tag":91,"props":3426,"children":3428},{"class":93,"line":3427},136,[3429,3433,3437,3441,3445,3449,3453,3457,3461,3465,3469,3473,3477,3481,3485,3489,3493,3497],{"type":16,"tag":91,"props":3430,"children":3431},{"style":98},[3432],{"type":22,"value":1031},{"type":16,"tag":91,"props":3434,"children":3435},{"style":121},[3436],{"type":22,"value":3071},{"type":16,"tag":91,"props":3438,"children":3439},{"style":115},[3440],{"type":22,"value":129},{"type":16,"tag":91,"props":3442,"children":3443},{"style":2921},[3444],{"type":22,"value":2924},{"type":16,"tag":91,"props":3446,"children":3447},{"style":98},[3448],{"type":22,"value":431},{"type":16,"tag":91,"props":3450,"children":3451},{"style":104},[3452],{"type":22,"value":630},{"type":16,"tag":91,"props":3454,"children":3455},{"style":115},[3456],{"type":22,"value":543},{"type":16,"tag":91,"props":3458,"children":3459},{"style":2921},[3460],{"type":22,"value":2941},{"type":16,"tag":91,"props":3462,"children":3463},{"style":98},[3464],{"type":22,"value":431},{"type":16,"tag":91,"props":3466,"children":3467},{"style":104},[3468],{"type":22,"value":630},{"type":16,"tag":91,"props":3470,"children":3471},{"style":115},[3472],{"type":22,"value":543},{"type":16,"tag":91,"props":3474,"children":3475},{"style":2921},[3476],{"type":22,"value":3217},{"type":16,"tag":91,"props":3478,"children":3479},{"style":98},[3480],{"type":22,"value":431},{"type":16,"tag":91,"props":3482,"children":3483},{"style":104},[3484],{"type":22,"value":630},{"type":16,"tag":91,"props":3486,"children":3487},{"style":115},[3488],{"type":22,"value":418},{"type":16,"tag":91,"props":3490,"children":3491},{"style":98},[3492],{"type":22,"value":431},{"type":16,"tag":91,"props":3494,"children":3495},{"style":104},[3496],{"type":22,"value":630},{"type":16,"tag":91,"props":3498,"children":3499},{"style":115},[3500],{"type":22,"value":2966},{"type":16,"tag":91,"props":3502,"children":3504},{"class":93,"line":3503},137,[3505,3509,3513,3517],{"type":16,"tag":91,"props":3506,"children":3507},{"style":98},[3508],{"type":22,"value":3250},{"type":16,"tag":91,"props":3510,"children":3511},{"style":115},[3512],{"type":22,"value":2224},{"type":16,"tag":91,"props":3514,"children":3515},{"style":98},[3516],{"type":22,"value":3259},{"type":16,"tag":91,"props":3518,"children":3519},{"style":115},[3520],{"type":22,"value":3264},{"type":16,"tag":91,"props":3522,"children":3524},{"class":93,"line":3523},138,[3525,3529,3533,3537,3541,3545,3549,3553,3557,3562,3566,3570,3574,3578],{"type":16,"tag":91,"props":3526,"children":3527},{"style":98},[3528],{"type":22,"value":3273},{"type":16,"tag":91,"props":3530,"children":3531},{"style":115},[3532],{"type":22,"value":2224},{"type":16,"tag":91,"props":3534,"children":3535},{"style":98},[3536],{"type":22,"value":314},{"type":16,"tag":91,"props":3538,"children":3539},{"style":115},[3540],{"type":22,"value":2980},{"type":16,"tag":91,"props":3542,"children":3543},{"style":98},[3544],{"type":22,"value":1554},{"type":16,"tag":91,"props":3546,"children":3547},{"style":104},[3548],{"type":22,"value":1367},{"type":16,"tag":91,"props":3550,"children":3551},{"style":115},[3552],{"type":22,"value":140},{"type":16,"tag":91,"props":3554,"children":3555},{"style":98},[3556],{"type":22,"value":2193},{"type":16,"tag":91,"props":3558,"children":3559},{"style":115},[3560],{"type":22,"value":3561}," (f ",{"type":16,"tag":91,"props":3563,"children":3564},{"style":98},[3565],{"type":22,"value":885},{"type":16,"tag":91,"props":3567,"children":3568},{"style":115},[3569],{"type":22,"value":799},{"type":16,"tag":91,"props":3571,"children":3572},{"style":104},[3573],{"type":22,"value":1389},{"type":16,"tag":91,"props":3575,"children":3576},{"style":98},[3577],{"type":22,"value":3341},{"type":16,"tag":91,"props":3579,"children":3580},{"style":115},[3581],{"type":22,"value":3582}," d))\n",{"type":16,"tag":91,"props":3584,"children":3586},{"class":93,"line":3585},139,[3587,3591,3595],{"type":16,"tag":91,"props":3588,"children":3589},{"style":115},[3590],{"type":22,"value":3303},{"type":16,"tag":91,"props":3592,"children":3593},{"style":98},[3594],{"type":22,"value":3308},{"type":16,"tag":91,"props":3596,"children":3597},{"style":115},[3598],{"type":22,"value":2966},{"type":16,"tag":91,"props":3600,"children":3602},{"class":93,"line":3601},140,[3603,3607,3611,3615,3619,3623,3627],{"type":16,"tag":91,"props":3604,"children":3605},{"style":98},[3606],{"type":22,"value":3273},{"type":16,"tag":91,"props":3608,"children":3609},{"style":115},[3610],{"type":22,"value":2247},{"type":16,"tag":91,"props":3612,"children":3613},{"style":98},[3614],{"type":22,"value":885},{"type":16,"tag":91,"props":3616,"children":3617},{"style":115},[3618],{"type":22,"value":799},{"type":16,"tag":91,"props":3620,"children":3621},{"style":104},[3622],{"type":22,"value":1389},{"type":16,"tag":91,"props":3624,"children":3625},{"style":98},[3626],{"type":22,"value":3341},{"type":16,"tag":91,"props":3628,"children":3629},{"style":115},[3630],{"type":22,"value":3631}," d)\n",{"type":16,"tag":91,"props":3633,"children":3635},{"class":93,"line":3634},141,[3636],{"type":16,"tag":91,"props":3637,"children":3638},{"style":115},[3639],{"type":22,"value":2368},{"type":16,"tag":91,"props":3641,"children":3643},{"class":93,"line":3642},142,[3644],{"type":16,"tag":91,"props":3645,"children":3646},{"style":115},[3647],{"type":22,"value":993},{"type":16,"tag":91,"props":3649,"children":3651},{"class":93,"line":3650},143,[3652],{"type":16,"tag":91,"props":3653,"children":3654},{"emptyLinePlaceholder":560},[3655],{"type":22,"value":563},{"type":16,"tag":91,"props":3657,"children":3659},{"class":93,"line":3658},144,[3660,3664,3668,3672,3676,3680,3684,3688,3692,3696,3700,3704,3708,3712,3716,3720,3724,3728],{"type":16,"tag":91,"props":3661,"children":3662},{"style":98},[3663],{"type":22,"value":1031},{"type":16,"tag":91,"props":3665,"children":3666},{"style":121},[3667],{"type":22,"value":3105},{"type":16,"tag":91,"props":3669,"children":3670},{"style":115},[3671],{"type":22,"value":129},{"type":16,"tag":91,"props":3673,"children":3674},{"style":2921},[3675],{"type":22,"value":2924},{"type":16,"tag":91,"props":3677,"children":3678},{"style":98},[3679],{"type":22,"value":431},{"type":16,"tag":91,"props":3681,"children":3682},{"style":104},[3683],{"type":22,"value":630},{"type":16,"tag":91,"props":3685,"children":3686},{"style":115},[3687],{"type":22,"value":543},{"type":16,"tag":91,"props":3689,"children":3690},{"style":2921},[3691],{"type":22,"value":2941},{"type":16,"tag":91,"props":3693,"children":3694},{"style":98},[3695],{"type":22,"value":431},{"type":16,"tag":91,"props":3697,"children":3698},{"style":104},[3699],{"type":22,"value":630},{"type":16,"tag":91,"props":3701,"children":3702},{"style":115},[3703],{"type":22,"value":543},{"type":16,"tag":91,"props":3705,"children":3706},{"style":2921},[3707],{"type":22,"value":3217},{"type":16,"tag":91,"props":3709,"children":3710},{"style":98},[3711],{"type":22,"value":431},{"type":16,"tag":91,"props":3713,"children":3714},{"style":104},[3715],{"type":22,"value":630},{"type":16,"tag":91,"props":3717,"children":3718},{"style":115},[3719],{"type":22,"value":418},{"type":16,"tag":91,"props":3721,"children":3722},{"style":98},[3723],{"type":22,"value":431},{"type":16,"tag":91,"props":3725,"children":3726},{"style":104},[3727],{"type":22,"value":630},{"type":16,"tag":91,"props":3729,"children":3730},{"style":115},[3731],{"type":22,"value":2966},{"type":16,"tag":91,"props":3733,"children":3735},{"class":93,"line":3734},145,[3736,3741,3745],{"type":16,"tag":91,"props":3737,"children":3738},{"style":98},[3739],{"type":22,"value":3740},"   return",{"type":16,"tag":91,"props":3742,"children":3743},{"style":121},[3744],{"type":22,"value":3135},{"type":16,"tag":91,"props":3746,"children":3747},{"style":115},[3748],{"type":22,"value":3749},"(d,f,repRadius)\n",{"type":16,"tag":91,"props":3751,"children":3753},{"class":93,"line":3752},146,[3754],{"type":16,"tag":91,"props":3755,"children":3756},{"style":115},[3757],{"type":22,"value":993},{"type":16,"tag":91,"props":3759,"children":3761},{"class":93,"line":3760},147,[3762],{"type":16,"tag":91,"props":3763,"children":3764},{"emptyLinePlaceholder":560},[3765],{"type":22,"value":563},{"type":16,"tag":91,"props":3767,"children":3769},{"class":93,"line":3768},148,[3770,3774,3778,3782,3786,3790,3794,3798,3802,3806,3810,3814,3818,3822,3826,3830,3834,3838],{"type":16,"tag":91,"props":3771,"children":3772},{"style":98},[3773],{"type":22,"value":1031},{"type":16,"tag":91,"props":3775,"children":3776},{"style":121},[3777],{"type":22,"value":3135},{"type":16,"tag":91,"props":3779,"children":3780},{"style":115},[3781],{"type":22,"value":129},{"type":16,"tag":91,"props":3783,"children":3784},{"style":2921},[3785],{"type":22,"value":2924},{"type":16,"tag":91,"props":3787,"children":3788},{"style":98},[3789],{"type":22,"value":431},{"type":16,"tag":91,"props":3791,"children":3792},{"style":104},[3793],{"type":22,"value":630},{"type":16,"tag":91,"props":3795,"children":3796},{"style":115},[3797],{"type":22,"value":543},{"type":16,"tag":91,"props":3799,"children":3800},{"style":2921},[3801],{"type":22,"value":2941},{"type":16,"tag":91,"props":3803,"children":3804},{"style":98},[3805],{"type":22,"value":431},{"type":16,"tag":91,"props":3807,"children":3808},{"style":104},[3809],{"type":22,"value":630},{"type":16,"tag":91,"props":3811,"children":3812},{"style":115},[3813],{"type":22,"value":543},{"type":16,"tag":91,"props":3815,"children":3816},{"style":2921},[3817],{"type":22,"value":3217},{"type":16,"tag":91,"props":3819,"children":3820},{"style":98},[3821],{"type":22,"value":431},{"type":16,"tag":91,"props":3823,"children":3824},{"style":104},[3825],{"type":22,"value":630},{"type":16,"tag":91,"props":3827,"children":3828},{"style":115},[3829],{"type":22,"value":418},{"type":16,"tag":91,"props":3831,"children":3832},{"style":98},[3833],{"type":22,"value":431},{"type":16,"tag":91,"props":3835,"children":3836},{"style":104},[3837],{"type":22,"value":630},{"type":16,"tag":91,"props":3839,"children":3840},{"style":115},[3841],{"type":22,"value":2966},{"type":16,"tag":91,"props":3843,"children":3845},{"class":93,"line":3844},149,[3846,3850,3854,3858],{"type":16,"tag":91,"props":3847,"children":3848},{"style":98},[3849],{"type":22,"value":3250},{"type":16,"tag":91,"props":3851,"children":3852},{"style":115},[3853],{"type":22,"value":2224},{"type":16,"tag":91,"props":3855,"children":3856},{"style":98},[3857],{"type":22,"value":3259},{"type":16,"tag":91,"props":3859,"children":3860},{"style":115},[3861],{"type":22,"value":3264},{"type":16,"tag":91,"props":3863,"children":3865},{"class":93,"line":3864},150,[3866,3871,3875,3879,3883,3887],{"type":16,"tag":91,"props":3867,"children":3868},{"style":98},[3869],{"type":22,"value":3870},"      return",{"type":16,"tag":91,"props":3872,"children":3873},{"style":115},[3874],{"type":22,"value":2163},{"type":16,"tag":91,"props":3876,"children":3877},{"style":98},[3878],{"type":22,"value":314},{"type":16,"tag":91,"props":3880,"children":3881},{"style":115},[3882],{"type":22,"value":2980},{"type":16,"tag":91,"props":3884,"children":3885},{"style":98},[3886],{"type":22,"value":1554},{"type":16,"tag":91,"props":3888,"children":3889},{"style":104},[3890],{"type":22,"value":3294},{"type":16,"tag":91,"props":3892,"children":3894},{"class":93,"line":3893},151,[3895,3900,3904],{"type":16,"tag":91,"props":3896,"children":3897},{"style":115},[3898],{"type":22,"value":3899},"    } ",{"type":16,"tag":91,"props":3901,"children":3902},{"style":98},[3903],{"type":22,"value":3308},{"type":16,"tag":91,"props":3905,"children":3906},{"style":115},[3907],{"type":22,"value":2966},{"type":16,"tag":91,"props":3909,"children":3911},{"class":93,"line":3910},152,[3912,3916,3920,3924,3928,3932,3936],{"type":16,"tag":91,"props":3913,"children":3914},{"style":98},[3915],{"type":22,"value":3870},{"type":16,"tag":91,"props":3917,"children":3918},{"style":115},[3919],{"type":22,"value":2247},{"type":16,"tag":91,"props":3921,"children":3922},{"style":98},[3923],{"type":22,"value":885},{"type":16,"tag":91,"props":3925,"children":3926},{"style":115},[3927],{"type":22,"value":799},{"type":16,"tag":91,"props":3929,"children":3930},{"style":104},[3931],{"type":22,"value":1389},{"type":16,"tag":91,"props":3933,"children":3934},{"style":98},[3935],{"type":22,"value":3341},{"type":16,"tag":91,"props":3937,"children":3938},{"style":115},[3939],{"type":22,"value":3631},{"type":16,"tag":91,"props":3941,"children":3943},{"class":93,"line":3942},153,[3944],{"type":16,"tag":91,"props":3945,"children":3946},{"style":115},[3947],{"type":22,"value":1811},{"type":16,"tag":91,"props":3949,"children":3951},{"class":93,"line":3950},154,[3952],{"type":16,"tag":91,"props":3953,"children":3954},{"style":115},[3955],{"type":22,"value":993},{"type":16,"tag":17,"props":3957,"children":3959},{"id":3958},"quadtree",[3960],{"type":22,"value":3961},"QuadTree",{"type":16,"tag":25,"props":3963,"children":3964},{},[3965],{"type":22,"value":3966},"Now that my code is running in the browser, it's time for optimization. We have a set of points in 2D space that can only interact with one another within a given radius. To see which particles fall within this range, we must examine every particle in the system. This is the root cause of the inefficiency of our program.",{"type":16,"tag":25,"props":3968,"children":3969},{},[3970,3972,3978],{"type":22,"value":3971},"So, how do we retrieve particles that only reside in the surroundings of the particle we’re calculating the velocity of? We would need a data structure that stores ",{"type":16,"tag":3973,"props":3974,"children":3975},"strong",{},[3976],{"type":22,"value":3977},"regions",{"type":22,"value":3979}," of space and their corresponding particles. This way, we could just query regions within a given area and thus get all particles living there. Here comes the QuadTree!",{"type":16,"tag":25,"props":3981,"children":3982},{},[3983],{"type":22,"value":3984},"Consider the root node, which will translate to our entire 2D plane:",{"type":16,"tag":3986,"props":3987,"children":3989},"img",{"src":3988},"/articles/drawisland.png",[],{"type":16,"tag":25,"props":3991,"children":3992},{},[3993],{"type":22,"value":3994},"First, let’s examine if our node has more particles than its carrying capacity. Let’s assume the carrying capacity for every sector is 4.\nBelow, we have 5 particles. The number of particles exceeds the carrying capacity of our sector, so we need to subdivide it. We’ll divide one sector into 4 smaller ones:",{"type":16,"tag":3986,"props":3996,"children":3998},{"src":3997},"/articles/drawisland (2).png",[],{"type":16,"tag":25,"props":4000,"children":4001},{},[4002],{"type":22,"value":4003},"Now, let’s repeat the first step for every one of our new nodes. In this case, none of the child nodes exceed the carrying capacity, so we stop here, and this is our final quadtree. Had it not been the case, we’d repeat the division recursively, creating smaller and smaller sections for every node that exceeds its capacity. This makes it a very good data structure for our simulation, where attraction between particles will usually lead to an uneven distribution of particles. Only crowded sectors get subdivided.",{"type":16,"tag":25,"props":4005,"children":4006},{},[4007],{"type":22,"value":4008},"Now, every sector needs the following properties:",{"type":16,"tag":31,"props":4010,"children":4011},{},[4012,4022,4032,4042],{"type":16,"tag":35,"props":4013,"children":4014},{},[4015,4020],{"type":16,"tag":3973,"props":4016,"children":4017},{},[4018],{"type":22,"value":4019},"boundary",{"type":22,"value":4021}," - a region of space it covers. We can represent it as a rectangle with a center point (x,y) and its height and width;",{"type":16,"tag":35,"props":4023,"children":4024},{},[4025,4030],{"type":16,"tag":3973,"props":4026,"children":4027},{},[4028],{"type":22,"value":4029},"capacity",{"type":22,"value":4031}," - carrying capacity;",{"type":16,"tag":35,"props":4033,"children":4034},{},[4035,4040],{"type":16,"tag":3973,"props":4036,"children":4037},{},[4038],{"type":22,"value":4039},"points",{"type":22,"value":4041}," - an array of points, given the sector is not subdivided;",{"type":16,"tag":35,"props":4043,"children":4044},{},[4045,4050],{"type":16,"tag":3973,"props":4046,"children":4047},{},[4048],{"type":22,"value":4049},"divided",{"type":22,"value":4051}," - indicates if the sector is subdivided;",{"type":16,"tag":25,"props":4053,"children":4054},{},[4055],{"type":22,"value":4056},"Of course, we also need at least methods to insert, delete, and query particles. These methods will work recursively. For example, to implement query() method, we need to:",{"type":16,"tag":31,"props":4058,"children":4059},{},[4060,4065,4070,4075],{"type":16,"tag":35,"props":4061,"children":4062},{},[4063],{"type":22,"value":4064},"Check if the queried area intersects with the root node",{"type":16,"tag":35,"props":4066,"children":4067},{},[4068],{"type":22,"value":4069},"If it doesn’t return an empty array",{"type":16,"tag":35,"props":4071,"children":4072},{},[4073],{"type":22,"value":4074},"If it does and the root node is not subdivided, return all points belonging to this node",{"type":16,"tag":35,"props":4076,"children":4077},{},[4078],{"type":22,"value":4079},"If it does and the node is subdivided, repeat the same for every child node",{"type":16,"tag":25,"props":4081,"children":4082},{},[4083,4085,4092,4094],{"type":22,"value":4084},"This way, we can efficiently traverse our tree and return only relevant points. I decided to use ready implementation, as I don’t like reinventing the tree - thanks to ",{"type":16,"tag":56,"props":4086,"children":4089},{"href":4087,"rel":4088},"https://github.com/CodingTrain",[60],[4090],{"type":22,"value":4091},"The coding train",{"type":22,"value":4093}," for sharing his ",{"type":16,"tag":56,"props":4095,"children":4097},{"href":4096},"github.com/CodingTrain/QuadTree/blob/main/quadtree.js",[4098],{"type":22,"value":4099},"implementation",{"type":16,"tag":17,"props":4101,"children":4103},{"id":4102},"drawbacks",[4104],{"type":22,"value":4105},"Drawbacks",{"type":16,"tag":25,"props":4107,"children":4108},{},[4109],{"type":22,"value":4110},"Spatial partitioning can already take our Particle Life to another level, but it is far from an ideal solution. In the end, what limits us is the number of particles in the range that we need to test. If we want to keep things efficient, the radius needs to be small enough to contain a limited number of particles. This way, we create a zoomed-out, uniform version of the particle life. It’s an interesting optimization exercise, but nothing more. The more particles we want, the smaller the radius we need to set, and the less we see.",{"type":16,"tag":25,"props":4112,"children":4113},{},[4114,4116,4121],{"type":22,"value":4115},"What if we wanted to see how, let’s say, 100000 particles in range interact with one another? To achieve this, we need to think in a different way. Instead of sequentially calculating forces for every particle (which would require ",{"type":16,"tag":3973,"props":4117,"children":4118},{},[4119],{"type":22,"value":4120},"10 billion checks",{"type":22,"value":4122}," for every frame), let’s use the GPU to calculate force for every particle in parallel. So it happens that I was reading about the new webGPU API a few days ago, and I think it would be a nice programming experiment to implement our particle life this way.",{"type":16,"tag":17,"props":4124,"children":4126},{"id":4125},"further-considerations",[4127],{"type":22,"value":4128},"Further considerations",{"type":16,"tag":25,"props":4130,"children":4131},{},[4132],{"type":22,"value":4133},"If we were to continue developing our javascript implementation, there are more things we could do to optimize the code. Our system is very dynamic, and everything is moving with every frame, forcing us to reconstruct the tree. It happens to be quite an expensive operation.",{"type":16,"tag":25,"props":4135,"children":4136},{},[4137],{"type":22,"value":4138},"To further improve this, we could draw from data structure used in computer simulations, verlet list. Instead of querying particles within a maximum interaction radius, we add a padding of X%. Then, we consider how many repeated position updates we can calculate before particles move outside of our adjusted radius. This way, we can rebuild our quadtree not on every frame, but once in every few frames. The tricky part is finding a balance between an increased radius (and hence more particles to loop over) and the frequency of rebuilding the quadtree. This will vary depending on our system parameters.",{"type":16,"tag":17,"props":4140,"children":4142},{"id":4141},"particle-life-online",[4143],{"type":22,"value":4144},"Particle Life online",{"type":16,"tag":25,"props":4146,"children":4147},{},[4148,4150,4157,4159,4165],{"type":22,"value":4149},"I deployed my code to ",{"type":16,"tag":56,"props":4151,"children":4154},{"href":4152,"rel":4153},"https://webgpulife.netlify.app/",[60],[4155],{"type":22,"value":4156},"Netlify",{"type":22,"value":4158},", where you can play with an unoptimized JS version, quadtree enhanced code, and webGPU 3D particles. Remember to increase the parameters carefully if you’re not on a good machine, otherwise your browser will freeze. The code is available ",{"type":16,"tag":56,"props":4160,"children":4162},{"href":58,"rel":4161},[60],[4163],{"type":22,"value":4164},"here",{"type":22,"value":391},{"type":16,"tag":25,"props":4167,"children":4168},{},[4169],{"type":22,"value":4170},"See you in the next part, where I’ll take things to the next level by implementing and optimizing the webGPU version!",{"type":16,"tag":25,"props":4172,"children":4173},{},[4174],{"type":16,"tag":56,"props":4175,"children":4177},{"href":4176},"/articles/optimizing-the-article-life-millions-of-particles-with-webgpu",[4178],{"type":22,"value":4179},"See the next part",{"type":16,"tag":4181,"props":4182,"children":4183},"style",{},[4184],{"type":22,"value":4185},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":164,"depth":164,"links":4187},[4188,4189,4190,4191,4192],{"id":19,"depth":164,"text":23},{"id":3958,"depth":164,"text":3961},{"id":4102,"depth":164,"text":4105},{"id":4125,"depth":164,"text":4128},{"id":4141,"depth":164,"text":4144},"markdown","content:articles:optimizing-the-particle-life-javascript-quadtree.md","content","articles/optimizing-the-particle-life-javascript-quadtree.md","articles/optimizing-the-particle-life-javascript-quadtree","md",1792947343181]