.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/04_demos/viz_brownian_motion.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_04_demos_viz_brownian_motion.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_04_demos_viz_brownian_motion.py:


======================================================================
Brownian motion
======================================================================
Brownian motion, or pedesis, is the random motion of particles
suspended in a medium. In this animation, path followed by 20 particles
exhibiting brownian motion in 3D is plotted.

Importing necessary modules

.. GENERATED FROM PYTHON SOURCE LINES 11-17

.. code-block:: Python


    import numpy as np
    import fury
    from scipy.stats import norm









.. GENERATED FROM PYTHON SOURCE LINES 18-37

Let's define some variable and their description:

* **total_time**: time to be discretized via time_steps (default: 5)
* **num_total_steps**: total number of steps each particle will take
  (default: 300)
* **time_step**: By default, it is equal to total_time / num_total_steps
* **counter_step**: to keep track of number of steps taken
  (initialised to 0)
* **delta**: delta determines the "speed" of the Brownian motion.
  Increase delta to speed up the motion of the particle(s). The random
  variable of the position has a normal distribution whose mean is the
  position at counter_step = 0 and whose variance is equal to
  delta**2*time_step. (default: 1.8)
* **num_particles**: number of particles whose path will be plotted
  (default: 20)
* **path_thickness**: thickness of line(s) that will be used to plot the
  path(s) of the particle(s) (default: 3)
* **origin**: coordinate from which the the particle(s) begin the motion
  (default: [0, 0, 0])

.. GENERATED FROM PYTHON SOURCE LINES 37-46

.. code-block:: Python


    total_time = 5
    num_total_steps = 300
    counter_step = 0
    delta = 1.8
    num_particles = 20
    path_thickness = 3
    origin = [0, 0, 0]








.. GENERATED FROM PYTHON SOURCE LINES 47-49

We define a particle function that will return an actor, store and update
coordinates of the particles (the path of the particles).

.. GENERATED FROM PYTHON SOURCE LINES 49-74

.. code-block:: Python



    def particle(
        colors,
        _origin=origin,
        _num_total_steps=num_total_steps,
        _total_time=total_time,
        _delta=delta,
        _path_thickness=path_thickness,
    ):
        _origin = np.asarray(_origin, dtype=float)
        position = np.tile(origin, (_num_total_steps, 1))
        path_actor = fury.actor.line([position], colors=colors, linewidth=_path_thickness)
        path_actor.position = position
        path_actor.delta = _delta
        path_actor.num_total_steps = _num_total_steps
        path_actor.time_step = _total_time / _num_total_steps
        path_actor.vertices = fury.utils.vertices_from_actor(path_actor)
        path_actor.no_vertices_per_point = len(path_actor.vertices) / _num_total_steps
        path_actor.initial_vertices = path_actor.vertices.copy() - np.repeat(
            position, path_actor.no_vertices_per_point, axis=0
        )
        return path_actor









.. GENERATED FROM PYTHON SOURCE LINES 75-76

The function `update_path` will simulate the the brownian motion.

.. GENERATED FROM PYTHON SOURCE LINES 76-91

.. code-block:: Python



    def update_path(act, counter_step):
        if counter_step < act.num_total_steps:
            x, y, z = act.position[counter_step - 1]
            x += norm.rvs(scale=act.delta**2 * act.time_step)
            y += norm.rvs(scale=act.delta**2 * act.time_step)
            z += norm.rvs(scale=act.delta**2 * act.time_step)
            act.position[counter_step:] = [x, y, z]
            act.vertices[:] = act.initial_vertices + np.repeat(
                act.position, act.no_vertices_per_point, axis=0
            )
            fury.utils.update_actor(act)









.. GENERATED FROM PYTHON SOURCE LINES 92-93

Creating a scene object and configuring the camera's position

.. GENERATED FROM PYTHON SOURCE LINES 93-105

.. code-block:: Python


    scene = fury.window.Scene()
    scene.background((1.0, 1.0, 1.0))
    scene.zoom(1.7)
    scene.set_camera(
        position=(0, 0, 40), focal_point=(0.0, 0.0, 0.0), view_up=(0.0, 0.0, 0.0)
    )
    showm = fury.window.ShowManager(
        scene=scene, size=(600, 600), reset_camera=True, order_transparent=True
    )









.. GENERATED FROM PYTHON SOURCE LINES 106-107

Creating a list of particle objects

.. GENERATED FROM PYTHON SOURCE LINES 107-121

.. code-block:: Python


    l_particle = [
        particle(
            colors=np.random.rand(1, 3),
            _origin=origin,
            _num_total_steps=num_total_steps,
            _total_time=total_time,
            _path_thickness=path_thickness,
        )
        for _ in range(num_particles)
    ]

    scene.add(*l_particle)








.. GENERATED FROM PYTHON SOURCE LINES 122-123

Creating a container (cube actor) inside which the particle(s) move around

.. GENERATED FROM PYTHON SOURCE LINES 123-129

.. code-block:: Python


    container_actor = fury.actor.box(
        centers=np.array([[0, 0, 0]]), colors=(0.5, 0.9, 0.7, 0.4), scales=6
    )
    scene.add(container_actor)








.. GENERATED FROM PYTHON SOURCE LINES 130-131

Initializing text box to display the name of the animation

.. GENERATED FROM PYTHON SOURCE LINES 131-137

.. code-block:: Python


    tb = fury.ui.TextBlock2D(bold=True, position=(235, 40), color=(0, 0, 0))
    tb.message = "Brownian Motion"
    scene.add(tb)









.. GENERATED FROM PYTHON SOURCE LINES 138-139

The path of the particles exhibiting Brownian motion is plotted here

.. GENERATED FROM PYTHON SOURCE LINES 139-152

.. code-block:: Python



    def timer_callback(_obj, _event):
        global counter_step, list_particle
        counter_step += 1
        for p in l_particle:
            update_path(p, counter_step=counter_step)
        showm.render()
        scene.azimuth(2)
        if counter_step == num_total_steps:
            showm.exit()









.. GENERATED FROM PYTHON SOURCE LINES 153-154

Run every 30 milliseconds

.. GENERATED FROM PYTHON SOURCE LINES 154-161

.. code-block:: Python



    showm.add_timer_callback(True, 30, timer_callback)
    showm.start()
    fury.window.record(
        scene=showm.scene, size=(600, 600), out_path="viz_brownian_motion.png"
    )



.. image-sg:: /auto_examples/04_demos/images/sphx_glr_viz_brownian_motion_001.png
   :alt: viz brownian motion
   :srcset: /auto_examples/04_demos/images/sphx_glr_viz_brownian_motion_001.png
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (12 minutes 45.001 seconds)


.. _sphx_glr_download_auto_examples_04_demos_viz_brownian_motion.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: viz_brownian_motion.ipynb <viz_brownian_motion.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: viz_brownian_motion.py <viz_brownian_motion.py>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_