Vector3 in three.js for points in space
In Vector space a Vector can be used to represent position, but they are usually described as having magnitude and direction. In threejs the Vector3 class is a class that is used to create an instance of a Vector that has three values, x, y, and z. This Vector3 class is then a major class of interest then when it comes to working with all kinds of various other classes, methods, and features of threejs. One major feature of interest in the Object3d class is the position property of the Object3d class. The position property stores an instance of Vector3, and that instance can be used to set the position of anything that is based off of Object3d like a Mesh, Camera, Group, or a whole Scene object actually for that matter.
Although an instance of Vector3 can very much be used to set a position of something it can also very much be used to set the direction of something also. This is where things might be a little confusing because when it comes to setting the orientation of something based off of Object3d there is the rotation property. This rotation property is not an instance of Vector3, but an Instance of the Euler class. This Euler class is similar to that of Vector3, but the values given are in radians, and is then a more appropriate way of setting orientation of an object by rotating on the x, y, and z axis by given angles in the from of radian values. However there is also the concept of a unit vector that would be in the form of a normalized instance of Vector3 oddly enough. So then Vector3 can be used to set position, but it can also be used as a way to set orientation in the from of a direction using values between 0 and 1 for each axis.
This post is then about the Vector3 constructor that is a useful class for various things in a three.js project. A 3d Vector3 Instance consists of an x, y, and z value which makes it useful for plotting a single point in 3d space, but these values can also be in the range of numbers between 0 and 1 which can then be raised by a multiplier, and in some ways can be translated to angles and directions that have to do with the rotation of an object rather than its position. There are all kinds of use cases that will come up here and there for Vector3 such as finding Euclidean distance via the length method of the Vector3 instance, which is the distance from the vector to the origin for example.
This will be a fairly lengthy post then as there is a lot of going to cover with this one, nut just when it comes to the class itself, bit how it can be applied when it comes to everything else there is to work with in threejs.
The THREE.Vector3 class and What to know first
Threejs version numbers matter a lot.
Threejs is a project where the version number matters a lot, more so then what you might have grown accustom to when it comes to other libraries. When I first wrote this post I was using r91 of threejs, and the last time I got around to doing a little editing of this post I was using threejs r135 with the later examples that I am keep at the top of this content. I still have older examples here that i am now pushing down to the bottom of this text, and the latest version that I am using with them is r111, those code examples will break in late versions of threejs.
When I edit I generally make an effort to keep the newer examples to the top of the page, and leave the older examples towards the bottom for the sake of historical reasons, and for the off chance that one might be using an older version of threejs for one reason or another.
The source code examples in this post are on Github
I have a for post folder set up in my test threejs repository on Github where I will be keeping the source code examples for this post, as well as for my many other posts on threejs.
There is also the Euler class for angles
In the introduction of this post I mentioned the Euler class which is like Vector3 only it deals with angles rather than a position. Like that of the Vector3 class a Euler class also has x, y and z properties, but the expected value range is in radians rather than just any number value. The y value for a Euler instance then has to do with the angle at which an object should be rotated on the y axis rather than the position of an object along the y axis.
Check out arrow helpers also
There is a built in helper class in threejs called the THEE.ArrowHelper that can be used to create and add a helper to a scene that will show the direction of a vector. This can be very useful to find out what the current state of affairs is with a single Vector3 class, and there are also many other useful helpers like that of the arrow helper.
1 - Basic example of a THREE.Vector3 class instance
There are only 3 public properties of a Vector3 instance that are of interest which are of course is the x , y, and z properties of the Vector3 object that is returned when calling the constructor. To my knowledge there are only four properties in total, the fourth being the isVector3 property which should always be true. Every thing else of interest in a Vector3 instance is a method, such as the length method that will give the current Euclidean distance, or distance from the origin.
2 - Basic example of the Vector3.set method
Setting the values of a Vector3 instance can be done by just setting the values directly, that is the I can just set a desired number value to say the x property of the instance. However there is also the set prototype method of the class that can be called off of an instance of vector3 and then values can be passed by way of the arguments of the set method.
One of the many use case examples of the set method is to just use it as a way to change the position of a Mesh object, or any object based off of the Object3d class such as a Camera. The position property of anything based off of the Object3d class is an instance of the Vector3 class, and as such has the set method in the prototype as a way to go about setting the values for that instance.
3 - Set objects in a circle around the center of a group example of Vector3.set
In this example I will once again be using the set method to set the position of objects, this time it is a collection of mesh objects that are children of a group, and they will be positioned in a circle like formation. Speaking of groups that is yet another feature of threejs that will come into play a lot when I want to make two or more instances of Mesh objects, or any kind of Object really that is based off of Object3d children of another Object that can then be moved and rotated and when doing so effects all children of that Object.
4 - Setting objects onto the surface of a sphere example of the Vector3 set method
Now for a more advanced example of the Vector3 set method that might help one to gain a better understanding of how a vector can be used for positioning things with an example that has to do with position one mesh onto the surface of a another mesh object that is a sphere.
This should not be thought of as any kind of definitive solution for this sort of thing, there are a lot of ways of going about doing this, as such I have wrote a project example post that is detected to this topic that I revise from time to time with other solutions some of which might prove to be better for other specific cases.
5 - Object3d and vector3
A very important base class in three.js is the Object3D class that is at the hart of many objects in threejs. Constructors such as Camera, Mesh, Group, and many more inherit from the base Object3d class. The reason why I bring this up is because there are a few properties in this base class the expect an instance of Vector3. Manly the Object3D.position, and Object3D.scale properties, so in this example I will be going a quick example of using the Object3d class, and also methods of the Vector3 class such as the copy method that can be used to copy the values of one instance of vector3 to another.
Because Vector3 is the constructor that is used to represent a point in 3d space in three.js, it’s use is to be expected in any situation in which its use is appropriate. Therefor it pays to have a solid foundational understanding of this constructor.
6 - Adding, diving, and multiplying Vectors
Vectors can be added together with the add method, which is pretty straight forward. There are also methods for diving, and multiplying as well that can often prove to be useful in various types of situations. These kinds of methods can then also be used in conjunction with many others in a chain. For example I can use the set method as a way to just define a kind of direction that I want and when doing so I can use any values that i want to do so assuming that I then normalized this, then I can use the multiply scalar method to set the desired length or magnitude with that set direction.
I will want to write more about normalization of vectors later in this post in at least one if not more examples as this is a very impotent concept to understand when it comes to working out all kinds of problems that one will run into with vectors. For now the basic idea is that it will turn a vector like 0,0,3 into 0,0,1 which I can then use with multiply scalar with a value of 6 to get 0,0,6.
7 - Finding the distance between two vectors.
The length method of Vector3 returns the distance from the origin, but what if I want the distance from one instance of vector3 to another that might not be the origin then I will want to use the distance to method of the vector3 class.
8 - Clone, and Copy
If I want to make an independent copy of a vector I can use the clone method which will return a whole new instance of vector3 with the same values of the instance of vector3 that I called the method off of. I can then mutate this new instance of vector3 without mutating any of the values of the source instance that I call the clone method off of. There is also a copy method but that is not use to create a copy of a vector3 like clone does, but rather copy the values of one instance of vector three into another, so then the copy method can be used as an alternative to the set method that involves setting an instance of vector three with another instance of vector3 rather than that of number values.
9 - Normalize a Vector
Normalizing a vector will keep the direction from the origin the same, but change its distance from it to a unit vector of just one. From there it additional methods like the of the multiply scalar method can be used to set any desired length alone that same direction. For example I can create a mesh and place it at a given position, I can then use that mesh position with methods like the copy method to set a whole much of mesh objects to the same position as that mesh, but then normalize, and then use multiply scalar to set each mesh on its own position that is the same direction, but with different unit lengths.
Old EXAMPLES ( r111 and before ) that make use of the Geometry constructor
When I first wrote this post I was using r91 of threejs, and the last version of threejs that I was using in my test threejs repository before the Geometry constructor was removed was r111. Last time I cam around to do a little editing with this post version r111 is still the latest version of threeejs that I was using to get these examples to work, they will break in late version of threejs that not longer have the Geometry constructor built in.
Create Geometry Vertices with Vector3
Although I will not be getting into making custom geometry in detail, doing so will often involve the use of Vector3 to create the array of vertices. The faces will then reference them by the index value of the vertex in the vertices array of the geometry.
Making Lines with Vector3
Read my full post on lines.
So now that you have at least the basic idea of Vector3 down, another typical use example of the use of Vector3 is to make lines. There are a number of ways to make 3d, and 2d lines in threejs. However maybe the most important way to do so is with the Line constructor.
Doing so is not so different from making a custom geometry that will be used in a material that renders faces. The main difference is that you only really have to work about the array of verticies, and not at all about the faces if there is not going to be any. There are two special materials that can be used with the Line constructor that are in place for this purpose that do not make use of faces, and are there purely for lines only.
Changing a Vector3 value in a geometry
This can be done by having a reference to the vertex that you want to change, and then just go ahead and change it’s position with the set method, or any other method that will have an impact on it’s values. When doing this the changes might not take effect with respect to the instance of geometry, so you will need to make sure that the verticesNeedUpdate property of the geometry is set to true.
It can go without saying that doing this can result in something that might eat up a lot of overhead, but is necessary from making things that mimic fabric, and the surface of water.
The Vector3 class is then a major class that will be used a whole lot in threejs projects, it is used as a way to go about setting positions of things in a scene, but the various methods are also used to set new positions by making use of tricks that have to do with the length of a vector. That is that there is knowing a thing or two about how a vector is not just position but also direction, and how the length of a vector can be adjusted without changing the direction.
It is not to say there are not a whole lot of other classes in threejs that are not a bit deal also. Another major class that I often look into now and again when I spend a little to much time away from threejs is the Euler class, and the object3d class. The Euler class has more to do with the rotation of objects, but there is also ways of converting from one to another. The object3d class is the base class of a mesh object, and as such in contains properties like the position property as well as the scale property both of which are instances of Vector3.