Normalizing Vectors in threejs
The Vector3 class in threejs has many prototype methods one of which is the Vector3 normalize method. Calling the normalize method of a Vector3 instance will preserve the direction of the vector, but it will reduce the distance of the vector from the origin to a vector unit length of one.
A Vector with a euclidean distance of one is often referred to as a unit vector, and what is nice about this kind of vector is that it can quickly be scaled up by just simply multiplying the values of the normalized vector by a desired magnitude that is any value other than one to result in any vector that is along a given line that is the direction of the vector.
Vectors are often described as being a unit of direction, and magnitude, the direction can be thought of as what the normalized vector is in terms of numbers between 0 and 1 for x, y, and z. This direction can then be raised outward, or lowered, by a magnitude to get any point along a ray. So then in this post I think I will be going over some basic examples of the normalize method, and while I am at it also end up writing about a few other topics that are closely related to the normalize method.
Normalizing Vectors and what to know before hand
This is a post on using the Vector3 normalize method, and other related features in the javaScript library know as threejs. There are a great number of things that you should be aware of before continuing to read this. For one thing this is not any kind of getting started type post on threejs let alone javaScript in general. However in this section I will be going over a few key details that you might want to read up on more in detail in order to gain a better understanding of what the Vector3 normalize method is all about.
You might want to read up more on Vector3 in general
There is checking out my main post on the Vector3 class where I am going over the Vector3 class in general. Normalizing a Vector is a major part of becoming proficient with the Vector3 class, but there is a great deal more to it when it comes to the basics of Vector3, as well as other various methods of the class.
The thing to keep in mind here is that the normalize method will just set the length of a vector to one, while preserving the direction of the Vector, but that is it. What if I want to set direction of a Vector by a set of given angles in terms of radians or degrees for example? I will be going over some additional methods other than just the normalize method here, but you might still want to read more on theclass in general, and maybe some posts on other vector3 class features.
Source code is also up on GitHub
On my GitHub account I have a repository in which I am parking all the source code examples for my various posts on threejs including this one. With that said all the examples here can be found in my test threejs repository on Github.
Version Numbers matter
When I first wrote this post I was using r127 of threejs which was a late version of threejs as or min 2021, and the last time I came around to do some editing all the demos are updated to my r146 style rules.
I have made a habit of mentioning what version of threejs I am using when writing new threejs posts, and also add a section like this to older posts when I get around to doing a little editing. Maybe this is something that I should do with just about any javaScript library actually, but threejs seems to be moving along real fast compared to other javaScript projects where development is very slow.
1 - Some Basic examples of Vector3 normalize
Like with all my other posts on threejs I like to start out with some very basic getting started type examples of the threejs feature. In this case the normalize method of the Vector3 class. So these examples will just involve static scenes, and I will be doing my best to not go to overboard with the over all volume of code. The focus here thine will mainly be just on the vector3 method itself, and to a lesser extent other closely related features.
1.1 - Getting started with the normalize method
For this first example I just want to normalize a vector and that is it. However in order to have something to look at I will need to still set up the usual collection of objects when it comes to the scene object, camera, and renderer. After that I create an instance of Vector3 and when doing so I can set any values that I want when it comes to the position. Tokeep things simple I am going to start with a position like 0,0,18 and after calling the normalize method of this new vector I end up with a position of 0,0,1.
|
|
1.2 - Using multiply scalar
There is also how to raise the unit length of an instance of THREE.Vector3. With that said I once again start out with a vector3 that is not normalized, and then just call the normalized method of the Vector3 instance to get a normalized vector. Once the vector is normalized I can call a method like multiply scalar off of the normalized vector to set any desired magnitude, or distance if you prefer while preserving the direction of the Vector. This is the main thing about the normalize method, it will convert a vector to a unit length of one, and then from there it is very easy to increase the unit length.
|
|
1.3 - Using the apply Euler method to change direction
So the multiply scalar method can be used to set the unit length after it has been normalized. However there is also the question of how to change the direction as well. Another great vector3 class method for this would be the apply Euler method.
|
|
1.4 - Some more on the concept of vector length
The normalize method will set the length of any vector to a length of 1, and then from there the length can easily be adjusted to any desired length. Also when it comes to the subject of the length of a vector the Vector3.length method can be used to find out what the current length of any vector is. The normalize method combined with a method like multiply scalar can be used to set the length of a vector while the length method can be used as a way to get what that length is.
|
|
1.5 - The clone method of Vector3 while using normalize
The clone method is another vector3 prototype method that I think I should write about in this section as well, sense that is another method that I find myself using often when doing something with the normalize method. Simply put if I am ever in a situation in which I would just like to have a copy of a vector3 object that there is all ready there to work with I can call the clone method to get a new vector3 object with the same values from this preexisting vector3 object.
For example say that I have this source mesh object and I would like to create a whole bunch of new mesh objects around the local position of this source mesh. I can just call the clone method off of the position property of this source mesh object, then I can normalize it, and use additional methods like apply Euler and so forth. This will all be relative to the parent object of the mesh though, in this case the scene object, however I can then use the add method to add the position of the source mesh again to get things where I need them to be again.
|
|
2 - Placing an object on the surface of a sphere example
So then one use case example for all of this would be to work out one or more methods that have to do with positioning an object on the surface of a sphere. That is that I can create a method in which I can pass values that will be used to create any point in space, and then normalized that point to a vector with the same direction but with a length of one. I can then set the length of the normalized vector to the radius of the sphere, plus one half the height of the object that I want on the surface of a sphere. That basic method seems to work pretty well, and it is then just a question of making other methods that serve as an abstraction for that kind of method, such as a method where I can just give a lat and long value in terms of values between 0 and 1 for each argument a a way to position something on to a sphere. This will then also serve as a way to take some kind of system that involves positioning things on a grid and make it so that it can also be used to position the same things on a corresponding sphere surface.
|
|
This is the sort of thing that I find myself coming back to now and then when it comes to working out new systems for placing objects onto the surface of a sphere. I have a simple project example that I made a little while back in which I was able to work out a solution for doing this sort of thing but it was very different from this kind of example that I like better.
3 - Apply Euler example to change direction
There is normalizing a vector to a length of one, and keeping the direction, but what if I want to change the direction while I am at it as well on top of that? In other words what if I want some kind of helper function that will return a normalized vector, but I can also set the direction of that normalized vector with some angle arguments. In addition I can also set a length as a way to not return a normalized vector but a vector with an interested length, and also adjust what the starting vector is.
One way to make this kind of method would be to make use of the apply Euler method that can be used to change the direction of a vector by way of using some angles to do so. The apply Euler vector3 prototype method accepts radian values, but if I want to use degrees there is a deg to rad convince method in the math utils object. I will then just want a starting vector by which to use the apply Euler method with, and this vector should have a length greater than zero.
|
|
4 - Animation example
Now for an example that might help to really visualize what the deal is with normalization and unit length of vector3 instances. This example involves creating a group of groups where each end child node is a mesh object that uses the capsule geometry. I am then using buffer geometry and object3d class methods and properties to make it so that each capsule geometry of each mesh is alight in such a way that each end is between 0 and a fixed end vector unit length.
The general idea here is to pick a few directions and use the capsule geometry as a way to mark those directions. I can then make one or more mesh objects and have them move along one or more of the directions.
|
|
Conclusion
That will be it for now when it comes to the normalize method in the Vector3 class, but I am sure that I will come around to expand on this post at some point in the future when I have more to write about on this subject. There are many other methods in the Vector3 class that can be used with a normalized vector that I might get around to writing about sooner or later, but I need to get to working out some demos, and doing some more research first.
Never the less I think I did an okay job covering the basics of what a normalized vector is, now it is just a question of applying this to make some useful or interesting projects. Or improve some ones that I have made all ready, and I can think of a few that I would like to fix up now that I have a better understanding of this sort of thing.