Software is not magic; software is made by humans
Tags: Threejs, WebGL, JavaScript, glitch
Published: 2020-05-01 04:03:24

We did it! @harald3dcv and I solved the issues with having objects circling the globe in a nice easily readable fashion. See the post ["Animated GIFs of 3D Globes and Tilting the bar"]( https://dev.to/theoarmour/animated-gifs-of-3d-globes-and-tilting-the-bar-1gin ) for the problem we were trying to solve.  In the animation above, each bar was given a random height, latitude and longitude. You will note the the text and bar are nicely positioned, are always aligned vertically. Each bar is scaled individually but the every text element is scaled the same. And the best thing is that the frames per second are 60 fps on my win10 laptop with a GPU and still in the high 50s on my Samsung Galaxy Chromebook. So what was the magic?

The magic is all in this function:

``` JavaScript
      function getMatrixComposed(r = 50, lat = 0, lon = 0, height = 5) {
        const position = latLonToXYZ(r + 0.5 * height, lat, lon);
        const matrix = new THREE.Matrix4();
        const quaternion = new THREE.Quaternion().setFromRotationMatrix(
          matrix.lookAt(
            new THREE.Vector3(0, 0, 0),
            position,
            new THREE.Vector3(0, 0, 1)
          )
        );
        const scale = new THREE.Vector3(1, 3, height);

        matrix.compose(
          position,
          quaternion,
          scale
        );

        return matrix;
      }
```

The THREE.Matrix4().compose function sets the position, rotation and scale of any three.js object in a single line of code. In some ways it is elegant and simple. And in other ways maddening and complex. All of which is another way of saying: Welcome to the world of [linear algebra]( https://en.wikipedia.org/wiki/Linear_algebra )! ;-)

Linear algebra plays a huge role in the creation of interactive 3D graphics. My own skills in linear algebra would hardly fill a teaspoon. Thank goodness there are lots of [shoulders of giants to stand]( https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants ) on and build upon. Three.js takes care of the core of the issues. There are hundreds of [three.js examples]( https://threejs.org/examples/#webgl_animation_cloth ). Among the examples there is likely to be a demo of what you are looking for.

On occasion there is a new problem - like the one above. So Harald and I spent a good amount of time looking at the three.js math library.  The three.js math library is a treasure. It is fairly well documented. Here are two pages I look at a lot:

* https://threejs.org/docs/#api/en/math/Matrix4
* https://threejs.org/docs/#api/en/math/Vector3

And when I am really in trouble, I look at the very readable source code:

https://github.com/mrdoob/three.js/blob/master/src/math/Vector4.js

Here is the good news: In this day and age most of the problems you will encounter have been solved already. If you cannot find the answer it is probably because you did not identify the correct search terminology.

So why did Harald and I spend two hours in battle with a 4x4 matrix this morning? In two hours we might have been able to find a dozen examples of similar solutions to our problem.

One reason is because solving linear algebra problems is so mentally challenging. The problems are tough, take a lot of thought and there are lots of fails. But then there is that ["Eureka!"]( https://en.wikipedia.org/wiki/Eureka_(word) ) - I have found it - moment. The thing you have been dreaming about appears on the screen and you know you have found the right answer.

You are then reminded that software is not magic, that software is made by people. You have turned something you imagined into something that is now real, useful and shareable. You are a good human.

Enough chit-chat for now. Have a look at the source code on Glitch. Click on the "addMeshGeometryInstanced" button and watch a hundred items of text pop up on your screen. 

{% glitch theo-2020-04-globe-template app %}

The happy thing is that this is beginning to turn into a nice project - to create and maintain a template on Glitch of a script that create a nice interactive 3D globe. More on this idea in the next post. In the meantime be happy that things are looking up just the way we wanted.