/// <summary> /// This should only be called if _newBallProps.SizeMode is Draw /// </summary> private void ResizeDrawingObject() { // Find the vector from the mousedown point to the current point MyVector fromToLine = _curMousePoint - _mouseDownPoint; // Adjust the radius and mass switch (_mode) { case AddingMode.AddBall: case AddingMode.AddSolidBall: double newValue = fromToLine.GetMagnitude(); if (newValue < MINRADIUS) { newValue = MINRADIUS; } _drawingBall.Radius = newValue; _drawingBall.Mass = UtilityCore.GetMassForRadius(newValue, 1d); break; //case AddingMode.AddRigidBody: // //TODO: I will need to pull all the point masses out proportionatly, as well as change their masses // break; default: throw new ApplicationException("Unknown AddingMode: " + _mode.ToString()); } }
private bool SelectionTest(RadarBlip blip, MyVector point) { // Just worry about spheres for now MyVector line = point - blip.Sphere.Position; return(line.GetMagnitude() <= blip.Sphere.Radius); }
public void StoreNewValue(double x, double y, double z) { // Store what was passed in _vector.X = x; _vector.Y = y; _vector.Z = z; // See if the multiplier needs to be expanded double newMagnitude = _vector.GetMagnitude(); if (newMagnitude > _multiplier) { // I need to set the property so that the appropriate events fire this.Multiplier = newMagnitude * 1.1d; // leave a bit more room for growth } else { // I put this in an else, because setting the multiplier invalidates as well _imageDirty = true; this.Invalidate(); } if (_vector.IsZero) { toolTip1.SetToolTip(this, _vector.ToString(0) + "\nLength = 0"); displayItem1.Text = _vector.ToString(0); displayItem2.Text = "Length = 0"; } else { toolTip1.SetToolTip(this, _vector.ToString(2) + "\nlength = " + _vector.GetMagnitude().ToString("N2")); displayItem1.Text = _vector.ToString(2); displayItem2.Text = "Length = " + _vector.GetMagnitude().ToString("N2"); } // Inform the world OnValueChanged(); }
private void btnAddRigidBody_Click(object sender, EventArgs e) { const int MINPOINTMASSES = 3; const int MAXPOINTMASSES = 8; const double MINPOINTMASSRADIUS = MINRADIUSMASS / MINPOINTMASSES; const double MAXPOINTMASSRADIUS = MAXRADIUSMASS / MAXPOINTMASSES; // Make the chassis RigidBody ball = new RigidBody(Utility3D.GetRandomVector(_boundryLower, _boundryUpper), new DoubleVector(0, -1, 0, -1, 0, 0), .1d, GetElasticity(), 1, 1, _boundryLower, _boundryUpper); int numPointMasses = _rand.Next(MINPOINTMASSES, MAXPOINTMASSES + 1); //double maxOffset = MAXRADIUSMASS - ((MINPOINTMASSRADIUS + MAXPOINTMASSRADIUS) / 2d); // this could result in bodies slightly larger than the other two types, but it should be close double maxOffset = MAXRADIUSMASS - MAXPOINTMASSRADIUS; double ballRadius = ball.Radius; double curRadius; // Add point masses for (int massCntr = 1; massCntr <= numPointMasses; massCntr++) { MyVector pointMassPos = Utility3D.GetRandomVectorSpherical(maxOffset); pointMassPos.Z = 0; // I do this here for the radius calculation below double pointMassMass = MINPOINTMASSRADIUS + (_rand.NextDouble() * (MAXPOINTMASSRADIUS - MINPOINTMASSRADIUS)); // Add a point mass ball.AddPointMass(pointMassPos.X, pointMassPos.Y, 0, pointMassMass); // See if this pushes out the ball's overall radius curRadius = pointMassPos.GetMagnitude() + pointMassMass; // I assume that the pointmass's mass is the same as its radius if (curRadius > ballRadius) { ballRadius = curRadius; } } // Store the new radius ball.Radius = ballRadius * 1.1d; // make it slightly bigger // Set the velocity ball.Velocity.Add(Utility3D.GetRandomVector(MAXVELOCITY)); ball.Velocity.Z = 0; BallBlip blip = new BallBlip(ball, CollisionStyle.Standard, RadarBlipQual.BallUserDefined02, TokenGenerator.NextToken()); _map.Add(blip); }
private MyVector GetSpinVelocityAtPoint(ref AngularVelocityInfo angularInfo, out MyVector dirToCenterLine, MyVector dirFacingWorld, MyVector lineBetween, MyVector blipPosition) { // Get a line that's orthogonal to lineBetween, and always points toward the dirFacingWorld vector dirToCenterLine = MyVector.Cross(MyVector.Cross(lineBetween, dirFacingWorld), lineBetween); dirToCenterLine.BecomeUnitVector(); if (angularInfo == null) { #region Cache Angular Velocity angularInfo = new AngularVelocityInfo(); if (_ship.TorqueBall != null) { angularInfo.AngularVelocity = _ship.TorqueBall.AngularVelocity.GetMagnitude(); angularInfo.SpinDirection = MyVector.Cross(_ship.TorqueBall.AngularVelocity, _ship.TorqueBall.DirectionFacing.Standard); angularInfo.SpinDirection.BecomeUnitVector(); angularInfo.CenterMass = _ship.TorqueBall.Rotation.GetRotatedVector(_ship.TorqueBall.CenterOfMass, true); angularInfo.CenterMass.Add(_ship.TorqueBall.Position); } else { angularInfo.SpinDirection = dirToCenterLine.Clone(); angularInfo.AngularVelocity = 0d; angularInfo.CenterMass = _ship.Ball.Position.Clone(); } #endregion } // Get the line between the blip and the center of mass MyVector lineBetweenCM = blipPosition - angularInfo.CenterMass; // Figure out my velocity of spin where the blip is return(angularInfo.SpinDirection * (angularInfo.AngularVelocity * lineBetweenCM.GetMagnitude())); }
private List <Interaction> GetInteractions_Static(out double totalForce, MyVector centerWorld, MyVector dirFacingWorld) { totalForce = 0d; List <Interaction> retVal = new List <Interaction>(); // This is only used for left/right modes (lazy initialization) AngularVelocityInfo angularInfo = null; // Scan for objects in my path foreach (BallBlip blip in FindBlipsInCone(centerWorld, dirFacingWorld)) { // Get a vector from me to the ball MyVector lineBetween = blip.Ball.Position - centerWorld; double distance = lineBetween.GetMagnitude(); switch (_mode) { case BeamMode.PushPull: #region Push Pull if (!Utility3D.IsNearZero(distance)) { lineBetween.BecomeUnitVector(); lineBetween.Multiply(-1); double relativeVelocity = MyVector.Dot(lineBetween, blip.Ball.Velocity - _ship.Ball.Velocity); // Figure out how much force is required to make this relative velocity equal zero double force = relativeVelocity * blip.Ball.Mass; // Velocity * Mass is impulse force // See if force needs to be limited by the tractor's max force double maxForce = UtilityCore.GetScaledValue(_forceAtZero, _forceAtMax, 0d, _maxDistance, distance); if (Math.Abs(force) > maxForce) { if (force > 0d) { force = maxForce; } else { force = maxForce * -1d; } } // Add to results retVal.Add(new Interaction(blip, lineBetween, force)); totalForce += Math.Abs(force); } #endregion break; case BeamMode.LeftRight: #region Left Right // Only do something if the lines aren't sitting directly on top of each other (even if they want to repel, // I'd be hesitant to just repel in any random direction) if (!Utility3D.IsNearValue(MyVector.Dot(lineBetween, dirFacingWorld, true), 1d)) { // Figure out how fast the ship is spinning where the blip is MyVector dirToCenterLine; MyVector spinVelocity = GetSpinVelocityAtPoint(ref angularInfo, out dirToCenterLine, dirFacingWorld, lineBetween, blip.Ball.Position); // Figure out the relative velocity (between blip and my spin) double relativeVelocity1 = MyVector.Dot(dirToCenterLine, blip.Ball.Velocity - spinVelocity); // Figure out how much force is required to make this relative velocity equal zero double force1 = relativeVelocity1 * blip.Ball.Mass; // Velocity * Mass is impulse force // See if force needs to be limited by the tractor's max force double maxForce1 = UtilityCore.GetScaledValue(_forceAtZero, _forceAtMax, 0d, _maxDistance, distance); if (Math.Abs(force1) > maxForce1) { if (force1 > 0d) { force1 = maxForce1; } else { force1 = maxForce1 * -1d; } } // Add to results retVal.Add(new Interaction(blip, dirToCenterLine, force1)); totalForce += force1; } #endregion break; default: throw new ApplicationException("Unknown BeamMode: " + _mode.ToString()); } } // Exit Function return(retVal); }
private List <Interaction> GetInteractions_Standard(out double totalForce, MyVector centerWorld, MyVector dirFacingWorld) { totalForce = 0d; List <Interaction> retVal = new List <Interaction>(); AngularVelocityInfo tractorAngularInfo = null; // Scan for objects in my path foreach (BallBlip blip in FindBlipsInCone(centerWorld, dirFacingWorld)) { // Get the distance MyVector lineBetween = blip.Sphere.Position - centerWorld; double distance = lineBetween.GetMagnitude(); // Figure out the force to apply double force = UtilityCore.GetScaledValue(_forceAtZero, _forceAtMax, 0d, _maxDistance, distance); force *= _percent; switch (_mode) { case BeamMode.PushPull: #region Push Pull if (!Utility3D.IsNearZero(distance)) { // Turn lineBetween into a unit vector (it will be multiplied by force later) lineBetween.BecomeUnitVector(); if (_isSoft) { force = GetForceForSoft(ref tractorAngularInfo, force, lineBetween, distance, blip.Ball, dirFacingWorld); } // Add this to the return list retVal.Add(new Interaction(blip, lineBetween, force)); totalForce += Math.Abs(force); // percent is negative when in repulse mode } #endregion break; case BeamMode.LeftRight: #region Left Right // Only do something if the lines aren't sitting directly on top of each other (even if they want to repel, // I'd be hesitant to just repel in any random direction) if (!Utility3D.IsNearValue(MyVector.Dot(lineBetween, dirFacingWorld, true), 1d)) { // Get a line that's orthogonal to lineBetween, and always points toward the dirFacingWorld vector MyVector dirToCenterLine = MyVector.Cross(lineBetween, MyVector.Cross(lineBetween, dirFacingWorld)); dirToCenterLine.BecomeUnitVector(); // Add to the return list retVal.Add(new Interaction(blip, dirToCenterLine, force)); totalForce += Math.Abs(force); // percent is negative when in repulse mode } #endregion break; default: throw new ApplicationException("Unknown BeamMode: " + _mode.ToString()); } } // Exit Function return(retVal); }