Setting up the Three.js ellipsoids
Introduction
In the previous articles in this series we talked about:
- Part 1: Reading VTK format particles with Javascript in a browser
- Part 2: Saving the read-in particle data in a Vuex store
- Part 3: Initialization of a store and the user interface.
- Part 4: Setting up the Three.js renderer
- Part 5: Setting up the Three.js scene and camera
We are now ready to discuss the three-ellipsoid-particles
component that we introduced in
ThreeGraphicsPanel.vue
. Recall that the template has the following form:
The ellipsoid particles component
The file ThreeEllipsoidParticles.vue
also does not contain any information inside the
<template>
tags and contains the following:
However, the source code contains more - as you can see below.
There are several aspects that need consideration in this code.
We use the watch
“instance method” of Vuex to make sure that
the particles are added to the scene only after the particle file has been read.
In this example
we do not stop watching the variable particleReadComplete
(see Part 2 for details) after the particle data has been converted and saved. However, that step is highly recommended.
Creating the ellipsoid particles
The particle axis data are in the form of angles between the ellipsoid axes and the world coordinate axes.
These are converted directly into the appropriate rotation matrix. Sphere objects are then created at
the origin, rotated, scaled, and translated to their actual positions. The sphere objects are then
transformed into SphereBufferGeometry
objects to make their manipulation slightly more efficient.
Finally, a “material” shading model is added to make sure that the image displayed isn’t flat and
a triangulated mesh is generated for each object.
The rotation matrix performs a transformation of the form \(\hat{\mathbf{w}} = \boldsymbol{R} \cdot \mathbf{w}\,.\) We want to rotate the world coordinate vectors \(\mathbf{E}_1\), \(\mathbf{E}_2\), \(\mathbf{E}_3\), into vectors that are aligned with the ellipsoid axes, \(\mathbf{e}_1\), \(\mathbf{e}_2\), \(\mathbf{e}_3\). Therefore, we need to find a rotation matrix \(\boldsymbol{R}\) such that \(\mathbf{e}_\alpha = \boldsymbol{R}\cdot\mathbf{E}_\alpha\) where \(\alpha = 1,2,3\). Taking dot products of both sides with \(\mathbf{E}_\beta\), we get \(\mathbf{E}_\beta\cdot\mathbf{e}_\alpha = \mathbf{E}_\beta\cdot\boldsymbol{R}\cdot\mathbf{E}_\alpha = (\mathbf{E}_\beta\otimes\mathbf{E}_\alpha):\boldsymbol{R} \,.\) Now, \(\boldsymbol{R} = R_{mn} \mathbf{E}_m \otimes \mathbf{E}_n\). So we have \(\mathbf{E}_\beta\cdot\mathbf{e}_\alpha = R_{mn} (\mathbf{E}_\beta\otimes\mathbf{E}_\alpha): (\mathbf{E}_m \otimes \mathbf{E}_n) = R_{mn} (\mathbf{E}_\beta\cdot\mathbf{E}_m) (\mathbf{E}_\alpha \cdot \mathbf{E}_n) = R_{mn} \delta_{\beta m} \delta_{\alpha n}\). Therefore, \(\mathbf{E}_\beta\cdot\mathbf{e}_\alpha = R_{\beta\alpha}\).
Let us look at the ellipsoid axis vector \(\mathbf{e}_1 = \mathbf{e}_a\). This vector has components \((e_{11}, e_{12}, e_{13})\) where \(e_{11} = \mathbf{e}_1 \cdot \mathbf{E}_1 = R_{11}\), \(e_{12} = \mathbf{e}_1 \cdot \mathbf{E}_2 = R_{21}\), and \(e_{13} = \mathbf{e}_1 \cdot \mathbf{E}_3 = R_{31}\). That is why we can create the rotation matrix directly from the axis data in the code sample.
Remarks
A plot of the ellipsoids produced by our code can be seen below.
In the next part of this series we will explore how vtk.js
can be used to do the same plot.