コード例 #1
0
        public static GLTK.Matrix Short3CoordToRotationMatrix(Chunks.Short3Coord xiCoord)
        {
            GLTK.Matrix lRotation = GLTK.Matrix.Rotation(-xiCoord.Z / 1024.0 * Math.PI / 2.0, GLTK.Vector.ZAxis);
            lRotation *= GLTK.Matrix.Rotation(-xiCoord.Y / 1024.0 * Math.PI / 2.0, GLTK.Vector.YAxis);
            lRotation *= GLTK.Matrix.Rotation(-xiCoord.X / 1024.0 * Math.PI / 2.0, GLTK.Vector.XAxis);

            return(lRotation);
        }
コード例 #2
0
        /// <summary>
        /// Converts a GLTK rotation matrix into the MMs representation of a rotation.
        ///
        /// The input matrix must be rotation-only, otherwise the output of this method
        /// is not defined.
        /// </summary>
        public static Chunks.Short3Coord RotationMatrixToShort3Coord(GLTK.Matrix xiRotation)
        {
            // Algorithm is as follows:
            //
            // There are only two degrees of freedom, so one of the coordinates in the
            // vector is redundant.  Therefore we fix one of the coordinates at 0 and
            // solve for the other 2.
            //
            //  * First identify the axis that moves the furthest under the rotation;
            //    this will be the fixed coordinate i.e. we'll rotate about the other
            //    two.
            //  * Next see what effect the rotation has on the axis that moves furthest;
            //    since rotations are defined uniquely by their action on a single point
            //    on the unit ball (apart from the poles) we just need to solve the
            //    simultaneous equations generated by applying rotations of theta and phi
            //    around the two non-fixed axis to this vector.  Note: it is sufficient
            //    to solve only two of the three equations as the third coordinate of the
            //    vector is determined by the other two.

            // see what effect the rotation has on the x and y axes
            GLTK.Vector lNewXAxis = xiRotation * GLTK.Vector.XAxis;
            GLTK.Vector lNewYAxis = xiRotation * GLTK.Vector.YAxis;
            GLTK.Vector lNewZAxis = xiRotation * GLTK.Vector.ZAxis;

            double lXdist = Math.Abs(lNewXAxis * GLTK.Vector.XAxis);
            double lYdist = Math.Abs(lNewYAxis * GLTK.Vector.YAxis);
            double lZdist = Math.Abs(lNewZAxis * GLTK.Vector.ZAxis);

            if (lXdist < lYdist && lXdist < lZdist)
            {
                // x axis has moved the furthest - use (0, y, z) format

                // rotate about z by theta first, then y by phi
                // need to solve cos(theta)*cos(phi) = newx.x; sin(theta) = newx.y
                double lTheta = Math.Asin(-lNewXAxis.y);

                // check which of the possible values for theta is correct
                if (lNewXAxis.x < 0)
                {
                    lTheta = Math.PI - lTheta;
                }

                double lPhi = Math.Acos(lNewXAxis.x / Math.Cos(lTheta));

                // check which of the possible values for phi is correct
                if (lNewXAxis.z < 0)
                {
                    lPhi = -lPhi;
                }

                return(new Chunks.Short3Coord(
                           0,
                           (short)((lPhi / Math.PI) * 2 * 1024),
                           (short)((lTheta / Math.PI) * 2 * 1024)));
            }
            else if (lYdist < lZdist)
            {
                // y axis has moved the furthest - use (x, 0, z) format

                // rotate about z by theta first, then x by phi
                // need to solve -sin(theta) = newy.x; cos(theta)cos(phi) = newy.y
                double lTheta = Math.Asin(lNewYAxis.x);

                // check which of the possible values for theta is correct
                if (lNewYAxis.y < 0)
                {
                    lTheta = Math.PI - lTheta;
                }

                double lPhi = Math.Acos(lNewYAxis.y / Math.Cos(lTheta));

                // check which of the possible values for phi is correct
                if (lNewYAxis.z > 0)
                {
                    lPhi = -lPhi;
                }

                return(new Chunks.Short3Coord(
                           (short)((lPhi / Math.PI) * 2 * 1024),
                           0,
                           (short)((lTheta / Math.PI) * 2 * 1024)));
            }
            else
            {
                // z axis has moved the furthest - use (x, y, 0) format

                // rotate about y by theta first, then x by phi
                // need to solve sin(theta) = newz.x; cos(phi)cos(theta) = newz.z
                double lTheta = Math.Asin(lNewZAxis.x);

                // check which of the possible values for theta is correct
                if (lNewZAxis.z < 0)
                {
                    lTheta = Math.PI - lTheta;
                }

                double lPhi = Math.Acos(lNewZAxis.z / Math.Cos(lTheta));

                // check which of the possible values for phi is correct
                if (lNewZAxis.y < 0)
                {
                    lPhi = -lPhi;
                }

                return(new Chunks.Short3Coord(
                           (short)((lPhi / Math.PI) * 2 * 1024),
                           (short)((lTheta / Math.PI) * 2 * 1024),
                           0));
            }
        }