private void AddBot_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                const double DISTANCE = 3;

                Point3D position = _camera.Position + (_camera.LookDirection.ToUnit() * DISTANCE);
                position += Math3D.GetRandomVector_Spherical(DISTANCE / 3);

                double radius;
                if (chkRandBotSize.IsChecked.Value)
                {
                    double percent = StaticRandom.NextPow(3, isPlusMinus: true);
                    //double percent = StaticRandom.NextBool() ? 1d : -1d;      // use to test the extremes
                    percent *= SWARMBOTRANDSIZEPERCENT;

                    if (percent > 0)
                    {
                        radius = SWARMBOTRADIUS * (1d + percent);
                    }
                    else
                    {
                        radius = SWARMBOTRADIUS / (1d + Math.Abs(percent));
                    }
                }
                else
                {
                    radius = SWARMBOTRADIUS;
                }

                SwarmBot1a bot = new SwarmBot1a(radius, position, _world, _map, _strokes, _material_Bot);

                SetBotConstraints(bot);

                bot.PhysicsBody.AngularVelocity = Math3D.GetRandomVector_Spherical(3d);

                _map.AddItem(bot);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
 public SwarmCluster(SwarmBot1a[] bots)
 {
     this.Bots = bots;
 }
        private void SetBotConstraints(SwarmBot1a bot)
        {
            const double SEARCHSLOPE = .66d;
            const double STROKESEARCHMULT = 2d;
            const double NEIGHBORSLOPE = .75d;
            const double ACCELSLOPE = 1.33d;
            const double ANGACCELSLOPE = .75d;
            const double ANGSPEEDSLOPE = .25d;

            double ratio = bot.Radius / SWARMBOTRADIUS;

            bot.SearchRadius = trkSearchRadius.Value * SetBotConstraints_Mult(SEARCHSLOPE, ratio);
            bot.SearchRadius_Strokes = bot.SearchRadius * STROKESEARCHMULT;
            bot.ChaseNeighborCount = (trkChaseNeighborCount.Value * SetBotConstraints_Mult(NEIGHBORSLOPE, ratio)).ToInt_Round();
            bot.MaxAccel = trkMaxAccel.Value * SetBotConstraints_Mult(ACCELSLOPE, 1 / ratio);
            bot.MaxAngularAccel = trkMaxAngAccel.Value * SetBotConstraints_Mult(ANGACCELSLOPE, 1 / ratio);
            bot.MaxSpeed = trkMaxSpeed.Value;       // not adjusting this, or the swarm will pull apart when they get up to speed
            bot.MaxAngularSpeed = trkMaxAngSpeed.Value * SetBotConstraints_Mult(ANGSPEEDSLOPE, 1 / ratio);
        }