mitm001 пре 5 година
родитељ
комит
723a0496fe
2 измењених фајлова са 782 додато и 926 уклоњено
  1. 0 802
      docs/modules/ROOT/pages/jme3/math.adoc
  2. 782 124
      docs/modules/tutorials/pages/intermediate/math.adoc

+ 0 - 802
docs/modules/ROOT/pages/jme3/math.adoc

@@ -1,802 +0,0 @@
-= Introduction to Mathematical Functionality
-:author:
-:revnumber:
-:revdate: 2016/03/17 20:48
-:relfileprefix: ../
-:imagesdir: ..
-ifdef::env-github,env-browser[:outfilesuffix: .adoc]
-
-
-It's a fact of life, math is hard. Unfortunately, 3D graphics require a fair bit of knowledge about the subject. Fortunately, jME is able to hide the majority of the details away from the user. Vectors are the fundamental type in the 3D environment, and it is used extensively. Matrices are also a basic necessity of 3D for representing linear systems. <<jme3/quaternion#,Quaternions>> are perhaps the most powerful and complicated of the basic types and are used for rotation in jME.
-
-I'll discuss how these are used in the system for the core functionality. Including Transforming, Visibility Determination, Collision Detection, and the Coordinate System. Note, that these are low level details. Further chapters will discuss how to use these various systems from a high level perspective.
-
-To get a visual introduction to math in jME3 for the absolute beginner, check out our <<jme3/math_for_dummies#,Math for Dummies>> introduction class.
-
-
-== Coordinate System
-
-
-=== Definition
-
-A _coordinate system_ consists of an origin (single point in space) and three coordinate axes that are each unit length and mutually perpendicular. The axes can be written as the column of a Matrix, R = [U1|U2|U3]. In fact, this is exactly how CameraNode works. The coordinate system defined by Camera is stored in a Matrix.
-
-jME uses a Right-Handed coordinate system (as OpenGL does).
-
-The definition of a coordinate system is defined in jME by the properties sent to Camera. There are no error checks to insure that: 1) the coordinate system is right-handed and 2) The axes are mutually perpendicular. Therefore, if the user sets the axes incorrectly, they are going to experience very odd rendering artifacts (random culling, etc).
-
-
-image::jme3/intermediate/coordinate-system.png[coordinate-system.png,width="235",height="210",align="center"]
-
-
-
-=== Homogenous coordinates
-
-Homogenous coordinates have an additional _W_ value tacked on to the end. The XYZ values are to be divided by W to give the true coordinates.
-
-This has several advantages, one technical, some relevant to application programmers:
-
-Technically, it simplifies some formulae used inside the vector math. For example, some operations need to apply the same factor to the XYZ coordinates. Chain multiple operations of that kind (and vector math tends to do that), and you can save a lot of multiplications by simply keeping the scaling factor around and doing the multiplication to XYZ at the end of the pipeline, in the 3D card (which does accept homogenous coordinates).
-It also simplifies some formulae, in particular anything that is related to rotations.
-
-For application programmers, this means you can express infinitely long vectors that still have a direction - these tend to be used in lighting. Just use a W value of 0.0.
-
-
-== Transformations
-
-Transformations define an operation that converts points from one coordinate system to another. This includes translation, rotation and scaling. In jME, local transforms are used to represent the positioning of objects relative to a parent coordinate system. While, world transforms are used to represent the positioning of objects in a global coordinate system.
-
-
-== Visibility Determination
-
-Visibility Determination concerns itself with minimizing the amount of data that is sent to the graphics card for rendering. Specifically, we do not want to send data that will not be seen. Data not sent to the graphics card is said to be culled. The primary focus of this section is Frustum Culling based on the Camera's view frustum. In essence, this frustum creates six standard view planes. The BoundingVolume of an object is tested against the frustum planes to determine if it is contained in the frustum. If at any point the object's bounding is outside of the plane, it is tossed out and no longer processed for rendering. This also includes any children that it managed, allowing fast culling of large sections of the scene.
-
-
-=== Fundamental Types
-
-
-== ColorRGBA
-
-
-=== Definition
-
-ColorRGBA defines a color value in the jME library. The color value is made of three components, red, green and blue. A fourth component defines the alpha value (transparent) of the color. Every value is set between [0, 1]. Anything less than 0 will be clamped to 0 and anything greater than 1 will be clamped to 1.
-
-*Note:* If you would like to "`convert`" an ordinary RGB value (0-255) to the format used here (0-1), simply multiply it with: 1/255.
-
-
-=== jME Class
-
-ColorRGBA defines a few static color values for ease of use. That is, rather than:
-
-[source,java]
-----
-
-ColorRGBA red = new ColorRGBA(1,0,0,1);
-object.setSomeColor(red);
-
-----
-
-you can simply say:
-
-[source,java]
-----
-
-object.setSomeColor(ColorRGBA.red)
-
-----
-
-ColorRGBA will also handle interpolation between two colors. Given a second color and a value between 0 and 1, a the owning ColorRGBA object will have its color values altered to this new interpolated color.
-
-
-== Matrix
-
-See link:{link-javadoc}/com/jme3/math/Matrix3f.html[Matrix3f Javadoc] and link:{link-javadoc}/com/jme3/math/Matrix4f.html[Matrix4f Javadoc]
-
-
-=== Definition
-
-A Matrix is typically used as a _linear transformation_ to map vectors to vectors. That is: Y = MX where X is a Vector and M is a Matrix applying any or all transformations (scale, <<jme3/rotate#,rotate>>, translate).
-
-There are a few special matrices:
-
-_zero matrix_ is the Matrix with all zero entries.
-[cols="3", options="header"]
-|===
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-a|0
-a|0
-a|0
-
-|===
-
-The _Identity Matrix_ is the matrix with 1 on the diagonal entries and 0 for all other entries.
-[cols="3", options="header"]
-|===
-
-a|1
-a|0
-a|0
-
-a|0
-a|1
-a|0
-
-a|0
-a|0
-a|1
-
-|===
-
-A Matrix is _invertible_ if there is a matrix _M^-1^_ where _MM^-1^ = M^-1^M = I_.
-
-The _transpose_ of a matrix _M = [m~ij~]_ is _M^T^ = [m~ji~]_. This causes the rows of _M_ to become the columns of _M^T^_.
-[cols="7", options="header"]
-|===
-
-a|1
-a|1
-a|1
-<a|
-a|1
-a|2
-a|3
-
-a|2
-a|2
-a|2
-a| ⇒
-a|1
-a|2
-a|3
-
-a|3
-a|3
-a|3
-<a|
-a|1
-a|2
-a|3
-
-|===
-
-A Matrix is symmetric if _M_ = _M^T^_.
-[cols="3", options="header"]
-|===
-
-a|X
-a|A
-a|B
-
-a|A
-a|X
-a|C
-
-a|B
-a|C
-a|X
-
-|===
-
-Where X, A, B, and C equal numbers
-
-jME includes two types of Matrix classes: Matrix3f and Matrix4f. Matrix3f is a 3x3 matrix and is the most commonly used (able to handle scaling and rotating), while Matrix4f is a 4x4 matrix that can also handle translation.
-
-
-=== Transformations
-
-Multiplying a vector with a Matrix allows the vector to be transformed. Either rotating, scaling or translating that vector.
-
-
-==== Scaling
-
-If a _diagonal Matrix_, defined by D = [d~ij~] and d~ij~ = 0 for i != j, has all positive entries it is a _scaling matrix_. If d~i~ is greater than 1 then the resulting vector will grow, while if d~i~ is less than 1 it will shrink.
-
-
-==== Rotation
-
-A _rotation matrix_ requires that the transpose and inverse are the same matrix (R^-1^ = R^T^). The _rotation matrix_ R can then be calculated as: R = I + (sin(angle)) S + (1 - cos(angle)S^2^ where S is:
-[cols="3", options="header"]
-|===
-
-a|0
-a|u~2~
-a|-u~1~
-
-a|-u~2~
-a|0
-a|u~0~
-
-a|u~1~
-a|-u~0~
-a|0
-
-|===
-
-
-==== Translation
-
-Translation requires a 4x4 matrix, where the vector (x,y,z) is mapped to (x,y,z,1) for multiplication. The _Translation Matrix_ is then defined as:
-[cols="2", options="header"]
-|===
-
-a|M
-a|T
-
-a|S^T^
-a|1
-
-|===
-
-where M is the 3x3 matrix (containing any rotation/scale information), T is the translation vector and S^T^ is the transpose Vector of T. 1 is just a constant.
-
-
-=== jME Class
-
-Both Matrix3f and Matrix4f store their values as floats and are publicly available as (m00, m01, m02, …, mNN) where N is either 2 or 3.
-
-Most methods are straight forward, and I will leave documentation to the Javadoc.
-
-
-== Vector
-
-See link:{link-javadoc}/com/jme3/math/Vector3f.html[Vector3f Javadoc] and link:{link-javadoc}/com/jme3/math/Vector2f.html[Vector2f Javadoc]
-
-
-=== Definition
-
-Vectors are used to represent a multitude of things in jME, points in space, vertices in a triangle mesh, normals, etc. These classes (Vector3f in particular) are probably the most used class in jME.
-
-A Vector is defined by an n-tuple of real numbers. *V* = &lt;V~1~, V~2~,…, V~n~&gt;.
-
-We have two Vectors (2f and 3f) meaning we have tuples of 2 float values or 3 float values.
-
-
-=== Operations
-
-
-==== Multiplication by Scalar
-
-A Vector can be multiplied by a scalar value to produce a second Vector with the same proportions as the first. a**V** = **V**a = &lt;aV~1~, aV~2~,…,aV~n~&gt;
-
-
-==== Addition and Subtraction
-
-Adding or subtracting two Vectors occurs component-wise. That is the first component is added (subtracted) with the first component of the second Vector and so on.
-
-*P* + *Q* = &lt;P~1~+Q~1~, P~2~+Q~2~, …, P~n~+Q~n~&gt;
-
-
-==== Magnitude
-
-The _magnitude_ defines the length of a Vector. A Vector of magnitude 1 is _unit length_.
-
-For example, if *V* = (x, y, z), the magnitude is the square root of (x^2^ + y^2^ + z^2^).
-
-A Vector can be _normalized_ or made _unit length_ by multiplying the Vector by (1/magnitude).
-
-
-==== Dot Products
-
-The dot product of two vectors is defined as:
-*P* dot *Q* = P~x~Q~x~ + P~y~Q~y~ + P~z~Q~z~
-
-Using the dot product allows us to determine how closely two Vectors are pointing to the same point. If the dot product is negative they are facing in relatively opposite directions, while postive tells us they are pointing in the relative same direction.
-
-If the dot product is 0 then the two Vectors are _orthogonal_ or 90 degrees off.
-
-
-==== Cross Product
-
-The Cross Product of two Vectors returns a third Vector that is prependicular to the two Vectors. This is very useful for calculating surface normals.
-
-*P* X *Q* = &lt;P~y~Q~z~ - P~z~Q~y~, P~z~Q~x~ - P~x~Q~z~, P~x~Q~y~ - P~y~Q~x~&gt;
-
-
-==== jME Class
-
-Vector3f and Vector2f store their values (x, y, z) and (x, y) respectively as floats. Most methods are straight forward, and I will leave documentation to the Javadoc.
-
-
-== Quaternion
-
-See link:{link-javadoc}/com/jme3/math/Quaternion.html[Quaternion Javadoc]
-
-
-=== Definition
-
-Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation.
-
-Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).
-
-While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in the <<jme3/advanced/spatial#,Spatial>> as its local rotation component.
-
-Quaternion *q* has the form
-
-*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_
-
-or alternatively, it can be written as:
-
-*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.
-
-Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):
-
-`i^2^ = j^2^ = k^2^ = -1`+
-`ij = -ji = k`+
-`jk = -kj = i`+
-`ki = -ik = j`
-
-However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.
-
-*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*
-
-Quaternions also have conjugates where the conjugate of *q* is (s - *v*)
-
-These basic operations allow us to convert various rotation representations to Quaternions.
-
-
-=== Angle Axis
-
-You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to <<jme3/rotate#,rotate>> about this axis. <<jme3/quaternion#,Quaternion>> defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.
-
-
-==== Example - Rotate a Spatial Using fromAngleAxis
-
-[source,java]
-----
-
-//rotate about the Y-Axis by approximately 1 pi
-Vector3f axis = Vector3f.UNIT_Y;
-// UNIT_Y equals (0,1,0) and does not require to create a new object
-float angle = 3.14f;
-s.getLocalRotation().fromAngleAxis(angle, axis);
-
-----
-
-
-=== Three Angles
-
-You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`
-
-
-==== Example - Rotate a Spatial Using fromAngles
-
-[source,java]
-----
-
-//rotate 1 radian on the x, 3 on the y and 0 on z
-float[] angles = {1, 3, 0};
-s.getLocalRotation().fromAngles(angles);
-
-----
-
-
-=== Three Axes
-
-If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a Vector3f array.
-
-
-==== Example - Rotate a Spatial Using fromAxes
-
-[source,java]
-----
-
-//rotate a spatial to face up ~45 degrees
-Vector3f[] axes = new Vector3f[3];
-axes[0] = new Vector3f(-1, 0, 0); //left
-axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
-axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir
-
-s.getLocalRotation().fromAxes(axes);
-
-----
-
-
-=== Rotation Matrix
-
-Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a Matrix create a Quaternion, rotate the Quaternion, and then get the Matrix back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the give Matrix. The `toRotationMatrix` will populate a given Matrix.
-
-
-==== Example - Rotate a Spatial Using a Rotation Matrix
-
-[source,java]
-----
-
-
-Matrix3f mat = new Matrix3f();
-mat.setColumn(0, new Vector3f(1,0,0));
-mat.setColumn(1, new Vector3f(0,-1,0));
-mat.setColumn(2, new Vector3f(0,0,1));
-
-s.getLocalRotation().fromRotationMatrix(mat);
-
-----
-
-As you can see there are many ways to build a Quaternion. This allows you to work with rotations in a way that is conceptually easier to picture, but still build Quaternions for internal representation.
-
-
-=== Slerp
-
-One of the biggest advantages to using Quaternions is allowing interpolation between two rotations. That is, if you have an initial Quaternion representing the original orientation of an object, and you have a final Quaternion representing the orientation you want the object to face, you can do this very smoothly with slerp. Simply supply the time, where time is [0, 1] and 0 is the initial rotation and 1 is the final rotation.
-
-
-==== Example - Use Slerp to Rotate Between two Quaternions
-
-[source,java]
-----
-
-/*
-You can interpolate rotations between two quaternions using spherical linear
-interpolation (slerp).
-*/
-Quaternion Xroll45 = new Quaternion();
-Xroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
-//
-Quaternion Yroll45 = new Quaternion();
-Yroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y);
-
-//the rotation half - way between these two
-
-Quaternion halfBetweenXroll45Yroll45 = new Quaternion();
-halfBetweenXroll45Yroll45.slerp(Xroll45, Yroll45, 0.5f);
-geom2.setLocalRotation(halfBetweenXroll45Yroll45);
-
-----
-
-
-=== Multiplication
-
-You can concatenate (add) rotations: This means you turn the object first around one axis, then around the other, in one step.
-
-[source,java]
-----
-Quaternion myRotation = pitch90.mult(roll45); /* pitch and roll */
-----
-
-To rotate a Vector3f around its origin by the Quaternion amount, use the multLocal method of the Quaternion:
-
-[source,java]
-----
-Quaternion myRotation = pitch90;
-Vector3f myVector = new Vector3f(0,0,-1);
-myRotation.multLocal(myVector);
-
-----
-
-
-==== Utility Classes
-
-Along with the base Math classes, jME provides a number of Math classes to make development easier (and, hopefully, faster). Most of these classes find uses throughout the jME system internally. They can also prove beneficial to users as well.
-
-
-== Fast Math
-
-See link:{link-javadoc}/com/jme3/math/FastMath.html[FastMath Javadoc]
-
-
-=== Definition
-
-FastMath provides a number of convience methods, and where possible faster versions (although this can be at the sake of accuracy).
-
-
-=== Usage
-
-FastMath provides a number of constants that can help with general math equations. One important attribute is `USE_FAST_TRIG` if you set this to true, a look-up table will be used for trig functions rather than Java's standard Math library. This provides significant speed increases, but might suffer from accuracy so care should be taken.
-
-There are five major categories of functions that FastMath provides.
-
-
-==== Trig Functions
-
-* cos and acos - provide link:http://en.wikipedia.org/wiki/cosine[cosine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc cosine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
-* sin and asin - provide link:http://en.wikipedia.org/wiki/sine[sine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc sine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
-* tan and atan - provide link:http://en.wikipedia.org/wiki/tangent[tangent] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc tangent] values
-
-
-==== Numerical Methods
-
-* ceil - provides the ceiling (smallest value that is greater than or equal to a given value and an integer)of a value.
-* floor - provides the floor (largest value that is less than or equal to a given value and an integer) of a value.
-* exp - provides the link:http://en.wikipedia.org/wiki/Euler_number[euler number] (e) raised to the provided value.
-* sqr - provides the square of a value (i.e. value * value).
-* pow - provides the first given number raised to the second.
-* isPowerOfTwo - provides a boolean if a value is a power of two or not (e.g. 32, 64, 4).
-* abs - provides the link:http://en.wikipedia.org/wiki/Absolute_value[absolute value] of a given number.
-* sign - provides the sign of a value (1 if positive, -1 if negative, 0 if 0).
-* log - provides the link:http://en.wikipedia.org/wiki/Natural_logarithm[natural logarithm] of a value.
-* sqrt - provides the link:http://en.wikipedia.org/wiki/Square_root[square root] of a value.
-* invSqrt - provides the inverse square root of a value (1 / sqrt(value).
-
-
-==== Linear Algebra
-
-* LERP - calculate the link:http://en.wikipedia.org/wiki/Linear_interpolation[linear interpolation] of two points given a time between 0 and 1.
-* determinant - calculates the link:http://en.wikipedia.org/wiki/determinant[determinant] of a 4x4 matrix.
-
-
-==== Geometric Functions
-
-* counterClockwise - given three points (defining a triangle), the winding is determined. 1 if counter-clockwise, -1 if clockwise and 0 if the points define a line.
-* pointInsideTriangle - calculates if a point is inside a triangle.
-* sphericalToCartesian - converts a point from link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates] to link:https://en.wikipedia.org/wiki/Cartesian[cartesian coordinates].
-* cartesianToSpherical - converts a point from cartesian coordinates to link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates].
-
-
-==== Misc.
-
-* newRandomFloat - obtains a random float.
-
-
-== Line
-
-See link:{link-javadoc}/com/jme3/math/Line.html[Line Javadoc]
-
-
-=== Definition
-
-A line is a straight one-dimensional figure having no thickness and extending infinitely in both directions. A line is defined by two points *A* and *B* with the line passing through both.
-
-
-=== Usage
-
-jME defines a Line class that is defined by an origin and direction. In reality, this Line class is typically used as a _line segment_. Where the line is finite and contained between these two points.
-
-`random` provides a means of generate a random point that falls on the line between the origin and direction points.
-
-
-=== Example 1 - Find a Random Point on a Line
-
-[source,java]
-----
-
-Line l = new Line(new Vector3f(0,1,0), new Vector3f(3,2,1));
-Vector3f randomPoint = l.random();
-
-----
-
-
-== Plane
-
-See link:{link-javadoc}/com/jme3/math/Plane.html[Plane Javadoc]
-
-
-=== Definition
-
-A plane is defined by the equation *N* . (*X* - *X~0~*) = 0 where *N* = (a, b, c) and passes through the point *X~0~* = (x~0~, y~0~, z~0~). *X* defines another point on this plane (x, y, z).
-
-*N* . (*X* - *X~0~*) = 0 can be described as (*N* . *X*) + (*N* . -*X~0~*) = 0
-
-or
-
-(ax + by + cz) + (-ax~0~-by~0~-cz~0~) = 0
-
-where (-ax~0~-by~0~-cz~0~) = d
-
-Where d is the negative value of a point in the plane times the unit vector describing the orientation of the plane.
-
-This gives us the general equation: (ax + by + cz + d = 0)
-
-
-=== Usage in jME
-
-jME defines the Plane as ax + by + cz = -d. Therefore, during creation of the plane, the normal of the plane (a,b,c) and the constant d is supplied.
-
-The most common usage of Plane is <<jme3/advanced/camera#,Camera>> frustum planes. Therefore, the primary purpose of Plane is to determine if a point is on the positive side, negative side, or intersecting a plane.
-
-Plane defines the constants:
-
-* `NEGATIVE_SIDE` - represents a point on the opposite side to which the normal points.
-* `NO_SIDE` - represents a point that lays on the plane itself.
-* `POSITIVE_SIDE` - represents a point on the side to which the normal points.
-
-These values are returned on a call to `whichSide`.
-
-
-=== Example 1 - Determining if a Point is On the Positive Side of a Plane
-
-[source,java]
-----
-
-Vector3f normal = new Vector3f(0,1,0);
-float constant = new Vector3f(1,1,1).dot(normal);
-Plane testPlane = new Plane(normal, constant);
-
-int side = testPlane.whichSide(new Vector3f(2,1,0));
-
-if(side == Plane.NO_SIDE) {
-   System.out.println("This point lies on the plane");
-}
-
-----
-
-
-=== Example 2 - For the Layperson
-
-Using the standard constructor Plane(Vector3f normal, float constant), here is what you need to do to create a plane, and then use it to check which side of the plane a point is on.
-
-[source,java]
-----
-
-package test;
-
-import java.util.logging.Logger;
-
-import com.jme.math.*;
-
-/**
- *@author Nick Wiggill
- */
-
-public class TestPlanes
-{
-  public static final Logger logger = Logger.getLogger(LevelGraphBuilder.class.getName());
-
-  public static void main(String[] args) throws Exception
-  {
-    //***Outline.
-    //This example shows how to construct a plane representation using
-    //com.jme.math.Plane.
-    //We will create a very simple, easily-imagined 3D plane. It will
-    //be perpendicular to the x axis (it's facing). It's "centre" (if
-    //such a thing exists in an infinite plane) will be positioned 1
-    //unit along the positive x axis.
-
-    //***Step 1.
-    //The vector that represents the normal to the plane, in 3D space.
-    //Imagine a vector coming out of the origin in this direction.
-    //There is no displacement yet (see Step 2, below).
-    Vector3f normal = new Vector3f(5f,0,0);
-
-    //***Step 2.
-    //This is our displacement vector. The plane remains facing in the
-    //direction we've specified using the normal above, but now we are
-    //are actually giving it a position other than the origin.
-    //We will use this displacement to define the variable "constant"
-    //needed to construct the plane. (see step 3)
-    Vector3f displacement = Vector3f.UNIT_X;
-    //or
-    //Vector3f displacement = new Vector3f(1f, 0, 0);
-
-    //***Step 3.
-    //Here we generate the constant needed to define any plane. This
-    //is semi-arcane, don't let it worry you. All you need to
-    //do is use this same formula every time.
-    float constant = displacement.dot(normal);
-
-    //***Step 4.
-    //Finally, construct the plane using the data you have assembled.
-    Plane plane = new Plane(normal, constant);
-
-    //***Some tests.
-    logger.info("Plane info: "+plane.toString()); //trace our plane's information
-
-    Vector3f p1  = new Vector3f(1.1f,0,0); //beyond the plane (further from origin than plane)
-    Vector3f p2  = new Vector3f(0.9f,0,0); //before the plane (closer to origin than plane)
-    Vector3f p3  = new Vector3f(1f,0,0); //on the plane
-
-    logger.info("p1 position relative to plane is "+plane.whichSide(p1)); //outputs NEGATIVE
-    logger.info("p2 position relative to plane is "+plane.whichSide(p2)); //outputs POSITIVE
-    logger.info("p3 position relative to plane is "+plane.whichSide(p3)); //outputs NONE
-  }
-}
-
-----
-
-
-== Ray
-
-See link:{link-javadoc}/com/jme3/math/Ray.html[Ray Javadoc]
-
-
-=== Definition
-
-Ray defines a line that starts at a point *A* and continues in a direction through *B* into infinity.
-
-This Ray is used extensively in jME for <<jme3/beginner/hello_picking#,Picking>>. A Ray is cast from a point in screen space into the scene. Intersections are found and returned. To create a ray supply the object with two points, where the first point is the origin.
-
-
-=== Example 1 - Create a Ray That Represents Where the Camera is Looking
-
-[source,java]
-----
-
-Ray ray = new Ray(cam.getLocation(), cam.getDirection());
-
-----
-
-
-== Rectangle
-
-See link:{link-javadoc}/com/jme3/math/Rectangle.html[Rectangle Javadoc]
-
-
-=== Definition
-
-Rectangle defines a finite plane within three dimensional space that is specified via three points (A, B, C). These three points define a triangle with the forth point defining the rectangle ( (B + C) - A ).
-
-
-=== jME Usage
-
-Rectangle is a straight forward data class that simply maintains values that defines a Rectangle in 3D space. One interesting use is the `random` method that will create a random point on the Rectangle. The <<jme3/advanced/effects_overview#,Particle System>> makes use of this to define an area that generates <<jme3/advanced/particle_emitters#,Particles>>.
-
-
-=== Example 1 : Define a Rectangle and Get a Point From It
-
-[source,java]
-----
-
-Vector3f v1 = new Vector3f(1,0,0);
-Vector3f v2 = new Vector3f(1,1,0);
-Vector3f v3 = new Vector3f(0,1,0);
-Rectangle r = new Rectangle(v1, v2, v3);
-Vector3f point = r.random();
-
-----
-
-
-== Triangle
-
-See link:{link-javadoc}/com/jme3/math/Triangle.html[Triangle Javadoc]
-
-
-=== Definition
-
-A triangle is a 3-sided polygon. Every triangle has three sides and three angles, some of which may be the same. If the triangle is a right triangle (one angle being 90 degrees), the side opposite the 90 degree angle is the hypotenuse, while the other two sides are the legs. All triangles are link:http://en.wikipedia.org/wiki/Convex_polygon[convex] and link:http://mathworld.wolfram.com/BicentricPolygon.html[bicentric].
-
-
-=== Usage
-
-jME's Triangle class is a simple data class. It contains three <<jme3/terminology.html#vectors#,Vector3f>> objects that represent the three points of the triangle. These can be retrieved via the `get` method. The `get` method, obtains the point based on the index provided. Similarly, the values can be set via the `set` method.
-
-
-=== Example 1 - Creating a Triangle
-
-[source,java]
-----
-
-//the three points that make up the triangle
-Vector3f p1 = new Vector3f(0,1,0);
-Vector3f p2 = new Vector3f(1,1,0);
-Vector3f p3 = new Vector3f(0,1,1);
-Triangle t = new Triangle(p1, p2, p3);
-
-----
-
-
-==== Tips and Tricks
-
-
-== How do I get height/width of a spatial?
-
-Cast the spatial to com.jme3.bounding.BoundingBox to be able to use getExtent().
-
-[source,java]
-----
-Vector3f extent = ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f());
-float x = ( (BoundingBox)spatial.getWorldBound()).getXExtent();
-float y = ( (BoundingBox)spatial.getWorldBound()).getYExtent();
-float z = ( (BoundingBox)spatial.getWorldBound()).getZExtent();
-
-----
-
-
-== How do I position the center of a Geomtry?
-
-[source,java]
-----
-geo.center().move(pos);
-----
-
-
-=== See Also
-
-*  <<jme3/rotate#,Rotate>>
-*  <<jme3/quaternion#,Quaternion>>

+ 782 - 124
docs/modules/tutorials/pages/intermediate/math.adoc

@@ -1,144 +1,802 @@
-= Math Cheat Sheet
-:author: 
-:revnumber: 
+= Introduction to Mathematical Functionality
+:author:
+:revnumber:
 :revdate: 2016/03/17 20:48
-:relfileprefix: ../../
-:imagesdir: ../..
+:relfileprefix: ../
+:imagesdir: ..
 ifdef::env-github,env-browser[:outfilesuffix: .adoc]
 
 
+It's a fact of life, math is hard. Unfortunately, 3D graphics require a fair bit of knowledge about the subject. Fortunately, jME is able to hide the majority of the details away from the user. Vectors are the fundamental type in the 3D environment, and it is used extensively. Matrices are also a basic necessity of 3D for representing linear systems. <<jme3/quaternion#,Quaternions>> are perhaps the most powerful and complicated of the basic types and are used for rotation in jME.
 
-== Formulas
+I'll discuss how these are used in the system for the core functionality. Including Transforming, Visibility Determination, Collision Detection, and the Coordinate System. Note, that these are low level details. Further chapters will discuss how to use these various systems from a high level perspective.
 
-[NOTE]
-====
-Typically you have to string these formulas together. Look in the table for what you want, and what you have. If the two are not the same line, than you need conversion steps inbetween. E.g. if you have an angle in degrees, but the formula expects radians: 1) convert degrees to radians, 2) use the radians formula on the result.
-====
+To get a visual introduction to math in jME3 for the absolute beginner, check out our <<jme3/math_for_dummies#,Math for Dummies>> introduction class.
 
+
+== Coordinate System
+
+
+=== Definition
+
+A _coordinate system_ consists of an origin (single point in space) and three coordinate axes that are each unit length and mutually perpendicular. The axes can be written as the column of a Matrix, R = [U1|U2|U3]. In fact, this is exactly how CameraNode works. The coordinate system defined by Camera is stored in a Matrix.
+
+jME uses a Right-Handed coordinate system (as OpenGL does).
+
+The definition of a coordinate system is defined in jME by the properties sent to Camera. There are no error checks to insure that: 1) the coordinate system is right-handed and 2) The axes are mutually perpendicular. Therefore, if the user sets the axes incorrectly, they are going to experience very odd rendering artifacts (random culling, etc).
+
+
+image::jme3/intermediate/coordinate-system.png[coordinate-system.png,width="235",height="210",align="center"]
+
+
+
+=== Homogenous coordinates
+
+Homogenous coordinates have an additional _W_ value tacked on to the end. The XYZ values are to be divided by W to give the true coordinates.
+
+This has several advantages, one technical, some relevant to application programmers:
+
+Technically, it simplifies some formulae used inside the vector math. For example, some operations need to apply the same factor to the XYZ coordinates. Chain multiple operations of that kind (and vector math tends to do that), and you can save a lot of multiplications by simply keeping the scaling factor around and doing the multiplication to XYZ at the end of the pipeline, in the 3D card (which does accept homogenous coordinates).
+It also simplifies some formulae, in particular anything that is related to rotations.
+
+For application programmers, this means you can express infinitely long vectors that still have a direction - these tend to be used in lighting. Just use a W value of 0.0.
+
+
+== Transformations
+
+Transformations define an operation that converts points from one coordinate system to another. This includes translation, rotation and scaling. In jME, local transforms are used to represent the positioning of objects relative to a parent coordinate system. While, world transforms are used to represent the positioning of objects in a global coordinate system.
+
+
+== Visibility Determination
+
+Visibility Determination concerns itself with minimizing the amount of data that is sent to the graphics card for rendering. Specifically, we do not want to send data that will not be seen. Data not sent to the graphics card is said to be culled. The primary focus of this section is Frustum Culling based on the Camera's view frustum. In essence, this frustum creates six standard view planes. The BoundingVolume of an object is tested against the frustum planes to determine if it is contained in the frustum. If at any point the object's bounding is outside of the plane, it is tossed out and no longer processed for rendering. This also includes any children that it managed, allowing fast culling of large sections of the scene.
+
+
+=== Fundamental Types
+
+
+== ColorRGBA
+
+
+=== Definition
+
+ColorRGBA defines a color value in the jME library. The color value is made of three components, red, green and blue. A fourth component defines the alpha value (transparent) of the color. Every value is set between [0, 1]. Anything less than 0 will be clamped to 0 and anything greater than 1 will be clamped to 1.
+
+*Note:* If you would like to "`convert`" an ordinary RGB value (0-255) to the format used here (0-1), simply multiply it with: 1/255.
+
+
+=== jME Class
+
+ColorRGBA defines a few static color values for ease of use. That is, rather than:
+
+[source,java]
+----
+
+ColorRGBA red = new ColorRGBA(1,0,0,1);
+object.setSomeColor(red);
+
+----
+
+you can simply say:
+
+[source,java]
+----
+
+object.setSomeColor(ColorRGBA.red)
+
+----
+
+ColorRGBA will also handle interpolation between two colors. Given a second color and a value between 0 and 1, a the owning ColorRGBA object will have its color values altered to this new interpolated color.
+
+
+== Matrix
+
+See link:{link-javadoc}/com/jme3/math/Matrix3f.html[Matrix3f Javadoc] and link:{link-javadoc}/com/jme3/math/Matrix4f.html[Matrix4f Javadoc]
+
+
+=== Definition
+
+A Matrix is typically used as a _linear transformation_ to map vectors to vectors. That is: Y = MX where X is a Vector and M is a Matrix applying any or all transformations (scale, <<jme3/rotate#,rotate>>, translate).
+
+There are a few special matrices:
+
+_zero matrix_ is the Matrix with all zero entries.
 [cols="3", options="header"]
 |===
 
-a|I have…
-a|I want…
-a|Formula
-
-a|normalized direction and length +
-n1,d1
-a|a vector that goes that far in that direction +
-new direction vector v0
-a|v0 = n1.mult(d1)
-
-a|point and direction vector +
-p1,v1
-a|to move the point +
-new point p0
-a|p0 = p1.add(v1)
-
-a| direction, position and distance +
-v1,p1,dist
-a|Position at distance +
-p2 
-a|v1.normalzeLocal() +
-scaledDir = v1.mult(dist) +
-p2 = p1.add(scaledDir)
-
-a|two direction vectors or normals +
-v1,v2
-a|to combine both directions +
-new direction vector v0
-a|v0 = v1.add(v2)
-
-a|two points +
-p1, p2
-a|distance between two points +
-new scalar d0
-a|d0 = p1.subtract(p2).length() +
-d0 = p1.distance(p2)
-
-a|two points +
-p1, p2
-a|the direction from p2 to p1 +
-new direction vector v0
-a|v0 = p1.substract(p2)
-
-a|two points, a fraction +
-p1, p2, h=0.5f
-a|the point “halfway (h=0.5f) between the two points +
-new interpolated point p0
-a|p0 = FastMath.interpolateLinear(h,p1,p2)
-
-a|a direction vector, an up vector +
-v, up
-a|A rotation around this up axis towards this direction +
-new Quaternion q
-a|Quaternion q = new Quaternion(); +
-q.lookAt(v,up)
+a|0
+a|0
+a|0
+
+a|0
+a|0
+a|0
+
+a|0
+a|0
+a|0
 
 |===
+
+The _Identity Matrix_ is the matrix with 1 on the diagonal entries and 0 for all other entries.
 [cols="3", options="header"]
 |===
 
-a|I have…
-a|I want…
-a|Formula
-
-a|angle in degrees +
-a 
-a| to convert angle a from degrees to radians +
-new float angle phi
-a|phi = a / 180 * FastMath.PI; +
-OR +
-phi=a.mult(FastMath.DEG_TO_RAD); 
-
-a|angle in radians +
-phi 
-a| to convert angle phi from radians to degrees +
-new float angle a
-a|a = phi * 180 / FastMath.PI 
-
-a|radian angle and x axis +
-phi, x 
-a|to rotate around x axis +
-new quaternion q0
-a|q0.fromAngleAxis( phi, Vector3f.UNIT_X )
-
-a|radian angle and y axis +
-phi, y 
-a|to rotate around y axis +
-new quaternion q0
-a|q0.fromAngleAxis( phi, Vector3f.UNIT_Y )
-
-a|radian angle and z axis +
-phi, z 
-a|to rotate around z axis +
-new quaternion q0
-a|q0.fromAngleAxis( phi, Vector3f.UNIT_Z )
-
-a|several quaternions +
-q1, q2, q3
-a|to combine rotations, in that order +
-new quaternion q0
-a|q0 = q1.mult(q2).mult(q3)
-
-a|point and quaternion +
-p1, q1
-a|to rotate the point around origin +
-new point p0
-a|p0 = q1.mult(p1)
-
-a|angle in radians and radius +
-phi,r
-a|to arrange or move objects horizontally in a circle (with y=0) +
-x and z coordinates
-a|float x = FastMath.cos(phi)*r; +
-float z = FastMath.sin(phi)*r;
+a|1
+a|0
+a|0
+
+a|0
+a|1
+a|0
+
+a|0
+a|0
+a|1
+
+|===
+
+A Matrix is _invertible_ if there is a matrix _M^-1^_ where _MM^-1^ = M^-1^M = I_.
 
+The _transpose_ of a matrix _M = [m~ij~]_ is _M^T^ = [m~ji~]_. This causes the rows of _M_ to become the columns of _M^T^_.
+[cols="7", options="header"]
 |===
 
+a|1
+a|1
+a|1
+<a|
+a|1
+a|2
+a|3
+
+a|2
+a|2
+a|2
+a| ⇒
+a|1
+a|2
+a|3
+
+a|3
+a|3
+a|3
+<a|
+a|1
+a|2
+a|3
+
+|===
+
+A Matrix is symmetric if _M_ = _M^T^_.
+[cols="3", options="header"]
+|===
+
+a|X
+a|A
+a|B
+
+a|A
+a|X
+a|C
+
+a|B
+a|C
+a|X
+
+|===
+
+Where X, A, B, and C equal numbers
+
+jME includes two types of Matrix classes: Matrix3f and Matrix4f. Matrix3f is a 3x3 matrix and is the most commonly used (able to handle scaling and rotating), while Matrix4f is a 4x4 matrix that can also handle translation.
+
+
+=== Transformations
+
+Multiplying a vector with a Matrix allows the vector to be transformed. Either rotating, scaling or translating that vector.
+
+
+==== Scaling
+
+If a _diagonal Matrix_, defined by D = [d~ij~] and d~ij~ = 0 for i != j, has all positive entries it is a _scaling matrix_. If d~i~ is greater than 1 then the resulting vector will grow, while if d~i~ is less than 1 it will shrink.
+
+
+==== Rotation
+
+A _rotation matrix_ requires that the transpose and inverse are the same matrix (R^-1^ = R^T^). The _rotation matrix_ R can then be calculated as: R = I + (sin(angle)) S + (1 - cos(angle)S^2^ where S is:
+[cols="3", options="header"]
+|===
+
+a|0
+a|u~2~
+a|-u~1~
+
+a|-u~2~
+a|0
+a|u~0~
+
+a|u~1~
+a|-u~0~
+a|0
+
+|===
+
+
+==== Translation
+
+Translation requires a 4x4 matrix, where the vector (x,y,z) is mapped to (x,y,z,1) for multiplication. The _Translation Matrix_ is then defined as:
+[cols="2", options="header"]
+|===
+
+a|M
+a|T
+
+a|S^T^
+a|1
+
+|===
+
+where M is the 3x3 matrix (containing any rotation/scale information), T is the translation vector and S^T^ is the transpose Vector of T. 1 is just a constant.
+
+
+=== jME Class
+
+Both Matrix3f and Matrix4f store their values as floats and are publicly available as (m00, m01, m02, …, mNN) where N is either 2 or 3.
+
+Most methods are straight forward, and I will leave documentation to the Javadoc.
+
+
+== Vector
+
+See link:{link-javadoc}/com/jme3/math/Vector3f.html[Vector3f Javadoc] and link:{link-javadoc}/com/jme3/math/Vector2f.html[Vector2f Javadoc]
+
+
+=== Definition
+
+Vectors are used to represent a multitude of things in jME, points in space, vertices in a triangle mesh, normals, etc. These classes (Vector3f in particular) are probably the most used class in jME.
+
+A Vector is defined by an n-tuple of real numbers. *V* = &lt;V~1~, V~2~,…, V~n~&gt;.
+
+We have two Vectors (2f and 3f) meaning we have tuples of 2 float values or 3 float values.
+
+
+=== Operations
+
+
+==== Multiplication by Scalar
+
+A Vector can be multiplied by a scalar value to produce a second Vector with the same proportions as the first. a**V** = **V**a = &lt;aV~1~, aV~2~,…,aV~n~&gt;
+
+
+==== Addition and Subtraction
+
+Adding or subtracting two Vectors occurs component-wise. That is the first component is added (subtracted) with the first component of the second Vector and so on.
+
+*P* + *Q* = &lt;P~1~+Q~1~, P~2~+Q~2~, …, P~n~+Q~n~&gt;
+
+
+==== Magnitude
+
+The _magnitude_ defines the length of a Vector. A Vector of magnitude 1 is _unit length_.
+
+For example, if *V* = (x, y, z), the magnitude is the square root of (x^2^ + y^2^ + z^2^).
+
+A Vector can be _normalized_ or made _unit length_ by multiplying the Vector by (1/magnitude).
+
+
+==== Dot Products
+
+The dot product of two vectors is defined as:
+*P* dot *Q* = P~x~Q~x~ + P~y~Q~y~ + P~z~Q~z~
+
+Using the dot product allows us to determine how closely two Vectors are pointing to the same point. If the dot product is negative they are facing in relatively opposite directions, while postive tells us they are pointing in the relative same direction.
+
+If the dot product is 0 then the two Vectors are _orthogonal_ or 90 degrees off.
+
+
+==== Cross Product
+
+The Cross Product of two Vectors returns a third Vector that is prependicular to the two Vectors. This is very useful for calculating surface normals.
+
+*P* X *Q* = &lt;P~y~Q~z~ - P~z~Q~y~, P~z~Q~x~ - P~x~Q~z~, P~x~Q~y~ - P~y~Q~x~&gt;
+
+
+==== jME Class
+
+Vector3f and Vector2f store their values (x, y, z) and (x, y) respectively as floats. Most methods are straight forward, and I will leave documentation to the Javadoc.
+
+
+== Quaternion
+
+See link:{link-javadoc}/com/jme3/math/Quaternion.html[Quaternion Javadoc]
+
+
+=== Definition
+
+Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation.
+
+Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).
+
+While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in the <<jme3/advanced/spatial#,Spatial>> as its local rotation component.
+
+Quaternion *q* has the form
+
+*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_
+
+or alternatively, it can be written as:
+
+*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.
+
+Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):
+
+`i^2^ = j^2^ = k^2^ = -1`+
+`ij = -ji = k`+
+`jk = -kj = i`+
+`ki = -ik = j`
+
+However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.
+
+*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*
+
+Quaternions also have conjugates where the conjugate of *q* is (s - *v*)
+
+These basic operations allow us to convert various rotation representations to Quaternions.
+
+
+=== Angle Axis
+
+You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to <<jme3/rotate#,rotate>> about this axis. <<jme3/quaternion#,Quaternion>> defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.
+
+
+==== Example - Rotate a Spatial Using fromAngleAxis
+
+[source,java]
+----
+
+//rotate about the Y-Axis by approximately 1 pi
+Vector3f axis = Vector3f.UNIT_Y;
+// UNIT_Y equals (0,1,0) and does not require to create a new object
+float angle = 3.14f;
+s.getLocalRotation().fromAngleAxis(angle, axis);
+
+----
+
+
+=== Three Angles
+
+You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`
+
+
+==== Example - Rotate a Spatial Using fromAngles
+
+[source,java]
+----
+
+//rotate 1 radian on the x, 3 on the y and 0 on z
+float[] angles = {1, 3, 0};
+s.getLocalRotation().fromAngles(angles);
+
+----
+
+
+=== Three Axes
+
+If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a Vector3f array.
+
+
+==== Example - Rotate a Spatial Using fromAxes
+
+[source,java]
+----
+
+//rotate a spatial to face up ~45 degrees
+Vector3f[] axes = new Vector3f[3];
+axes[0] = new Vector3f(-1, 0, 0); //left
+axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
+axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir
+
+s.getLocalRotation().fromAxes(axes);
+
+----
+
+
+=== Rotation Matrix
+
+Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a Matrix create a Quaternion, rotate the Quaternion, and then get the Matrix back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the give Matrix. The `toRotationMatrix` will populate a given Matrix.
+
+
+==== Example - Rotate a Spatial Using a Rotation Matrix
+
+[source,java]
+----
+
+
+Matrix3f mat = new Matrix3f();
+mat.setColumn(0, new Vector3f(1,0,0));
+mat.setColumn(1, new Vector3f(0,-1,0));
+mat.setColumn(2, new Vector3f(0,0,1));
+
+s.getLocalRotation().fromRotationMatrix(mat);
+
+----
+
+As you can see there are many ways to build a Quaternion. This allows you to work with rotations in a way that is conceptually easier to picture, but still build Quaternions for internal representation.
+
+
+=== Slerp
+
+One of the biggest advantages to using Quaternions is allowing interpolation between two rotations. That is, if you have an initial Quaternion representing the original orientation of an object, and you have a final Quaternion representing the orientation you want the object to face, you can do this very smoothly with slerp. Simply supply the time, where time is [0, 1] and 0 is the initial rotation and 1 is the final rotation.
+
+
+==== Example - Use Slerp to Rotate Between two Quaternions
+
+[source,java]
+----
+
+/*
+You can interpolate rotations between two quaternions using spherical linear
+interpolation (slerp).
+*/
+Quaternion Xroll45 = new Quaternion();
+Xroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_X);
+//
+Quaternion Yroll45 = new Quaternion();
+Yroll45.fromAngleAxis(45 * FastMath.DEG_TO_RAD, Vector3f.UNIT_Y);
+
+//the rotation half - way between these two
+
+Quaternion halfBetweenXroll45Yroll45 = new Quaternion();
+halfBetweenXroll45Yroll45.slerp(Xroll45, Yroll45, 0.5f);
+geom2.setLocalRotation(halfBetweenXroll45Yroll45);
+
+----
+
+
+=== Multiplication
+
+You can concatenate (add) rotations: This means you turn the object first around one axis, then around the other, in one step.
+
+[source,java]
+----
+Quaternion myRotation = pitch90.mult(roll45); /* pitch and roll */
+----
+
+To rotate a Vector3f around its origin by the Quaternion amount, use the multLocal method of the Quaternion:
+
+[source,java]
+----
+Quaternion myRotation = pitch90;
+Vector3f myVector = new Vector3f(0,0,-1);
+myRotation.multLocal(myVector);
+
+----
+
+
+==== Utility Classes
+
+Along with the base Math classes, jME provides a number of Math classes to make development easier (and, hopefully, faster). Most of these classes find uses throughout the jME system internally. They can also prove beneficial to users as well.
+
+
+== Fast Math
+
+See link:{link-javadoc}/com/jme3/math/FastMath.html[FastMath Javadoc]
+
+
+=== Definition
+
+FastMath provides a number of convience methods, and where possible faster versions (although this can be at the sake of accuracy).
+
+
+=== Usage
+
+FastMath provides a number of constants that can help with general math equations. One important attribute is `USE_FAST_TRIG` if you set this to true, a look-up table will be used for trig functions rather than Java's standard Math library. This provides significant speed increases, but might suffer from accuracy so care should be taken.
+
+There are five major categories of functions that FastMath provides.
+
+
+==== Trig Functions
+
+* cos and acos - provide link:http://en.wikipedia.org/wiki/cosine[cosine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc cosine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
+* sin and asin - provide link:http://en.wikipedia.org/wiki/sine[sine] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc sine] values (make use of the look-up table if `USE_FAST_TRIG` is true)
+* tan and atan - provide link:http://en.wikipedia.org/wiki/tangent[tangent] and link:https://en.wikipedia.org/wiki/Inverse_trigonometric_functions[arc tangent] values
+
+
+==== Numerical Methods
+
+* ceil - provides the ceiling (smallest value that is greater than or equal to a given value and an integer)of a value.
+* floor - provides the floor (largest value that is less than or equal to a given value and an integer) of a value.
+* exp - provides the link:http://en.wikipedia.org/wiki/Euler_number[euler number] (e) raised to the provided value.
+* sqr - provides the square of a value (i.e. value * value).
+* pow - provides the first given number raised to the second.
+* isPowerOfTwo - provides a boolean if a value is a power of two or not (e.g. 32, 64, 4).
+* abs - provides the link:http://en.wikipedia.org/wiki/Absolute_value[absolute value] of a given number.
+* sign - provides the sign of a value (1 if positive, -1 if negative, 0 if 0).
+* log - provides the link:http://en.wikipedia.org/wiki/Natural_logarithm[natural logarithm] of a value.
+* sqrt - provides the link:http://en.wikipedia.org/wiki/Square_root[square root] of a value.
+* invSqrt - provides the inverse square root of a value (1 / sqrt(value).
+
+
+==== Linear Algebra
+
+* LERP - calculate the link:http://en.wikipedia.org/wiki/Linear_interpolation[linear interpolation] of two points given a time between 0 and 1.
+* determinant - calculates the link:http://en.wikipedia.org/wiki/determinant[determinant] of a 4x4 matrix.
+
+
+==== Geometric Functions
+
+* counterClockwise - given three points (defining a triangle), the winding is determined. 1 if counter-clockwise, -1 if clockwise and 0 if the points define a line.
+* pointInsideTriangle - calculates if a point is inside a triangle.
+* sphericalToCartesian - converts a point from link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates] to link:https://en.wikipedia.org/wiki/Cartesian[cartesian coordinates].
+* cartesianToSpherical - converts a point from cartesian coordinates to link:https://en.wikipedia.org/wiki/Spherical_coordinate_system[spherical coordinates].
+
+
+==== Misc.
+
+* newRandomFloat - obtains a random float.
+
+
+== Line
+
+See link:{link-javadoc}/com/jme3/math/Line.html[Line Javadoc]
+
+
+=== Definition
+
+A line is a straight one-dimensional figure having no thickness and extending infinitely in both directions. A line is defined by two points *A* and *B* with the line passing through both.
+
+
+=== Usage
+
+jME defines a Line class that is defined by an origin and direction. In reality, this Line class is typically used as a _line segment_. Where the line is finite and contained between these two points.
+
+`random` provides a means of generate a random point that falls on the line between the origin and direction points.
+
+
+=== Example 1 - Find a Random Point on a Line
+
+[source,java]
+----
+
+Line l = new Line(new Vector3f(0,1,0), new Vector3f(3,2,1));
+Vector3f randomPoint = l.random();
+
+----
+
+
+== Plane
+
+See link:{link-javadoc}/com/jme3/math/Plane.html[Plane Javadoc]
+
+
+=== Definition
+
+A plane is defined by the equation *N* . (*X* - *X~0~*) = 0 where *N* = (a, b, c) and passes through the point *X~0~* = (x~0~, y~0~, z~0~). *X* defines another point on this plane (x, y, z).
+
+*N* . (*X* - *X~0~*) = 0 can be described as (*N* . *X*) + (*N* . -*X~0~*) = 0
+
+or
+
+(ax + by + cz) + (-ax~0~-by~0~-cz~0~) = 0
+
+where (-ax~0~-by~0~-cz~0~) = d
+
+Where d is the negative value of a point in the plane times the unit vector describing the orientation of the plane.
+
+This gives us the general equation: (ax + by + cz + d = 0)
+
+
+=== Usage in jME
+
+jME defines the Plane as ax + by + cz = -d. Therefore, during creation of the plane, the normal of the plane (a,b,c) and the constant d is supplied.
+
+The most common usage of Plane is <<jme3/advanced/camera#,Camera>> frustum planes. Therefore, the primary purpose of Plane is to determine if a point is on the positive side, negative side, or intersecting a plane.
+
+Plane defines the constants:
+
+* `NEGATIVE_SIDE` - represents a point on the opposite side to which the normal points.
+* `NO_SIDE` - represents a point that lays on the plane itself.
+* `POSITIVE_SIDE` - represents a point on the side to which the normal points.
+
+These values are returned on a call to `whichSide`.
+
+
+=== Example 1 - Determining if a Point is On the Positive Side of a Plane
+
+[source,java]
+----
+
+Vector3f normal = new Vector3f(0,1,0);
+float constant = new Vector3f(1,1,1).dot(normal);
+Plane testPlane = new Plane(normal, constant);
+
+int side = testPlane.whichSide(new Vector3f(2,1,0));
+
+if(side == Plane.NO_SIDE) {
+   System.out.println("This point lies on the plane");
+}
+
+----
+
+
+=== Example 2 - For the Layperson
+
+Using the standard constructor Plane(Vector3f normal, float constant), here is what you need to do to create a plane, and then use it to check which side of the plane a point is on.
+
+[source,java]
+----
+
+package test;
+
+import java.util.logging.Logger;
+
+import com.jme.math.*;
+
+/**
+ *@author Nick Wiggill
+ */
+
+public class TestPlanes
+{
+  public static final Logger logger = Logger.getLogger(LevelGraphBuilder.class.getName());
+
+  public static void main(String[] args) throws Exception
+  {
+    //***Outline.
+    //This example shows how to construct a plane representation using
+    //com.jme.math.Plane.
+    //We will create a very simple, easily-imagined 3D plane. It will
+    //be perpendicular to the x axis (it's facing). It's "centre" (if
+    //such a thing exists in an infinite plane) will be positioned 1
+    //unit along the positive x axis.
+
+    //***Step 1.
+    //The vector that represents the normal to the plane, in 3D space.
+    //Imagine a vector coming out of the origin in this direction.
+    //There is no displacement yet (see Step 2, below).
+    Vector3f normal = new Vector3f(5f,0,0);
+
+    //***Step 2.
+    //This is our displacement vector. The plane remains facing in the
+    //direction we've specified using the normal above, but now we are
+    //are actually giving it a position other than the origin.
+    //We will use this displacement to define the variable "constant"
+    //needed to construct the plane. (see step 3)
+    Vector3f displacement = Vector3f.UNIT_X;
+    //or
+    //Vector3f displacement = new Vector3f(1f, 0, 0);
+
+    //***Step 3.
+    //Here we generate the constant needed to define any plane. This
+    //is semi-arcane, don't let it worry you. All you need to
+    //do is use this same formula every time.
+    float constant = displacement.dot(normal);
+
+    //***Step 4.
+    //Finally, construct the plane using the data you have assembled.
+    Plane plane = new Plane(normal, constant);
+
+    //***Some tests.
+    logger.info("Plane info: "+plane.toString()); //trace our plane's information
+
+    Vector3f p1  = new Vector3f(1.1f,0,0); //beyond the plane (further from origin than plane)
+    Vector3f p2  = new Vector3f(0.9f,0,0); //before the plane (closer to origin than plane)
+    Vector3f p3  = new Vector3f(1f,0,0); //on the plane
+
+    logger.info("p1 position relative to plane is "+plane.whichSide(p1)); //outputs NEGATIVE
+    logger.info("p2 position relative to plane is "+plane.whichSide(p2)); //outputs POSITIVE
+    logger.info("p3 position relative to plane is "+plane.whichSide(p3)); //outputs NONE
+  }
+}
+
+----
+
+
+== Ray
+
+See link:{link-javadoc}/com/jme3/math/Ray.html[Ray Javadoc]
+
+
+=== Definition
+
+Ray defines a line that starts at a point *A* and continues in a direction through *B* into infinity.
+
+This Ray is used extensively in jME for <<jme3/beginner/hello_picking#,Picking>>. A Ray is cast from a point in screen space into the scene. Intersections are found and returned. To create a ray supply the object with two points, where the first point is the origin.
+
+
+=== Example 1 - Create a Ray That Represents Where the Camera is Looking
+
+[source,java]
+----
+
+Ray ray = new Ray(cam.getLocation(), cam.getDirection());
+
+----
+
+
+== Rectangle
+
+See link:{link-javadoc}/com/jme3/math/Rectangle.html[Rectangle Javadoc]
+
+
+=== Definition
+
+Rectangle defines a finite plane within three dimensional space that is specified via three points (A, B, C). These three points define a triangle with the forth point defining the rectangle ( (B + C) - A ).
+
+
+=== jME Usage
+
+Rectangle is a straight forward data class that simply maintains values that defines a Rectangle in 3D space. One interesting use is the `random` method that will create a random point on the Rectangle. The <<jme3/advanced/effects_overview#,Particle System>> makes use of this to define an area that generates <<jme3/advanced/particle_emitters#,Particles>>.
+
+
+=== Example 1 : Define a Rectangle and Get a Point From It
+
+[source,java]
+----
+
+Vector3f v1 = new Vector3f(1,0,0);
+Vector3f v2 = new Vector3f(1,1,0);
+Vector3f v3 = new Vector3f(0,1,0);
+Rectangle r = new Rectangle(v1, v2, v3);
+Vector3f point = r.random();
+
+----
+
+
+== Triangle
+
+See link:{link-javadoc}/com/jme3/math/Triangle.html[Triangle Javadoc]
+
+
+=== Definition
+
+A triangle is a 3-sided polygon. Every triangle has three sides and three angles, some of which may be the same. If the triangle is a right triangle (one angle being 90 degrees), the side opposite the 90 degree angle is the hypotenuse, while the other two sides are the legs. All triangles are link:http://en.wikipedia.org/wiki/Convex_polygon[convex] and link:http://mathworld.wolfram.com/BicentricPolygon.html[bicentric].
+
+
+=== Usage
+
+jME's Triangle class is a simple data class. It contains three <<jme3/terminology.html#vectors#,Vector3f>> objects that represent the three points of the triangle. These can be retrieved via the `get` method. The `get` method, obtains the point based on the index provided. Similarly, the values can be set via the `set` method.
+
+
+=== Example 1 - Creating a Triangle
+
+[source,java]
+----
+
+//the three points that make up the triangle
+Vector3f p1 = new Vector3f(0,1,0);
+Vector3f p2 = new Vector3f(1,1,0);
+Vector3f p3 = new Vector3f(0,1,1);
+Triangle t = new Triangle(p1, p2, p3);
+
+----
+
+
+==== Tips and Tricks
+
+
+== How do I get height/width of a spatial?
+
+Cast the spatial to com.jme3.bounding.BoundingBox to be able to use getExtent().
+
+[source,java]
+----
+Vector3f extent = ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f());
+float x = ( (BoundingBox)spatial.getWorldBound()).getXExtent();
+float y = ( (BoundingBox)spatial.getWorldBound()).getYExtent();
+float z = ( (BoundingBox)spatial.getWorldBound()).getZExtent();
+
+----
+
+
+== How do I position the center of a Geomtry?
+
+[source,java]
+----
+geo.center().move(pos);
+----
+
 
-== Local vs Non-local methods?
+=== See Also
 
-*  Non-local method creates new object as return value, v remains unchanged. +
-`v2 = v.mult(); v2 = v.add(); v2 = v.subtract();` etc
-*  Local method changes v directly! +
-`v.multLocal(); v.addLocal(); v.subtractLocal();` etc
+*  <<jme3/rotate#,Rotate>>
+*  <<jme3/quaternion#,Quaternion>>