Пример #1
0
        /// <summary>
        /// This function returns a vector that is rotated by the opposite of me
        /// </summary>
        public MyVector GetRotatedVectorReverse(MyVector vector, bool isQuatNormalized)
        {
            if (!isQuatNormalized)
            {
                // I'm not normalized, clone myself and normalize it
                MyQuaternion myUnitClone = new MyQuaternion(this.X, this.Y, this.Z, this.W);
                myUnitClone.BecomeUnitQuaternion();

                return(myUnitClone.GetRotatedVectorReverse(vector, true));
            }

            MyVector qvec = new MyVector(this.X, this.Y, this.Z);

            //Vector uv = qvec.Cross(vector);
            MyVector uv = MyVector.Cross(qvec, vector);

            //Vector uuv = qvec.Cross(uv);
            MyVector uuv = MyVector.Cross(qvec, uv);

            //uv *= (2.0f * quat.w);
            uv.Multiply(this.W * -2d);

            //uuv *= 2.0f;
            uuv.Multiply(2d);

            //return vector + uv + uuv;
            MyVector retVal = vector.Clone();

            retVal.Add(uv);
            retVal.Add(uuv);
            return(retVal);
        }
Пример #2
0
        /// <summary>
        /// The vectors passed in are orientated to the body frame
        /// NOTE: This gets reset at the beginning of each timer tick
        /// </summary>
        /// <remarks>
        /// See Ball.InternalForce's remarks for when you would use this as apposed to ApplyExternalForce()
        /// </remarks>
        /// <param name="offset">
        /// This is the displacement from my center where the force is applied (if you know this is always zero at compile time,
        /// just directly add force to base.InternalForce instead)
        /// </param>
        /// <param name="force">This is the direction and strength of the force being applied</param>
        public void ApplyInternalForce(MyVector offset, MyVector force)
        {
            //TODO: Convert forcePos from being relative to the center of position to being relative to the center of mass

            // Split the force acting on me into rotational and translational
            MyVector translationForce, torque;

            SplitForceIntoTranslationAndTorque(out translationForce, out torque, _centerOfMass, offset, force);

            // Add to my torque
            _internalTorque.Add(torque);

            // Add the translational force to my base
            this.InternalForce.Add(translationForce);
        }
Пример #3
0
        /// <summary>
        /// This function will check to see if I've clipped the box boundry.  If I have, I will change the ChangeInPosition, so that the ball
        /// won't cross the boundry line.
        /// </summary>
        /// <param name="curPositionCloned">The values of this will be changed if there is a boundry collision</param>
        /// <param name="changeInPos">This will get reset if there is a collision with the boundry</param>
        /// <param name="elapsedTime">This is needed to recalculate changeInPos if there is a boundry collision</param>
        private void TimerBoxBoundry(MyVector position, ref MyVector changeInPos, double elapsedTime)
        {
            List <Coords> affectedAxiis = new List <Coords>();

            // Clone the Position in order to start generating the ProposedPosition
            MyVector proposedPosition = this.Position.Clone();

            // Add the change in position to the proposed position to make it a real proposed position
            proposedPosition.Add(changeInPos);

            // Now compare the proposed position with the stated corner stones to see if I went to far
            #region X

            if (proposedPosition.X < _boundingLower.X)
            {
                affectedAxiis.Add(Coords.X);
                position.X = _boundingLower.X;
            }
            else if (proposedPosition.X > _boundingUpper.X)
            {
                affectedAxiis.Add(Coords.X);
                position.X = _boundingUpper.X;
            }

            #endregion
            #region Y

            if (proposedPosition.Y < _boundingLower.Y)
            {
                affectedAxiis.Add(Coords.Y);
                position.Y = _boundingLower.Y;
            }
            else if (proposedPosition.Y > _boundingUpper.Y)
            {
                affectedAxiis.Add(Coords.Y);
                position.Y = _boundingUpper.Y;
            }

            #endregion
            #region Z

            if (proposedPosition.Z < _boundingLower.Z)
            {
                affectedAxiis.Add(Coords.Z);
                position.Z = _boundingLower.Z;
            }
            else if (proposedPosition.Z > _boundingUpper.Z)
            {
                affectedAxiis.Add(Coords.Z);
                position.Z = _boundingUpper.Z;
            }

            #endregion

            if (affectedAxiis.Count > 0)
            {
                // Bounce the ball
                changeInPos = TimerBoxBoundrySprtBounceIt(affectedAxiis, elapsedTime);
            }
        }
Пример #4
0
        /// <summary>
        /// This function will calculate the new velocity based on the current acceleration and elapsed time.  I will store the result back into
        /// my velocity property.
        /// </summary>
        private void TimerSprtVel(double elapsedTime)
        {
            // Clone the current accel
            MyVector changeInVel = _acceleration.Clone();

            // Now make the ChangeInVel a velocity instead of an acceleration by multiplying it by time
            changeInVel.Multiply(elapsedTime);

            // I have the change in velocity, so I will add it to the current velocity in order to make a new velocity
            _velocity.Add(changeInVel);
        }
Пример #5
0
        /// <summary>
        /// This function will compute the new acceleration based on the force pushing against the ball.  The result will overwrite the
        /// current acceleration
        /// </summary>
        private void TimerSprtAccel(MyVector force)
        {
            // Make the PartialAccel into a clone of the force passed in
            MyVector partialAccel = force.Clone();

            // I will divide by mass, and it will no longer be force, it will be change in accel (the property guarantees that mass
            // isn't zero)
            partialAccel.Divide(_mass);

            // Add the partial accel to this ball's accel
            _acceleration.Add(partialAccel);
        }
Пример #6
0
        private void button1_Click(object sender, EventArgs e)
        {
            MyVector v1 = new MyVector(3, 4, 5);

            v1.Add(1, 2, 3);

            v1.BecomeUnitVector();

            MyVector v2 = v1.Clone();

            v2.Multiply(3);

            v1.Divide(3);
        }
Пример #7
0
        /// <summary>
        /// The vectors passed in are orientated to the world frame
        /// NOTE: This gets reset at the beginning of each timer tick
        /// </summary>
        /// <remarks>
        /// See Ball.ExternalForce's remarks for when you would use this as apposed to ApplyInternalForce()
        /// </remarks>
        /// <param name="offset">
        /// This is the displacement from my center where the force is applied (if you know this is always zero at compile time,
        /// just directly add force to base.ExternalForce instead)
        /// </param>
        /// <param name="force">This is the direction and strength of the force being applied</param>
        public void ApplyExternalForce(MyVector offset, MyVector force)
        {
            // Split the force acting on me into rotational and translational
            MyVector translationForce, torque;

            SplitForceIntoTranslationAndTorque(out translationForce, out torque, _centerOfMass, offset, force);

            //System.Windows.Forms.MessageBox.Show(torque.X.ToString() + ", " + torque.Y.ToString() + ", " + torque.Z.ToString());

            // Add to my torque
            _externalTorque.Add(torque);

            // Add the translational force to my base
            this.ExternalForce.Add(translationForce);
        }
Пример #8
0
        private void ApplyTorque(double elapsedTime)
        {
            // Calculate the new angular momentum (current + (torque * time))
            MyVector newMomentum = _internalTorque.Clone();

            newMomentum.Multiply(elapsedTime);
            _angularMomentum.Add(newMomentum);

            // Figure out the inverse of the world frame's inertia tensor
            // (Rotation * bodyInertialTensorInverse * Transposed Rotation)
            MyMatrix3 curRotation = base.RotationMatrix.Clone();
            MyMatrix3 inverseWorldInertiaTensor = MyMatrix3.Multiply(MyMatrix3.Multiply(curRotation, _inertialTensorBodyInverse), MyMatrix3.Transpose(curRotation));

            // Now all that's left is to figure out the new angular velocity
            _angularVelocity.StoreNewValues(MyMatrix3.Multiply(inverseWorldInertiaTensor, _angularMomentum));
        }
Пример #9
0
        /// <summary>
        /// This function returns the addition of internal force and external force.  Before I do that, I need to rotate a copy of internal
        /// force so that it is based off of the same orientation as the external force.
        /// </summary>
        private MyVector TimerSprtCombineForce()
        {
            if (_internalForce.IsZero)
            {
                // Internal force is zero, so there is nothing to rotate (or add)
                return(_externalForce.Clone());
            }

            // The sphere's rotation quaternion already knows how to rotate from internal to external.  So make a copy of
            // internal line up with external.
            MyVector retVal = base.Rotation.GetRotatedVector(_internalForce, true);

            // retVal holds the internal force in the same orientation as the external force.  I will add external force to it, and retVal
            // will hold the net force placed on the ball
            retVal.Add(_externalForce);

            // Exit Function
            return(retVal);
        }
Пример #10
0
        private void Copy()
        {
            if (_mode != SelectionMode.Selected || _selectedObjects.Count == 0)
            {
                return;
            }

            _myClipboard.Clear();
            _clipboardPositionCenter = new MyVector();

            foreach (RadarBlip blip in _map.GetAllBlips())
            {
                if (_selectedObjects.Contains(blip.Token))
                {
                    _myClipboard.Add(Scenes.CloneBlip(blip, _map));
                    _clipboardPositionCenter.Add(blip.Sphere.Position);
                }
            }

            if (_myClipboard.Count > 0)
            {
                _clipboardPositionCenter.Divide(_myClipboard.Count);
            }
        }
Пример #11
0
        /// <summary>
        /// This function prunes the list of positions that are too old.  It then figures out the average velocity
        /// of the remaining positions.
        /// </summary>
        private MyVector TimerSprtCalculateVelocity()
        {
            const int RETENTION = 75;		// milliseconds

            int curTick = Environment.TickCount;

            // Add the current to the list
            _prevMousePositions.Add(new MousePosition(_curMousePoint.Clone()));

            #region Prune List

            int lastIndex = -1;
            for (int cntr = _prevMousePositions.Count - 1; cntr >= 0; cntr--)
            {
                if (curTick - _prevMousePositions[cntr].Tick > RETENTION)
                {
                    // This item is too old.  And since the list is in time order, all the entries before this are also too old
                    lastIndex = cntr;
                    break;
                }
            }

            if (lastIndex >= 0)
            {
                //_prevMousePositions.RemoveRange(lastIndex, _prevMousePositions.Count - lastIndex);
                _prevMousePositions.RemoveRange(0, lastIndex + 1);
            }

            #endregion

            #region Calculate Velocity

            MyVector retVal = new MyVector(0, 0, 0);

            // Add up all the instantaneous velocities
            for (int cntr = 0; cntr < _prevMousePositions.Count - 1; cntr++)
            {
                retVal.Add(_prevMousePositions[cntr + 1].Position - _prevMousePositions[cntr].Position);
            }

            // Take the average
            if (_prevMousePositions.Count > 2)		// if count is 0 or 1, then retVal will still be (0,0,0).  If it's 2, then I would be dividing by 1, which is pointless
            {
                retVal.Divide(_prevMousePositions.Count - 1);
            }

            #endregion

            // Exit Function
            return retVal;
        }