예제 #1
0
        /// <summary>
        /// WARNING: Don't rotate my direction facing outside of me, we will fall out of sync
        /// </summary>
        public virtual void RotateAroundAxis(MyVector rotateAround, double radians)
        {
            // Avoid mathmatical drift
            _numRotations++;
            if (_numRotations > 10000)
            {
                _numRotations = 0;
                _rotation.BecomeUnitQuaternion();
            }

            // Make a quaternion that holds the axis and radians passed in
            MyQuaternion intermediate = new MyQuaternion(rotateAround, radians);

            // Apply that to my existing one
            _rotation = MyQuaternion.Multiply(intermediate, _rotation);         // it seems counterintuitive to multiply them in this order, but testing shows it doesn't work the other way (and reading some articles confirms the order)

            if (_dirFacingRequested)
            {
                SyncDirFacing();
            }
        }
예제 #2
0
        /// <summary>
        /// This function takes in a destination double vector, and I will tell you how much you need to rotate me in order for me to end up
        /// along that destination double vector.
        /// </summary>
        /// <remarks>
        /// This function is a mutated copy of MyVector.GetAngleBetweenVectors.  It is almost identical, but slightly more complex  :)
        ///
        /// If I am already aligned with the vector passed in, then I will return an arbitrary orthoganal, and an angle of zero.
        /// </remarks>
        /// <param name="destination">This is the double vector you want me to align myself with</param>
        public MyQuaternion GetAngleAroundAxis(DoubleVector destination)
        {
            #region Standard

            // Get the angle
            double rotationRadians = MyVector.GetAngleBetweenVectors(this.Standard, destination.Standard);
            if (Double.IsNaN(rotationRadians))
            {
                rotationRadians = 0d;
            }

            // I need to pull the cross product from me to the vector passed in
            MyVector rotationAxis = MyVector.Cross(this.Standard, destination.Standard);

            // If the cross product is zero, then there are two possibilities.  The vectors point in the same direction, or opposite directions.
            if (rotationAxis.IsNearZero)
            {
                // If I am here, then the angle will either be 0 or PI.
                if (Utility3D.IsNearZero(rotationRadians))
                {
                    // The vectors sit on top of each other.  I will set the orthoganal to an arbitrary value, and return zero for the radians
                    rotationAxis.X  = 1d;
                    rotationAxis.Y  = 0d;
                    rotationAxis.Z  = 0d;
                    rotationRadians = 0d;
                }
                else
                {
                    // The vectors are pointing directly away from each other, because this is a double vector, I must rotate along an axis that
                    // is orthogonal to my standard and orth
                    rotationAxis = this.Orth; //MyVector.Cross(this.Standard, this.Orth);
                }
            }

            MyQuaternion quatStandard = new MyQuaternion(rotationAxis, rotationRadians);



            //return quatStandard;



            #endregion

            // I only need to rotate the orth, because I already know where the standard will be
            MyVector rotatedOrth = quatStandard.GetRotatedVector(this.Orth, true);

            #region Orthogonal

            // Grab the angle
            rotationRadians = MyVector.GetAngleBetweenVectors(rotatedOrth, destination.Orth);
            if (Double.IsNaN(rotationRadians))
            {
                rotationRadians = 0d;
            }

            // Since I've rotated the standards onto each other, the rotation axis of the orth is the standard (asumming it was truely orthogonal
            // to begin with)
            rotationAxis = destination.Standard.Clone();

            MyQuaternion quatOrth = new MyQuaternion(rotationAxis, rotationRadians);

            #endregion

            // Exit Function
            //return MyQuaternion.Multiply(quatOrth, quatStandard);
            return(MyQuaternion.Multiply(quatStandard, quatOrth));
        }