This module contains two distinct methods for:

  1. Particle visualisation
  2. Coarse grained data visualisation

These methods both leverage three.js to render the visualisations in the browser. Visualisation options are controlled by setting the URL of the browser correctly.


To be able to view local data, that data needs to be served from a local server. This can be done by using the TexturingServer described elsewhere, or if no texturing is needed, two lightweight servers are included that work under Python or JS:

TexturingServer method

Follow the instructions to compile the TexturingServer.

JS Method

  1. Install node.js. Try sudo apt-get install nodejs (tested with node.js v11.13.0)
  2. Install required packages by running npm install express cors glob

Python method

This should work under python2 or python3, with no additional dependencies, so as long as you have either of these installed on your system you have no need to install anything


  1. Navigate to the main github directory and run node server.js or python or ./Texturing/TexturingServer to start a web server which will be used to serve local files.
  2. Open visualise/index.html in chrome or firefox. Supermedium is recommended if you want to use VR.
  3. Visualisation flags can either be hardcoded in index.html or can be set via the URL, for example: index.html?fname=Samples/SpinnerD5/&view_mode=rotations


  • fname: folder name where data is stored. Trailing slash is optional. Default is Samples/D4/
  • display_type: VR, keyboard or anaglyph. Default is keyboard.
  • view_mode: undefined (normal and default), catch_particle, rotations, rotations2, velocity or rotation_rate. rotations requires the TexturingServer to be running and works in any number of dimensions. rotations2 can be computed in the browser, and can be used with any server, and does the calculations on the GPU at render time, but only works for N = 3 or 4.
  • autoplay: true or false to start time marching on load. Default is false.
  • rate: float that sets the speed of time marching. Units are DEM time units\second. Default is 5.0.
  • shadows: true or false to render shadows. Default is true.
  • quality: int to set quality of rendering. Higher is more compute expensive. Default is 5.
  • zoom: float to set how much to zoom in. Default is 20.
  • pinky: only used if view_mode is catch_particle. int that sets which particle to render in pink. Default is 100.
  • cache: true or false to cache local data in the browser. Default is false.
  • hard_mode: true or false to disable tori in VR mode to make things harder for the user. Default is false. This is meant to be more 'fun' but YMMV.
  • no_axes: include this flag to disable drawing of axes.
  • no_walls: include this flag to disable drawing of walls.
  • quasicrystal: true or false to view in quasicrystal mode. Default is false.
  • mercury: true or false to load MercuryDPM data instead of NDDEM data. Default is false.
  • colour_scheme: set to inverted to invert global colour scheme to have a white background.
  • rotate_torus: float to rotate the torus around the x1 axis in degrees
  • record: true or false to save frames when autoplay is ticked. Default is false.
  • initial_camera_location: three numbers (e.g. initial_camera_location=1,2,3) to set the initial camera location if so desired.
  • camera_target: three numbers (e.g. camera_target=1,2,3) to set what the camera is pointing at if so desired.
  • t0: float to set the initial timestep to display. Default is 0.
  • binary: if included, this flag loads from binary data instead of csv data. You can convert csv to binary data using the included script in the scripts folder.

An example command that works for me, when the TexturingServer is running: /path/to/index.html?fname=D5Cristal/&view_mode=D4&colour_scheme=inverted&time=350&rate=5&display_type=keyboard

Particle visualisation

Below is the default output of the visualisation software for a 3D simulation of spheres flowing down an inclined plane. You can manually move through time, or enable auto playing in the top right. The speed it is playing can be controlled with the "Rate" parameter.

Getting around in ND

But what about dimensions higher than 3? For this, we need some way to project particles from higher dimensions down to 3D. In this example, we will project a 3D sphere down to a 2D circle by slicing it. Move the pink plane on the left around with the slider and see the resulting size of the circle on the right. The circle is largest when the sphere is sliced through its centre.

Now, lets try that same thing, but we are going to slice a 5D hypersphere with a 3D volume. For this, there are two coordinates for where we are slicing, which you can control with the sliders. The torus on the right hand side represents where we are in these two dimensions. Notice how as you move around, the small pink ball moves. This small pink ball represents the location of the hypersphere relative to these two coordinates. The sphere on the left is again largest when we slice through its centre — when the ball is at the centre of the black cross

Let's now go and look at inclined plane flow in 5D

Particle rotation

To be able to see a particle rotate, we need to attach a texture to it. Here is how we visualise the earth rotating.

In 3D, there are three directions that an object can rotate in.

As we can't render the textures needed to do this without a local installation, here is a video explaining how rotations work

Trying out VR (this will look blank if you don't have a VR headset attached)

Coarse grained data



Initialise the threejs scene, adding everything necessary, such as camera, controls, lighting etc.



Get the current orientation of the left hand controller and set world coordinates appropriately



Get the current orientation of the right hand controller and set world coordinates appropriately



Add the left oculus controller

add_left_oculus_model(controller: number)
controller (number) controller number (0 or 1)


Add the right oculus controller

add_right_oculus_model(controller: number)
controller (number) controller number (0 or 1)


Add the two vive controllers



Make the camera and position it



Add the renderer and associated VR warnings if necessary



Add the non-VR GUI and set all sliders



Add the non-VR and/or VR controllers and associated buttons



If the current example requires a specific direction for the camera to face at all times (e.g. a 1D or 2D simulation) then set that



Make the axes, including labels and arrows



Make the scene lighting



Make any necessary walls



Add the torus(es) as necessary



Remove everything from scene - very useful for presentation mode when we don't want to kill the computer by loading multiple scenes simultaneously



Make the initial texturing if showing rotations



Load particles from MercuryDPM file format - NOTE: THIS IS NOT WORKING YET



Make the initial particles



Load textures from TexturingServer

load_textures(t: number, Viewpoint: number)
t (number) timestep
Viewpoint (number) where we are in D>3 space


Update textures from TexturingServer

update_spheres_texturing(t: number)
t (number) timestep


Update sphere locations

update_spheres_CSV(t: number, changed_higher_dim_view: number)
t (number) timestep
changed_higher_dim_view (number) flag to determine if we have changed which dimensions we are representing --- NOTE: CURRENTLY NOT DOING ANYTHING


Update camera and renderer if window size changes



In catch_mode, let the user know if they found the pink ball



Animation loop that runs every frame



Do the actual rendering



Remove loading screen