public override void TimerTestPosition(double elapsedTime) { base.TimerTestPosition(elapsedTime); // Either remember the orig rotation, or restore to that orig rotation (as of PrepareForNew) if (_savedRotation == null) { _savedRotation = this.Rotation.Clone(); } else { this.Rotation.StoreNewValues(_savedRotation); } // Remember the elapsed time that was passed in _elapsedTime = elapsedTime; // Figure out the new rotation (the body has been rotating at some velocity during the previous tick) if (!_angularVelocity.IsZero) { // Figure out what the angle will be double timedAngle = _angularVelocity.GetMagnitude(); timedAngle *= elapsedTime; if (!_centerOfMass.IsZero) { #region Rotate around center of mass // Remember where the center of mass is in world coords MyVector cmRotated = this.Rotation.GetRotatedVector(_centerOfMass, true); MyVector cmWorld = this.Position + cmRotated; // Get the opposite of the cm MyVector posRelativeToCM = cmRotated.Clone(); posRelativeToCM.Multiply(-1d); // Rotate the center of position around the center of mass posRelativeToCM.RotateAroundAxis(_angularVelocity, timedAngle); // Now figure out the new center of position this.Position.X = cmWorld.X + posRelativeToCM.X; this.Position.Y = cmWorld.Y + posRelativeToCM.Y; this.Position.Z = cmWorld.Z + posRelativeToCM.Z; #endregion } // Rotate myself this.RotateAroundAxis(_angularVelocity, timedAngle); } }
protected void GetCollisionNormalAndPointsOfContact_SphereSphere(out MyVector normal, out double normalMagnitude, out MyVector pointOfContact1, out MyVector pointOfContact2, BallBlip ball1, BallBlip ball2) { // Vector that is perpendicular to the tangent of the collision, and it points in the direction of object 1. Real // easy when dealing with spheres :) normal = ball2.Ball.Position - ball1.Ball.Position; // Remember this length normalMagnitude = normal.GetMagnitude(); // This needs to be returned as a unit vector normal.Divide(normalMagnitude); // Start them off as unit vectors pointOfContact1 = normal.Clone(); pointOfContact2 = normal.Clone(); // Finish (use the ratio of their radii) pointOfContact1.Multiply((ball1.Ball.Radius / (ball1.Ball.Radius + ball2.Ball.Radius)) * normalMagnitude); pointOfContact2.Multiply((ball2.Ball.Radius / (ball1.Ball.Radius + ball2.Ball.Radius)) * normalMagnitude * -1); // I want this one pointing the other direction // Now that I have the points of contact relative to the centers of position, I need to make them // relative to the centers of mass if (ball1.TorqueBall != null) { pointOfContact1.Subtract(ball1.TorqueBall.CenterOfMass); } if (ball2.TorqueBall != null) { pointOfContact2.Subtract(ball2.TorqueBall.CenterOfMass); } }