Mathematics of 3D Graphics
Last updated
Last updated
A basic understanding of mathematical concepts is necessary to script anything that is a bit more complicated. This section will put together a short review as well as MaxScript specific examples
3DS Max has a bit of wierd looking coordinate system... on first glance it seems like its left handed with Z pointing up instead of Y. However, this is not actually the case. 3DS Max is actually right handed but they define the floor on the XY plane as opposed to the XZ plane
A point describes a position in 3D space and is represented by an x,y and z value.
A vector in 3D space describes a motion and is also represented by an x,y and z value.
Suppose you have two points in A and B. If you took the positions of A and subtracted from B, you will get a vector that tells you how to move from A to B, (a direction and how far to go).
All the 3D transform functions you use essentially apply vector math to your object(s) in some manner.
To translate(move) an object to a new position, you can represent the movement as a vector. The move function adds the vector representing the movement to the position (a point) to get a new point.
For example:
Let be the point (1,1,1). Let be the point (2,1,3) then: is the vector that will translate from A to B. That is:
To scale an mesh we multiply each vertex of the mesh by a scalar value (a single number). Any number larger than 1 will make the object bigger. Any number smaller than 1 will make the object smaller.
To rotate an object, we use the rotate function passing it the object to rotate and any one of a number of possible rotation delta objects. Valid rotation delta object types are:
Eulerangles
Angleaxis
Quaternion
Eg, using a eulerangles
rotation delta:
Eulerangles objects are the simplest rotation representation. x y z
can be any degree angle values. An eulerangles
object as we see above will rotate an object first on the world x axis, second on the world y axis, then finally on the world z axis. Positive values will rotate in a counterclockwise direction around an axis if you imagine the axis arrow pointing out of the clock face.
Eg, assuming mybox
is a box object:
The above code segment would rotate mybox
45 degrees on the x axis first, 30 degrees on the y axis second, then finally 60 degrees on the z axis.
Please see the maxscript documentation on node transformations for more information.
Quaternion objects offer powerful rotational attributes that may be useful for LSystems though they are more complex and their implementation in MAXScript has some caveats. We explore Quaternions in their own section.
Trigonometry is the study of triangles (relationships between lengths and angles of triangles). In this section we will breifly go over some things that you may have forgotten about trigonometry that you might find useful.
Consider the above right angle triangle.
Let represent the angle at A
We define the following
Based on Pythagorean Theorem we know that
Now consider the following diagram of a unit circle:
The line from the origin to any point on a unit circle is going to have the coordinate value of .
A vector is a coordinate that represents a position in space. In MAXScript, vectors are implemented through point2 and point3 objects. Most frequently, you will be dealing with point3 objects.
A vector is composed of 1 component for each dimension in their respective space. Each component represents a specific point in that respective dimension. For example, the x component in a vector indicates the position of the vector in the x dimension. Image 1 above shows a 2-dimensional (2D) vector that lies at the coordinate (5, 2) (that is, 5 on the x and 2 on the y).
In MAXScript, vectors are implemented through the point2 and point3 objects. Point2 objects represent a 2D vector that has 2 components, an x and a y. In MAXScript, these are constructible via the square braces syntax.
Eg:
The code segment above constructs a point2 object with x value 50 and y value 75.
Similarly, we can construct point3 objects. Eg:
The code segment above constructs a point3 object with x value 25, y value 50, and z value 75.
Point2 and point3 objects share most operations. For the remainder of this document, the focus will be on point3 objects.
We can access the components of a vector via their component names. Eg:
Vectors can perform basic mathematical operations, eg:
Vectors can also be scaled by a float, eg:
The length of a vector is the distance from the origin (the point zero on all dimensions) to the tip. We can find the length of a vector by calling the length function. Eg:
The direction of a vector is the direction from the point of origin to the tip of the vector. A pure direction vector is a vector whose length is 1; we call this a normalized vector or a unit length vector. For example, the vectors [10, 0, 0] and [1, 0, 0] share the same direction but have different lengths; [1, 0, 0] is a unit length vector while [10, 0, 0] is not. To get a normalized vector from any non-zero length vector, we call the normalize function.
Eg:
A quaternion represents an angular rotation around an axis; or more technically, the rotational transformation of a space from one frame of reference to another.
In practical terms, a quarternion gives us a way to rotate a vector around an axis by some angle. Quarternions do not suffer from gimble-lock.
A quarternion can be constructed as an angle and an axis of rotation or by casting other rotation objects. It is not important for us to understand the internal math involved with using quaternions. Instead we only care here about its application to rotations.
In MAXScript, quaternions are implemented through the Quat
class.
We can construct a quat by passing an amount of degrees and an axis of rotation to the class constructor or by casting any other rotation object to a quat as seen above.
Eg:
In the above code segment, we construct the quats q1 and q2 representing the following:
q1 represents a rotation of 30 degrees around the z axis
q2 represents the same rotation as the casted eulerangles object, which in this case amounts to 30 degrees around the x axis
Note: When constructing a quaternion from an angle and axis, be sure that the axis vector is normalized (See vectors article).
A quaternion object can be used to rotate objects and vectors. We will look at both capacities.
A quaternion has 4 components, x, y, z, and w. Each is a floating point value. The components of a quat must follow a long list of very specific rules that are beyond the scope of this course. Quaternions overall are complex objects so accessing their raw component values is not very useful. Most of the time, we will use quats as black boxes that we can construct using their angle axis constructor or using a cast. Using the listed high level operations on a quat allows us to make use of them without having to understand the theory behind them.
To rotate an object using a quaternion, we use the rotate function. Eg:
We can get a rotated vector by multiplying a point3 by a quat. Eg:
Note: Due to issues with MAXScript's implementation of quats, vector rotation is clockwise while object rotation is counterclockwise. For a workaround, see the Implementation Issues section.
An identity quaternion is the default quaternion that performs a zero rotation on objects and vectors ie it does not rotate them. Mathematically, this is similar to multiplying a number by 1. The identity quat has the following special component values:
x = 0, y = 0, z = 0, w = 1
To construct this quaternion, we use the 4 element quat constructor. Eg:
Rotations can be appended by using the operator. The resultant quaternion represents the rotation induced by applying the quat on the right first then the quat on the *left second. Eg:
In the above code segment, mybox and mybox2 were ultimately rotated by the same amount.
A useful aspect of quaternions is that we can get the negative of a rotation (the opposite rotation) by inversing the rotation quaternion. This is useful since quaternions can be made to hold complex rotations where creating the opposite rotation could be difficult. This is not possible with eulerangles objects. Eg:
MAXScript's implementation of quaternions is slightly problematic. The biggest issue is that a quaternion will rotate a vector clockwise around an axis while it will rotate a geometric object counterclockwise around an axis. This will be an issue if your algorithm needs to rotate vectors and objects by the same quaternion; for example, if you need to rotate an object and also update a heading vector.
To solve this problem, we need to rotate either the vector OR the object by an inverse copy of the quaternion used to store overall rotation.
Note: This must be done consistently or else you will produce incorrect results!
Ex: