Beispiel #1
0
        private void ChangeSwarmBotsSprtSizeProps(out double radius, out double mass, out double thrustForce, out int numClosestBotsToLookAt, out double visionLimit, double sizeMultiplier)
        {
            const double RADIUS           = .125d;
            const double DENSITY          = 61.115d;    // I want the mass to be .5 when radius is .125:  d = m / (4/3 * pi * r^3)
            const double ACCEL_HALF       = 190d;       // note that these don't scale evenly with mass.  I don't want the acceleration affected that much (I want the acceleration to be 160 when size multiplier is 1)
            const double ACCEL_FOUR       = 130d;
            const double VISIONLIMIT_HALF = 12d;        // middle is 20
            const double VISIONLIMIT_FOUR = 28d;
            const double CLOSECOUNT_HALF  = 2d;
            const double CLOSECOUNT_TWICE = 4d;

            radius = RADIUS * sizeMultiplier;

            // v = 4/3 * pi * r^3
            // m = d * v
            // m = d * 4/3 * pi * r^3
            mass = DENSITY * 4 / 3 * Math.PI * Math.Pow(radius, 3);

            // f = ma
            // a = f / m
            double accel = UtilityCore.GetScaledValue(ACCEL_HALF, ACCEL_FOUR, .5d, 4d, sizeMultiplier);         //NOTE:  not capping it, the min/max are just for scaling

            thrustForce = mass * accel;

            visionLimit = UtilityCore.GetScaledValue(VISIONLIMIT_HALF, VISIONLIMIT_FOUR, .5d, 4d, sizeMultiplier);

            numClosestBotsToLookAt = Convert.ToInt32(Math.Round(UtilityCore.GetScaledValue(CLOSECOUNT_HALF, CLOSECOUNT_TWICE, .5d, 2d, sizeMultiplier)));
            if (numClosestBotsToLookAt < 2)
            {
                numClosestBotsToLookAt = 2;
            }
        }
Beispiel #2
0
        private void trkWestMass_Scroll(object sender, EventArgs e)
        {
            _west.Mass = UtilityCore.GetScaledValue(MINMASS, MAXMASS, trkWestMass.Minimum, trkWestMass.Maximum, trkWestMass.Maximum - trkWestMass.Value);

            if (!_isProgramaticPointMass1D && chkCoupledXMass.Checked)
            {
                _isProgramaticPointMass1D = true;

                // Align 1D
                trkEastMass.Value = trkWestMass.Maximum - trkWestMass.Value;
                trkEastMass_Scroll(this, new EventArgs());

                _isProgramaticPointMass1D = false;

                if (!_isProgramaticPointMass2D && chkCoupledBothMass.Checked)
                {
                    _isProgramaticPointMass2D = true;

                    // Align 2D
                    trkSouthMass.Value = trkEastMass.Value;
                    trkSouthMass_Scroll(this, new EventArgs());

                    _isProgramaticPointMass2D = false;
                }
            }
        }
Beispiel #3
0
        private void trkSouthPos_Scroll(object sender, EventArgs e)
        {
            _south.Y = -1d * UtilityCore.GetScaledValue(MINRADIUS, MAXRADIUS, trkSouthPos.Minimum, trkSouthPos.Maximum, trkSouthPos.Value);

            if (!_isProgramaticPointMass1D && chkCoupledYPos.Checked)
            {
                _isProgramaticPointMass1D = true;

                // Align 1D
                trkNorthPos.Value = trkSouthPos.Maximum - trkSouthPos.Value;
                trkNorthPos_Scroll(this, new EventArgs());

                _isProgramaticPointMass1D = false;

                if (!_isProgramaticPointMass2D && chkCoupledBothPos.Checked)
                {
                    _isProgramaticPointMass2D = true;

                    // Align 2D
                    trkEastPos.Value = trkSouthPos.Value;
                    trkEastPos_Scroll(this, new EventArgs());

                    _isProgramaticPointMass2D = false;
                }
            }
        }
Beispiel #4
0
        private void trkAngularMomentum_Scroll(object sender, EventArgs e)
        {
            double magnitude = UtilityCore.GetScaledValue(MINMOMENTUM, MAXMOMENTUM, trkAngularMomentum.Minimum, trkAngularMomentum.Maximum, trkAngularMomentum.Value);

            _rigidBody.AngularMomentum.StoreNewValues(new MyVector(0, 0, magnitude));

            txtAngularMomentum.Text = _rigidBody.AngularMomentum.Z.ToString();
        }
Beispiel #5
0
        private void trkElapsedTime_Scroll(object sender, EventArgs e)
        {
            const double MINTIME = .01d;
            const double MAXTIME = 10d;

            _elapsedTime = UtilityCore.GetScaledValue(MINTIME, MAXTIME, trkElapsedTime.Minimum, trkElapsedTime.Maximum, trkElapsedTime.Value);

            txtElapsedTime.Text = Math.Round(_elapsedTime, 2).ToString();
        }
Beispiel #6
0
        private void trkThreshold_Scroll(object sender, EventArgs e)
        {
            const double MINPERCENT = .001d;
            const double MAXPERCENT = .999d;

            _map.CollisionHandler.PenetrationThresholdPercent = UtilityCore.GetScaledValue(MINPERCENT, MAXPERCENT, trkThreshold.Minimum, trkThreshold.Maximum, trkThreshold.Value);

            txtThreshold.Text = Math.Round(_map.CollisionHandler.PenetrationThresholdPercent * 100d, 1).ToString() + "%";
        }
Beispiel #7
0
        private void trkPullApartSpring_Scroll(object sender, EventArgs e)
        {
            const double MINVELOCITY = .01d;
            const double MAXVELOCITY = 30d;

            _map.CollisionHandler.PullApartSpringVelocity = UtilityCore.GetScaledValue(MINVELOCITY, MAXVELOCITY, trkPullApartSpring.Minimum, trkPullApartSpring.Maximum, trkPullApartSpring.Value);

            txtPullApartSpring.Text = _map.CollisionHandler.PullApartSpringVelocity.ToString();
        }
Beispiel #8
0
        private void trkVectorFieldSize_Scroll(object sender, EventArgs e)
        {
            const double MINSIZE = 10;
            const double MAXSIZE = 10000;

            double size = UtilityCore.GetScaledValue(MINSIZE, MAXSIZE, trkVectorFieldSize.Minimum, trkVectorFieldSize.Maximum, trkVectorFieldSize.Value);

            _vectorField.SizeX = size;
            _vectorField.SizeY = size;
        }
Beispiel #9
0
        private void trkAngularVelocity_Scroll(object sender, EventArgs e)
        {
            // Calculate the trackbar value
            double scaledValue = UtilityCore.GetScaledValue(_exposedProps.MinRandAngularVelocity, _exposedProps.MaxRandAngularVelocity, trkAngularVelocity.Minimum, trkAngularVelocity.Maximum, trkAngularVelocity.Maximum - trkAngularVelocity.Value);

            toolTip1.SetToolTip(trkAngularVelocity, Math.Round(scaledValue, 2).ToString());

            // I present angular velocity in rotations/frame.  But the torqueball wants it in radians/frame
            _exposedProps.AngularVelocityIfFixed = scaledValue * Math.PI * 2;

            OnValueChanged();
        }
Beispiel #10
0
        private void trkGravityForce_Scroll(object sender, EventArgs e)
        {
            if (_gravController == null)
            {
                return;
            }

            const double MINGRAVITY = 0d;
            const double MAXGRAVITY = 10d;

            _gravController.GravityMultiplier = UtilityCore.GetScaledValue(MINGRAVITY, MAXGRAVITY, trkGravityForce.Minimum, trkGravityForce.Maximum, trkGravityForce.Value);
        }
Beispiel #11
0
        private static double SetBotConstraints_Mult(double slope, double value, double center = 1d)
        {
            // y=mx+b
            // y=mx + (1-m)

            double minX = center / 2d;
            double maxX = center * 2d;

            double minY = (slope * minX) + (center - slope);
            double maxY = (slope * maxX) + (center - slope);

            return(UtilityCore.GetScaledValue(minY, maxY, minX, maxX, value));
        }
Beispiel #12
0
        private static BitmapSource DrawStrokes(IEnumerable <EncogOCR_StrokeDefinition> strokes, int width, int height, double origWidth, double origHeight)
        {
            //NOTE: InkCanvas draws lines smoother than this method.  This is a crude way to approximate the thickness/darkeness of the lines
            double scale  = Math1D.Avg(width, height) / Math1D.Avg(origWidth, origHeight);
            double reduce = 1;

            if (scale < .2)
            {
                reduce = UtilityCore.GetScaledValue(.8, 1, .05, .2, scale);
            }

            RenderTargetBitmap retVal = new RenderTargetBitmap(width, height, UtilityWPF.DPI, UtilityWPF.DPI, PixelFormats.Pbgra32);

            DrawingVisual dv = new DrawingVisual();

            using (DrawingContext ctx = dv.RenderOpen())
            {
                foreach (EncogOCR_StrokeDefinition stroke in strokes)
                {
                    SolidColorBrush brush = new SolidColorBrush(UtilityWPF.ColorFromHex(stroke.Color));

                    if (stroke.Points.Length == 1)
                    {
                        // Single Point
                        double radius = stroke.Thickness / 2d;
                        radius *= reduce;
                        ctx.DrawEllipse(brush, null, stroke.Points[0], radius, radius);
                    }
                    else
                    {
                        // Multiple Points
                        Pen pen = new Pen(brush, stroke.Thickness * reduce)
                        {
                            StartLineCap = PenLineCap.Round,
                            EndLineCap   = PenLineCap.Round,
                        };

                        for (int cntr = 0; cntr < stroke.Points.Length - 1; cntr++)
                        {
                            ctx.DrawLine(pen, stroke.Points[cntr], stroke.Points[cntr + 1]);
                        }
                    }
                }
            }

            dv.Transform = new ScaleTransform(width / origWidth, height / origHeight);

            retVal.Render(dv);

            return(retVal);
        }
Beispiel #13
0
        private void trkSize_Scroll(object sender, EventArgs e)
        {
            if (_exposedProps == null)
            {
                return;
            }

            // Store the value
            _exposedProps.SizeIfFixed = UtilityCore.GetScaledValue(_exposedProps.MinRandSize, _exposedProps.MaxRandSize, trkSize.Minimum, trkSize.Maximum, trkSize.Value);
            toolTip1.SetToolTip(trkSize, _exposedProps.SizeIfFixed.ToString());

            // Raise Event
            OnValueChanged();
        }
Beispiel #14
0
        private Color GetGreenRedColor(double minTarget, double maxTarget, double actualValue, double sizePercent)
        {
            if (sizePercent < .9d)
            {
                return(Color.OliveDrab);
            }
            else
            {
                double derivedMinTarget = UtilityCore.GetScaledValue(minTarget, maxTarget, 0d, 1d, .9d);
                double colorPercent     = UtilityCore.GetScaledValue_Capped(0d, 1d, derivedMinTarget, maxTarget * 3d, actualValue);

                return(UtilityGDI.AlphaBlend(Color.Firebrick, Color.OliveDrab, colorPercent));
            }
        }
Beispiel #15
0
        private void trkStrengthFar_Scroll(object sender, EventArgs e)
        {
            _strengthFar = UtilityCore.GetScaledValue(0, _strengthMax, trkStrengthFar.Minimum, trkStrengthFar.Maximum, trkStrengthFar.Value);

            toolTip1.SetToolTip(trkStrengthFar, _strengthFar.ToString());

            // Apply to tractor beams
            foreach (TractorBeamCone tractor in _shipController.TractorBeams)
            {
                tractor.ForceAtMax = _strengthFar;
            }

            ShipController_ChangeTractorBeamPower(this, new EventArgs());
        }
Beispiel #16
0
        private void trkHeight_Scroll(object sender, EventArgs e)
        {
            double size = UtilityCore.GetScaledValue(0, BOUNDRYMAX, trkHeight.Minimum, trkHeight.Maximum, trkHeight.Value);

            _boundryLower.Y = size * -1d;
            _boundryUpper.Y = size;

            if (chkForceSquare.Checked && trkWidth.Value != trkHeight.Value)
            {
                trkWidth.Value = trkHeight.Value;
                trkWidth_Scroll(this, new EventArgs());
            }

            ShowDimensions();
        }
Beispiel #17
0
        private void trkPullApartPercent_Scroll(object sender, EventArgs e)
        {
            const double MINPERCENT = 1d;
            const double MAXPERCENT = 1.25d;

            try
            {
                _map.CollisionHandler.PullApartInstantPercent = UtilityCore.GetScaledValue(MINPERCENT, MAXPERCENT, trkPullApartPercent.Minimum, trkPullApartPercent.Maximum, trkPullApartPercent.Value);

                txtPullApartPercent.Text = Math.Round(_map.CollisionHandler.PullApartInstantPercent * 100d, 1).ToString() + "%";
            }
            catch (Exception ex)
            {
                // I added caps in the property set
                MessageBox.Show("Had trouble setting property\n\n" + ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
Beispiel #18
0
        private void StoreMouseMove(int x, int y)
        {
            MyVector safe = new MyVector();

            safe.X = UtilityCore.GetScaledValue(_multiplier * -1d, _multiplier, 0, this.Width, x);
            safe.Y = UtilityCore.GetScaledValue(_multiplier * -1d, _multiplier, 0, this.Height, y);

            double safeMultiplier = _multiplier * SAFEPERCENT;          // I don't want to butt up against the multiplier, or store value will increase it on me

            if (safe.GetMagnitudeSquared() > safeMultiplier * safeMultiplier)
            {
                safe.BecomeUnitVector();
                safe.Multiply(safeMultiplier);
            }

            StoreNewValue(safe.X, safe.Y, 0d);
        }
Beispiel #19
0
        private static GradientEntry[] TransformValues(GradientEntry[] orig, double fromDist, double toDist, double fromPerc, double toPerc, bool isUpGraph)
        {
            double percentMinRange = 0;
            double percentMaxRange = 1;

            if (!isUpGraph)
            {
                // The slope is going down, so reverse the min/max
                percentMinRange = 1;
                percentMaxRange = 0;
            }

            return(orig.Select(o => new GradientEntry
                               (
                                   UtilityCore.GetScaledValue(fromDist, toDist, 0, 1, o.Distance),
                                   UtilityCore.GetScaledValue(fromPerc, toPerc, percentMinRange, percentMaxRange, o.Percent)
                               )).
                   ToArray());
        }
Beispiel #20
0
        private void CreateFields()
        {
            _gravityField = new GravityFieldSpace(_map);

            // These two can't deviate too far from each other.  Too much gravity with no swirl will just make a big blob.  Too much swirl with no gravity
            // isn't as bad, but more gravity makes it more interesting
            double gravitationalConstant = UtilityCore.GetScaledValue(.0001d, .0005d, 0d, 1d, StaticRandom.NextDouble());
            double swirlStrength         = UtilityCore.GetScaledValue(50d, 600d, 0d, 1d, StaticRandom.NextDouble());

            double percent = UtilityCore.GetScaledValue(.1d, 1.5d, 0d, 1d, StaticRandom.NextDouble());

            gravitationalConstant *= percent;
            swirlStrength         *= percent;

            _gravityField.GravitationalConstant = gravitationalConstant;

            _gravityField.Swirl   = new GravityFieldSpace.SwirlField(swirlStrength, new Vector3D(0, 0, 1), 10d);
            _gravityField.Boundry = new GravityFieldSpace.BoundryField(.85d, 5000d, 2d, _boundryMin, _boundryMax);
        }
Beispiel #21
0
        /// <summary>
        /// Each hit line should create a cone of probability to place control points onto
        /// Once a point on the surface of a cone is chosen, choose a couple more on that circle
        /// </summary>
        private static Point3D[] GetVoronoiCtrlPoints_AroundLine_Cone(Point3D lineStart, Point3D lineStop, int count, double entryRadius, double exitRadius, double maxAxisLength)
        {
            // Figure out where on the axis the control point ring should go (the bell has a spike around 30% in)
            double axisPercent = StaticRandomWPF.NextBell(_coneAxisBell.Value);

            Vector3D axis       = lineStop - lineStart;
            double   axisLength = axis.Length;

            Point3D ringCenter = lineStart + (axis * axisPercent);

            // Figure out the radius of the cone at this point
            double exitRadiusAdjusted = (axisLength / maxAxisLength) * exitRadius;

            double ringRadius = UtilityCore.GetScaledValue(entryRadius, exitRadiusAdjusted, 0, 1, axisPercent);

            // Get some points
            var points = Enumerable.Range(0, count).
                         Select(o => Math3D.GetRandomVector_Circular_Shell(ringRadius).ToPoint());



            //TODO: Figure out the minimum to shift by
            //double shiftRadius = Math.Max(.01, ringRadius / 20);
            double shiftRadius = ringRadius / 20;

            points = points.Select(o => o + Math3D.GetRandomVector_Spherical(shiftRadius));     // the voronoi can't handle coplanar input



            // Rotate/Translate
            Quaternion roation = Math3D.GetRotation(new Vector3D(0, 0, 1), axis);

            Transform3DGroup transform = new Transform3DGroup();

            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(roation)));
            transform.Children.Add(new TranslateTransform3D(ringCenter.X, ringCenter.Y, ringCenter.Z));

            points = points.Select(o => transform.Transform(o));

            return(points.ToArray());
        }
Beispiel #22
0
        public void Update_AnyThread(double elapsedTime)
        {
            double distance = (this.Bot.PositionWorld - _center).Length;

            double score;

            if (distance < _maxSafeDistance)
            {
                score = 1d;
            }
            else if (distance > _maxUnsafeDistance)
            {
                score = 0d;
            }
            else
            {
                score = 1 - UtilityCore.GetScaledValue(0, 1, _maxSafeDistance, _maxUnsafeDistance, distance);
            }

            _score = (double)_score + (score * elapsedTime);
        }
        private static double[] ConvertToVector_Text_Normalize(int[] number, double numUniqueChars)
        {
            const double WHITESPACEGAP = .15;

            double[] retVal = new double[number.Length];

            for (int cntr = 0; cntr < number.Length; cntr++)
            {
                if (number[cntr] == 0)
                {
                    // Leave it zero
                    continue;
                }

                double percent = number[cntr] / numUniqueChars;

                //NOTE: 1 is actually the smallest value, so the range is from 1/numunique to 1 (so all the values in retVal will be 0 or greater than WHITESPACEGAP)
                retVal[cntr] = UtilityCore.GetScaledValue(WHITESPACEGAP, 1d, 0d, 1d, percent);
            }

            return(retVal);
        }
Beispiel #24
0
        private static Tuple <int, double>[] GetFieldCircle(Point point, double radiusX, double radiusY, double valueCenter, double valueEdge, FluidField2D field)
        {
            // Get the box that contains the return circle
            var center = GetFieldPoint_XY(new Point(point.X, point.Y), field);
            var min    = GetFieldPoint_XY(new Point(point.X - radiusX, point.Y - radiusY), field);
            var max    = GetFieldPoint_XY(new Point(point.X + radiusX, point.Y + radiusY), field);

            // Get points that are inside the circle
            List <Tuple <int, double> > retVal = new List <Tuple <int, double> >();
            Vector radius             = new Vector(radiusX * field.XSize, radiusY * field.YSize);
            double maxDistance        = ((radiusX * field.XSize) + (radiusY * field.YSize)) * .5d; // just take the average.  TODO: see if inside the ellipse
            double maxDistanceSquared = maxDistance * maxDistance;

            for (int x = min.Item1; x <= max.Item1; x++)
            {
                for (int y = min.Item2; y <= max.Item2; y++)
                {
                    double dx = x - center.Item1;
                    double dy = y - center.Item2;
                    double distanceSquared = (dx * dx) + (dy * dy);

                    if (distanceSquared <= maxDistanceSquared)
                    {
                        double distance = Math.Sqrt(distanceSquared);

                        retVal.Add(Tuple.Create(
                                       field.GetK(x, y),                                                            // coordinates that the field wants
                                       UtilityCore.GetScaledValue(valueCenter, valueEdge, 0, maxDistance, distance) // LERP
                                       ));
                    }
                }
            }

            // Exit Function
            return(retVal.ToArray());
        }
Beispiel #25
0
        public static double GetGradientPercent(double distance, GradientEntry[] gradient)
        {
            // See if they are outside the gradient (if so, use that cap's %)
            if (distance <= gradient[0].Distance)
            {
                return(gradient[0].Percent);
            }
            else if (distance >= gradient[gradient.Length - 1].Distance)
            {
                return(gradient[gradient.Length - 1].Percent);
            }

            //  It is inside the gradient.  Find the two stops that are on either side
            for (int cntr = 0; cntr < gradient.Length - 1; cntr++)
            {
                if (distance > gradient[cntr].Distance && distance <= gradient[cntr + 1].Distance)
                {
                    // LERP between the from % and to %
                    return(UtilityCore.GetScaledValue(gradient[cntr].Percent, gradient[cntr + 1].Percent, gradient[cntr].Distance, gradient[cntr + 1].Distance, distance));        //NOTE: Not calling the capped overload, because max could be smaller than min (and capped would fail)
                }
            }

            throw new ApplicationException("Execution should never get here");
        }
Beispiel #26
0
        // these were copied from the 1.53 collision shapes tester
        private void GetRatiosMass(out double x, out double y, out double z, out double mass, CollisionShapeType shape)
        {
            // Ratios
            if (chkRandomRatios.IsChecked.Value)
            {
                x = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, _rand.NextDouble());         // reused as radius
                y = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, _rand.NextDouble());         // reused as height
                z = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, 0d, 1d, _rand.NextDouble());
            }
            else
            {
                x = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkX.Minimum, trkX.Maximum, trkX.Value);
                y = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkY.Minimum, trkY.Maximum, trkY.Value);
                z = UtilityCore.GetScaledValue(MINRATIO, MAXRATIO, trkZ.Minimum, trkZ.Maximum, trkZ.Value);
            }

            switch (shape)
            {
            case CollisionShapeType.Box:
                x   *= 2d;              // sphere treats x as a radius.  box thinks of it as width
                y   *= 2d;
                z   *= 2d;
                mass = x * y * z;
                break;

            case CollisionShapeType.Sphere:
                mass = (4d / 3d) * Math.PI * x * y * z;
                break;

            default:
                throw new ApplicationException("Unexpected CollisionShapeType: " + shape.ToString());
            }

            // If I try to be realistic, then it's boring, so I'll scale the result.  (density shrinks a bit as things get larger)
            mass = UtilityCore.GetScaledValue(MINMASS, MAXMASS, Math.Pow(MINRATIO, 3), Math.Pow(MAXRATIO, 3), mass);
        }
Beispiel #27
0
 private void trkSize_Scroll(object sender, EventArgs e)
 {
     this.ExposedProps.SizeIfFixed = UtilityCore.GetScaledValue(this.ExposedProps.MinRandSize, this.ExposedProps.MaxRandSize, trkSize.Minimum, trkSize.Maximum, trkSize.Value);
     toolTip1.SetToolTip(trkSize, this.ExposedProps.SizeIfFixed.ToString());
 }
Beispiel #28
0
        /// <summary>
        /// This method will adjust the force to keep the relative velocity relativaly small
        /// </summary>
        /// <remarks>
        /// This method needs work.  It would help if I exposed velocity and force lines to be drawn for debugging
        /// </remarks>
        private double GetForceForSoft(ref AngularVelocityInfo angularInfo, double maxForce, MyVector forceDirection, double distance, Ball ball, MyVector dirFacingWorld)
        {
            const double MINVELOCITY = 20d;

            double minVelocity = UtilityCore.GetScaledValue(0, MINVELOCITY, 0, _maxDistance, distance);

            MyVector dummy;
            MyVector tractorVelocity = GetSpinVelocityAtPoint(ref angularInfo, out dummy, dirFacingWorld, _offset, _ship.Ball.Position + _offset);

            tractorVelocity = tractorVelocity + _ship.Ball.Velocity;

            double relativeVelocity = MyVector.Dot(forceDirection, ball.Velocity - tractorVelocity);

            double retVal = maxForce;

            if (maxForce > 0)
            {
                #region Pulling In

                // Positive force means the relative velocity will need to be negative (pulling the object in)

                if (Utility3D.IsNearValue(relativeVelocity, minVelocity * -1d))
                {
                    // It's going the right speed.  No force needed
                    return(0);
                }
                else if (relativeVelocity < (minVelocity * -1d))
                {
                    // It's coming in too fast.  Slow it down
                    retVal = Math.Abs(relativeVelocity) - Math.Abs(minVelocity) * ball.Mass;   // Velocity * Mass is impulse force
                }

                #endregion
            }
            else
            {
                #region Pushing Away

                // Negative force means the relative velocity will need to be positive (pushing the object away)


                if (Utility3D.IsNearValue(relativeVelocity, minVelocity))
                {
                    // It's going the right speed.  No force needed
                    return(0);
                }
                else if (relativeVelocity > minVelocity)
                {
                    // It's going away too fast.  Slow it down
                    retVal = Math.Abs(relativeVelocity) - Math.Abs(minVelocity) * ball.Mass;   // Velocity * Mass is impulse force

                    retVal *= -1d;
                }



                //if (relativeVelocity > MINVELOCITY)
                //{
                //    // It's going fast enough, no need to apply any more force
                //    return 0;
                //}


                // Figure out how much force is required to make this relative velocity equal MINVELOCITY
                //retVal = (relativeVelocity - MINVELOCITY) * ball.Mass;   // Velocity * Mass is impulse force

                #endregion
            }

            // Cap the return the max force
            if (Math.Abs(retVal) > Math.Abs(maxForce))
            {
                if (retVal > 0)
                {
                    retVal = Math.Abs(maxForce);
                }
                else
                {
                    retVal = Math.Abs(maxForce) * -1d;
                }
            }

            // Exit Function
            return(retVal);
        }
Beispiel #29
0
        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);
        }
Beispiel #30
0
        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);
        }