/// <summary>
/// Resets this matrix to a rotation matrix.  The resulting matrix
/// will rotate a point counter-clockwise around the specified axis
/// by the specified angle.
/// </summary>
/// <param name="angle">The angle of rotation in radians.</param>
/// <param name="axis">The orientation of the axis to rotate around.</param>
/// <param name="point">A point on the axis of rotation.</param>
void Matrix3D::SetToRotation(double angle, Vector3D axis, Point3D& point)
{
    // translate the rotation center back to the origin
    SetToTranslation(-point.x, -point.y, -point.z);

    // rotate about the axis at the origin
    Vector3D normalAxis = axis.normal();

    double angle2 = 0.5*angle;
    double x = sin(angle2) * normalAxis.x;
    double y = sin(angle2) * normalAxis.y;
    double z = sin(angle2) * normalAxis.z;
    double w = cos(angle2);

    double twoX = 2.0*x;
    double twoY = 2.0*y;
    double twoZ = 2.0*z;

    double twoWX = w * twoX;
    double twoXX = x * twoX;

    double twoWY = w * twoY;
    double twoXY = x * twoY;
    double twoYY = y * twoY;

    double twoWZ = w * twoZ;
    double twoXZ = x * twoZ;
    double twoYZ = y * twoZ;
    double twoZZ = z * twoZ;

    Matrix3D tempMat = Matrix3D::wkMat3Db;
    tempMat.m00 = 1.0 - (twoYY + twoZZ);
    tempMat.m01 = twoXY - twoWZ;
    tempMat.m02 = twoXZ + twoWY;
    tempMat.m03 = 0.0;
    tempMat.m10 = twoXY + twoWZ;
    tempMat.m11 = 1.0 - (twoXX + twoZZ);
    tempMat.m12 = twoYZ - twoWX;
    tempMat.m13 = 0.0;
    tempMat.m20 = twoXZ - twoWY;
    tempMat.m21 = twoYZ + twoWX;
    tempMat.m22 = 1.0 - (twoXX + twoYY);
    tempMat.m23 = 0.0;
    tempMat.m30 = 0.0;
    tempMat.m31 = 0.0;
    tempMat.m32 = 0.0;
    tempMat.m33 = 1.0;
    PreConcatenate(tempMat);

    // translate back to the center
    tempMat.SetToTranslation(point.x, point.y, point.z);
    PreConcatenate(tempMat);
}
/// <summary>
/// Concatenates a translation matrix to this matrix.
/// </summary>
/// <param name="transX">Distance to translate in the X direction.</param>
/// <param name="transY">Distance to translate in the Y direction.</param>
/// <param name="transZ">Distance to translate in the Z direction.</param>
void Matrix3D::Translate(double transX, double transY, double transZ)
{
    Matrix3D matrix = Matrix3D::wkMat3Da;
    matrix.SetToTranslation(transX, transY, transZ);
    Concatenate(matrix);
}