示例#1
0
        private void button4_Click(object sender, EventArgs e)
        {
            ClearPictureBox();

            // Setup Orig Vector
            MyVector origVector = new MyVector(9, 0, 0);

            DrawVector(origVector, Color.Silver);

            MyQuaternion multiRotationQuat = new MyQuaternion(new MyVector(0, 0, 0), Utility3D.GetDegreesToRadians(0));

            // Rotate around Z
            MyQuaternion anotherRotationQuat = new MyQuaternion(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(1));

            //List<double> lengths = new List<double>();

            for (int outerCntr = 1; outerCntr <= 100000; outerCntr++)
            {
                //lengths.Add(multiRotationQuat.GetMagnitude());
                for (int innerCntr = 1; innerCntr <= 360; innerCntr++)
                {
                    multiRotationQuat = MyQuaternion.Multiply(anotherRotationQuat, multiRotationQuat);
                }
                //multiRotationQuat.BecomeUnitQuaternion();
            }

            // Draw the final output
            MyVector subRotation = multiRotationQuat.GetRotatedVector(origVector, true);

            DrawVector(subRotation, Color.Yellow);
        }
示例#2
0
        private void PropsChangedSprtThrusters()
        {
            if (_type != ShipTypeQual.SolidBall)
            {
                return;  // the ball just has the thruster in the center
            }

            MyVector thrusterSeed = new MyVector(0, _ship.Ball.Radius, 0);
            MyVector zAxis        = new MyVector(0, 0, 1);

            // Bottom Thrusters
            _thrusterOffset_BottomRight = thrusterSeed.Clone();
            _thrusterOffset_BottomRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(_thrusterAngle * -1));

            _thrusterOffset_BottomLeft = thrusterSeed.Clone();
            _thrusterOffset_BottomLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(_thrusterAngle));

            // Top Thrusters
            thrusterSeed             = new MyVector(0, _ship.Ball.Radius * -1, 0);
            _thrusterOffset_TopRight = thrusterSeed.Clone();
            _thrusterOffset_TopRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(_thrusterAngle));

            _thrusterOffset_TopLeft = thrusterSeed.Clone();
            _thrusterOffset_TopLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(_thrusterAngle * -1));
        }
示例#3
0
 private void SetRandomVelocities(double maxVelocity)
 {
     foreach (BallBlip blip in _map.GetAllBlips())
     {
         blip.Ball.Velocity.StoreNewValues(Utility3D.GetRandomVectorSpherical(maxVelocity));
     }
 }
示例#4
0
        private void AddMultiBall(double radius, double mass)
        {
            // Physical Ball
            MyVector     pos       = Utility3D.GetRandomVector(BOUNDRY);
            DoubleVector dirFacing = new DoubleVector(1, 0, 0, 0, 1, 0);

            Ball ball = new Ball(pos, dirFacing, radius, mass, ELASTICITY, KINETICFRICTION, STATICFRICTION, _boundryLower, _boundryUpper);

            BallBlip blip = new BallBlip(ball, CollisionStyle.Standard, RadarBlipQual.BallUserDefined00, TokenGenerator.NextToken());

            _map.Add(blip);

            // WPF Rendering
            Geometry3D      geometry      = UtilityWPF.GetSphere(5, radius);
            Material        material      = new DiffuseMaterial(new SolidColorBrush(Color.FromArgb(255, Convert.ToByte(_rand.Next(256)), Convert.ToByte(_rand.Next(256)), Convert.ToByte(_rand.Next(256)))));
            GeometryModel3D geometryModel = new GeometryModel3D(geometry, material);

            geometryModel.Transform = new Transform3DGroup();

            //TODO:  Tie this transform directly to the ball's velocity (the shpere class should take the transform group)
            Transform3DGroup group = geometryModel.Transform as Transform3DGroup;

            group.Children.Clear();
            group.Children.Add(new TranslateTransform3D(pos.X, pos.Y, pos.Z));

            _geometries.Add(geometryModel);
            _modelGroup.Children.Add(geometryModel);
        }
示例#5
0
 private void btnRandomVelocity_Click(object sender, EventArgs e)
 {
     foreach (BallBlip blip in _map.GetAllBlips())
     {
         blip.Ball.Velocity.StoreNewValues(Utility3D.GetRandomVector(MAXVELOCITY));
         blip.Ball.Velocity.Z = 0;
     }
 }
示例#6
0
        private void RebuildRegion()
        {
            // Wipe out the previous background image
            if (_bitmap != null)
            {
                _bitmap.Dispose();
            }
            _bitmap = null;

            #region Validate Width/Height

            // See if the height and width are unstable
            if (this.Width <= 0 || this.Height <= 0)
            {
                return;
            }

            #endregion

            // Calculate the pie wedge
            _regionPath = new GraphicsPath();

            // Calculate the angle
            double angle = Math.Asin(Convert.ToDouble(Width - Height) / Convert.ToDouble(Width));
            angle = Utility3D.GetRadiansToDegrees(angle);
            angle = 90d - angle;

            // Calculate the base length
            double baseLength = Math.Sqrt((Width * Width) - ((Width - Height) * (Width - Height)));

            // Draw the path
            _regionPath.AddArc(this.Width * -1, 0, this.Width * 2, this.Width * 2, 270, Convert.ToSingle(angle));
            _regionPath.AddLine(Convert.ToSingle(baseLength), Height, 0, Height);
            _regionPath.CloseFigure();          //outline.AddLine(0, Height, 0, 0);

            // Draw my background image
            _bitmap = new Bitmap(this.Width, this.Height);

            //TODO:  Make a gradient forground
            using (Graphics graphics = Graphics.FromImage(_bitmap))
            {
                graphics.SmoothingMode = SmoothingMode.HighQuality;

                graphics.Clear(this.BackColor);

                using (Pen pen = new Pen(SystemColors.ControlDark, 1f))
                {
                    graphics.DrawPath(pen, _regionPath);
                    //graphics.DrawLine(pen, 0, this.Height - 1, this.Width, this.Height - 1);		// the bottom line isn't drawing, so I'll back up a pixel
                }
            }

            // Make me the shape of the pie wedge
            this.Region = new Region(_regionPath);
            this.Refresh();
        }
示例#7
0
        private void btnSpinRandom_Click(object sender, EventArgs e)
        {
            if (_polygon == null)
            {
                MessageBox.Show("No polygon to spin", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            _polygon.AngularMomentum.StoreNewValues(Utility3D.GetRandomVector(MOMENTUM));
        }
示例#8
0
        private void trkSweepAngle_Scroll(object sender, EventArgs e)
        {
            toolTip1.SetToolTip(trkSweepAngle, trkSweepAngle.Value.ToString());

            _sweepAngle = Utility3D.GetDegreesToRadians(trkSweepAngle.Value);

            foreach (TractorBeamCone tractor in _shipController.TractorBeams)
            {
                tractor.SweepAngle = _sweepAngle;
            }
        }
示例#9
0
        private void btnSpinZ_Click(object sender, EventArgs e)
        {
            if (_polygon == null)
            {
                MessageBox.Show("No polygon to spin", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            _polygon.AngularMomentum.X = 0;
            _polygon.AngularMomentum.Y = 0;
            _polygon.AngularMomentum.Z = Utility3D.GetNearZeroValue(MOMENTUM);
        }
示例#10
0
        private void btnGravBallRandomSpeed_Click(object sender, EventArgs e)
        {
            const double MAXSPEED = 40;

            Random rand = new Random();

            foreach (Ball gravBall in _gravityBalls)
            {
                MyVector newVelocity = Utility3D.GetRandomVector(MAXSPEED);
                newVelocity.Z = 0;
                gravBall.Velocity.StoreNewValues(newVelocity);
            }
        }
示例#11
0
        private void chkIncludeShip_CheckedChanged(object sender, EventArgs e)
        {
            const double THRUSTERANGLE = 75;

            if (chkIncludeShip.Checked)
            {
                if (_ship == null)
                {
                    #region Create Ship

                    // Set up the ship
                    double    radius = MINRADIUSMASS + (_rand.NextDouble() * (MAXRADIUSMASS - MINRADIUSMASS));
                    SolidBall ship   = new SolidBall(Utility3D.GetRandomVector(_boundryLower, _boundryUpper), new DoubleVector(0, 1, 0, 1, 0, 0), radius, GetMass(radius), GetElasticity(), 1, 1, _boundryLower, _boundryUpper);

                    // Set up the thrusters
                    MyVector thrusterSeed = new MyVector(0, ship.Radius, 0);
                    MyVector zAxis        = new MyVector(0, 0, 1);

                    // Bottom Thrusters
                    _shipThrusterOffset_BottomRight = thrusterSeed.Clone();
                    _shipThrusterOffset_BottomRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(THRUSTERANGLE * -1));

                    _shipThrusterOffset_BottomLeft = thrusterSeed.Clone();
                    _shipThrusterOffset_BottomLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(THRUSTERANGLE));

                    // Top Thrusters
                    thrusterSeed = new MyVector(0, ship.Radius * -1, 0);
                    _shipThrusterOffset_TopRight = thrusterSeed.Clone();
                    _shipThrusterOffset_TopRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(THRUSTERANGLE));

                    _shipThrusterOffset_TopLeft = thrusterSeed.Clone();
                    _shipThrusterOffset_TopLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(THRUSTERANGLE * -1));

                    // Add to the map
                    _ship = new BallBlip(ship, CollisionStyle.Standard, RadarBlipQual.BallUserDefined03, TokenGenerator.NextToken());
                    _map.Add(_ship);

                    #endregion
                }
            }
            else
            {
                if (_ship != null)
                {
                    _map.Remove(_ship.Token);
                    _ship = null;
                }
            }
        }
示例#12
0
        private void btnAddSolidBall_Click(object sender, EventArgs e)
        {
            double radius     = _rand.Next(Convert.ToInt32(MINRADIUSMASS), Convert.ToInt32(MAXRADIUSMASS));
            double mass       = GetMass(radius);
            double elasticity = GetElasticity();

            SolidBall ball = new SolidBall(Utility3D.GetRandomVector(_boundryLower, _boundryUpper), new DoubleVector(0, 1, 0, 1, 0, 0), radius, mass, elasticity, 1, 1, _boundryLower, _boundryUpper);

            ball.Velocity.Add(Utility3D.GetRandomVector(MAXVELOCITY));
            ball.Velocity.Z = 0;

            BallBlip blip = new BallBlip(ball, CollisionStyle.Standard, RadarBlipQual.BallUserDefined01, TokenGenerator.NextToken());

            _map.Add(blip);
        }
示例#13
0
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            _prevRadians    = _currentRadians;
            _currentRadians = Utility3D.GetDegreesToRadians(trackBar1.Value);

            #region Draw Current

            Graphics graphics = pictureBox2.CreateGraphics();
            graphics.Clear(pictureBox1.BackColor);

            DrawVector(graphics, _sphere.Position, _sphere.Position + (_sphere.DirectionFacing.Standard * 100d), Color.White);
            DrawVector(graphics, _sphere.Position, _sphere.Position + (_sphere.DirectionFacing.Orth * 100d), Color.Silver);

            MyVector rotatedOffset = _sphere.Rotation.GetRotatedVector(_offset, true);

            DrawVector(graphics, _sphere.Position, _sphere.Position + rotatedOffset, Color.Orange);
            DrawDot(graphics, _sphere.Position + rotatedOffset, 3, Color.Gold);

            #endregion

            double radians = _currentRadians - _prevRadians;

            if (radOffset.Checked)
            {
                // Remember where the offset is in world coords
                MyVector offsetRotated = _sphere.Rotation.GetRotatedVector(_offset, true);
                MyVector offsetWorld   = _sphere.Position + offsetRotated;

                DrawDot(graphics, offsetWorld, 5, Color.DodgerBlue);

                // Get the opposite of the local offset
                MyVector posRelativeToOffset = offsetRotated.Clone();
                posRelativeToOffset.Multiply(-1d);

                // Rotate the center of position around the center of mass
                posRelativeToOffset.RotateAroundAxis(_rotationAxis, radians);

                // Now figure out the new center of position
                _sphere.Position.X = offsetWorld.X + posRelativeToOffset.X;
                _sphere.Position.Y = offsetWorld.Y + posRelativeToOffset.Y;
                _sphere.Position.Z = offsetWorld.Z + posRelativeToOffset.Z;
            }

            _sphere.RotateAroundAxis(_rotationAxis, radians);
        }
示例#14
0
        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);
        }
示例#15
0
        private void CreateGravityBall(Random rand)
        {
            const int MINMASS  = 500;
            const int MAXMASS  = 5000;
            const int MINCOLOR = 75;

            // Figure out ball properties
            int          radius    = rand.Next(100, 500);
            MyVector     position  = Utility3D.GetRandomVector(_boundryLower, _boundryUpper);
            DoubleVector dirFacing = new DoubleVector(new MyVector(1, 0, 0), new MyVector(0, 1, 0));
            int          mass      = rand.Next(MINMASS, MAXMASS);

            double massPercent = Convert.ToDouble(mass - MINMASS) / Convert.ToDouble(MAXMASS - MINMASS);
            int    colorValue  = MINCOLOR + Convert.ToInt32((255 - MINCOLOR) * massPercent);

            // Make the ball
            _gravityBalls.Add(new Ball(position, dirFacing, radius, mass, _boundryLower, _boundryUpper));
            _gravityBallColors.Add(Color.FromArgb(colorValue, colorValue, colorValue));
        }
示例#16
0
        private void PropsChangedSprtGuns()
        {
            //TODO:  Change the size and pain of the projectiles based on the size of the ship

            // Cannon
            _cannon.Barrels[0].Offset.BecomeUnitVector();
            _cannon.Barrels[0].Offset.Multiply(_ship.Ball.Radius + (_cannon.ProjectileRadius * 1.5d));
            _cannon.IgnoreOtherProjectiles = _ignoreOtherProjectiles;

            // Machine Guns
            MyVector zAxis   = new MyVector(0, 0, 1);
            MyVector gunSeed = new MyVector(0, _ship.Ball.Radius + (_machineGuns[0].ProjectileRadius * 1.5d), 0);
            bool     isLeft  = true;

            foreach (ProjectileWeapon weapon in _machineGuns)
            {
                // Misc
                weapon.IgnoreOtherProjectiles = _ignoreOtherProjectiles;

                double gunAngle = _machineGunAngle;
                if (isLeft)
                {
                    gunAngle *= -1;
                }

                // Offset
                weapon.Barrels[0].Offset.StoreNewValues(gunSeed);
                weapon.Barrels[0].Offset.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(gunAngle));

                // Rotation
                if (_isMachineGunCrossoverInfinity)
                {
                    weapon.Barrels[0].Rotation.StoreNewValues(new MyQuaternion(zAxis, 0));
                }
                else
                {
                    weapon.Barrels[0].Rotation.StoreNewValues(GetCrossoverRotation(weapon.Barrels[0].Offset, _machineGunCrossoverDistance, _ship.Ball.Radius, isLeft));
                }

                isLeft = false;
            }
        }
示例#17
0
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            MyVector thrusterSeed = new MyVector(0, _ship.Radius, 0);
            MyVector zAxis        = new MyVector(0, 0, 1);
            double   angle        = trackBar1.Value;

            // Bottom Thrusters
            _shipThrusterOffset_BottomRight = thrusterSeed.Clone();
            _shipThrusterOffset_BottomRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(angle * -1));

            _shipThrusterOffset_BottomLeft = thrusterSeed.Clone();
            _shipThrusterOffset_BottomLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(angle));

            // Top Thrusters
            thrusterSeed = new MyVector(0, _ship.Radius * -1, 0);
            _shipThrusterOffset_TopRight = thrusterSeed.Clone();
            _shipThrusterOffset_TopRight.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(angle));

            _shipThrusterOffset_TopLeft = thrusterSeed.Clone();
            _shipThrusterOffset_TopLeft.RotateAroundAxis(zAxis, Utility3D.GetDegreesToRadians(angle * -1));
        }
示例#18
0
        private void trackBar_Scroll(object sender, EventArgs e)
        {
            // Figure out the vector to rotate around
            MyVector rotateAround = new MyVector(trkXAxis.Value, trkYAxis.Value, trkZAxis.Value);

            if (rotateAround.X == 0 && rotateAround.Y == 0 && rotateAround.Z == 0)
            {
                pictureBox1.CreateGraphics().Clear(Color.Tomato);
                return;
            }

            // Rotate a vector
            MyVector rotatedVector = new MyVector(9, 0, 0);

            rotatedVector.RotateAroundAxis(rotateAround, Utility3D.GetDegreesToRadians(trackBar1.Value));

            // Draw it
            ClearPictureBox();
            DrawVector(rotateAround, Color.LightSteelBlue);
            DrawVector(rotatedVector, Color.GhostWhite);
        }
示例#19
0
        public void FillPie(Brush brush, MyVector centerPoint, double radius, MyVector centerLine, double sweepRadians)
        {
            // Turn the centerline and sweep radians into angles that GDI likes
            MyVector dummy = new MyVector(1, 0, 0);
            double   startDegrees;

            dummy.GetAngleAroundAxis(out dummy, out startDegrees, centerLine);
            startDegrees = Utility3D.GetRadiansToDegrees(startDegrees);

            if (centerLine.Y < 0)
            {
                startDegrees *= -1;
            }

            double sweepDegrees = Utility3D.GetRadiansToDegrees(sweepRadians);

            startDegrees -= sweepDegrees / 2d;

            // Call my overload
            FillPie(brush, centerPoint, radius, startDegrees, sweepDegrees);
        }
示例#20
0
        private void button5_Click(object sender, EventArgs e)
        {
            // This button tests TorqueBall.OrthonormalizeOrientation



            ClearPictureBox();

            // Setup Orig Vector
            MyVector origVector = new MyVector(9, 0, 0);

            DrawVector(origVector, Color.Silver);

            // Rotate around Z
            MyQuaternion rotationQuat = new MyQuaternion(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(30));

            MyVector rotated = rotationQuat.GetRotatedVector(origVector, true);

            DrawVector(rotated, Color.Black);

            MyMatrix3 rotationMatrix = rotationQuat.ToMatrix3FromUnitQuaternion();



            // See if this affects the rotation matrix
            TorqueBall.OrthonormalizeOrientation(rotationMatrix);



            rotationQuat = null;
            rotationQuat = new MyQuaternion();
            rotationQuat.FromRotationMatrix(rotationMatrix);

            rotationMatrix = null;


            // Draw the results
            rotated = rotationQuat.GetRotatedVector(origVector, true);
            DrawVector(rotated, Color.DodgerBlue);
        }
示例#21
0
        private void btnAdd_Click(object sender, EventArgs e)
        {
            const int    MINMASS     = 10;
            const int    MAXMASS     = 1000;
            const int    MINCOLOR    = 75;
            const double MAXVELOCITY = 7;

            // Figure out ball properties
            int          radius        = _rand.Next(2, 31);
            MyVector     position      = Utility3D.GetRandomVector(new MyVector(radius, radius, 0), new MyVector(pictureBox1.Width - radius, pictureBox1.Height - radius, 0));
            DoubleVector dirFacing     = new DoubleVector(new MyVector(1, 0, 0), new MyVector(0, 1, 0));
            int          mass          = _rand.Next(MINMASS, MAXMASS);
            MyVector     boundingLower = new MyVector(0, 0, -1);
            MyVector     boundingUpper = new MyVector(pictureBox1.Width, pictureBox1.Height, 1);

            double massPercent = Convert.ToDouble(mass - MINMASS) / Convert.ToDouble(MAXMASS - MINMASS);
            int    colorValue  = MINCOLOR + Convert.ToInt32((255 - MINCOLOR) * massPercent);

            // Make the ball
            _balls.Add(new Ball(position, dirFacing, radius, mass, boundingLower, boundingUpper));

            // Calculate the shell color
            if (chkRandVelocity.Checked)
            {
                _balls[_balls.Count - 1].Velocity.Add(Utility3D.GetRandomVector(MAXVELOCITY));
            }

            _ballColors.Add(Color.FromArgb(colorValue, colorValue, colorValue));

            // Make a tail
            _ballTails.Add(new Trail(100));
            _ballTails[_ballTails.Count - 1].SetColors(Color.MediumOrchid, Color.Black);
            _ballTails[_ballTails.Count - 1].SetWidths(3f, 1f);

            // Make sure the checkbox is checked
            if (!chkRunningGravBalls.Checked)
            {
                chkRunningGravBalls.Checked = true;
            }
        }
示例#22
0
        private void btnRotationMatrix_Click(object sender, EventArgs e)
        {
            ClearPictureBox();

            // Setup Orig Vector
            MyVector origVector = new MyVector(9, 0, 0);

            DrawVector(origVector, Color.Silver);

            // Rotate around Z
            MyQuaternion rotationQuat = new MyQuaternion(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(30));

            MyVector rotated = rotationQuat.GetRotatedVector(origVector, true);

            DrawVector(rotated, Color.Black);

            MyMatrix3 rotationMatrix;

            for (int cntr = 1; cntr <= 10000000; cntr++)
            {
                rotationMatrix = rotationQuat.ToMatrix3FromUnitQuaternion();

                rotationQuat = null;
                rotationQuat = new MyQuaternion();
                rotationQuat.FromRotationMatrix(rotationMatrix);

                rotationMatrix = null;
            }


            rotated = rotationQuat.GetRotatedVector(origVector, true);
            DrawVector(rotated, Color.DodgerBlue);

            rotationQuat.W *= -1;
            MyVector rotatedNegated = rotationQuat.GetRotatedVector(origVector, true);

            DrawVector(rotatedNegated, Color.Yellow);
        }
示例#23
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);
        }
示例#24
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);
        }
示例#25
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);
        }
示例#26
0
        private Ball BuildObject()
        {
            double radius;

            #region Calculate Radius

            switch (_newBallProps.SizeMode)
            {
            case BallProps.SizeModes.Draw:
                radius = .01d;                  // this function will only get called during mouse down if it's in draw mode, so I need to start with an arbitrarily small radius
                break;

            case BallProps.SizeModes.Fixed:
                radius = _newBallProps.SizeIfFixed;
                break;

            case BallProps.SizeModes.Random:
                radius = _rand.Next(Convert.ToInt32(_newBallProps.MinRandSize), Convert.ToInt32(_newBallProps.MaxRandSize));
                break;

            default:
                throw new ApplicationException("Unknown BallProps.SizeModes: " + _newBallProps.SizeMode);
            }

            if (radius < MINRADIUS)
            {
                radius = MINRADIUS;
            }

            #endregion

            double mass = UtilityCore.GetMassForRadius(radius, 1d);

            MyVector velocity;
            #region Calculate Velocity

            if (_newBallProps.RandomVelocity)
            {
                velocity = Utility3D.GetRandomVectorSpherical2D(_newBallProps.MaxVelocity);
            }
            else
            {
                velocity = _newBallProps.Velocity;              // no need to clone it.  I won't manipulate it
            }

            #endregion

            //TODO:  Listen to global props
            double elasticity      = .75d;
            double kineticFriction = .75d;
            double staticFriction  = 1d;

            Ball retVal;
            #region Build the ball

            switch (_mode)
            {
            case AddingMode.AddBall:
                #region Create Ball

                retVal = new Ball(_curMousePoint.Clone(), new DoubleVector(0, 1, 0, 1, 0, 0), radius, mass, elasticity, kineticFriction, staticFriction, _boundryLower, _boundryUpper);
                retVal.Velocity.Add(velocity);

                #endregion
                break;

            case AddingMode.AddSolidBall:
                #region Create Solid Ball

                retVal = new SolidBall(_curMousePoint.Clone(), new DoubleVector(0, 1, 0, 1, 0, 0), radius, mass, elasticity, kineticFriction, staticFriction, _boundryLower, _boundryUpper);
                retVal.Velocity.Add(velocity);
                //StoreAngularVelocity(retVal);		// no reason to do this here.  it will be applied during commit (if I'm in draw mode, the size will change, and the angular velocity will need to be reapplied anyway)

                #endregion
                break;

            default:
                throw new ApplicationException("Unsupported AddingMode: " + _mode.ToString());
            }

            #endregion

            // Exit Function
            return(retVal);
        }
示例#27
0
        private void PropsChangedSprtNew()
        {
            MyVector position = null;

            // Kill Existing
            if (_ship != null)
            {
                position = _ship.Ball.Position.Clone();
                _map.Remove(_ship.Token);
                _ship = null;
            }
            else
            {
                position = Utility3D.GetRandomVector(_boundryLower, _boundryUpper);
            }

            _tractorBeams.Clear();
            _cannon = null;
            _machineGuns.Clear();

            #region New Ship

            //TODO:  Listen to global props
            double elasticity      = .75d;
            double kineticFriction = .75d;
            double staticFriction  = 1d;

            // Build New
            Ball          newBall;
            RadarBlipQual blipQual;        // logic came from BallAdder.CommitObject

            switch (_type)
            {
            case ShipTypeQual.None:
                return;

            case ShipTypeQual.Ball:
                #region Ball

                newBall = new Ball(position, new DoubleVector(0, 1, 0, 1, 0, 0), _shipSize, UtilityCore.GetMassForRadius(_shipSize, 1d), elasticity, kineticFriction, staticFriction, _boundryLower, _boundryUpper);

                blipQual = RadarBlipQual.BallUserDefined00;

                _thrustForce = GetThrustForce(newBall.Mass);
                _torqueballLeftRightThrusterForce = _thrustForce;

                #endregion
                break;

            case ShipTypeQual.SolidBall:
                #region Solid Ball

                newBall = new SolidBall(position, new DoubleVector(0, 1, 0, 1, 0, 0), _shipSize, UtilityCore.GetMassForRadius(_shipSize, 1d), elasticity, kineticFriction, staticFriction, _boundryLower, _boundryUpper);

                blipQual = RadarBlipQual.BallUserDefined01;

                _thrustForce = GetThrustForce(newBall.Mass);
                _torqueballLeftRightThrusterForce = GetLeftRightThrusterMagnitude(((SolidBall)newBall).InertialTensorBody);

                #endregion
                break;

            default:
                throw new ApplicationException("Unknown ShipTypeQual: " + _type.ToString());
            }

            newBall.RotateAroundAxis(new MyVector(0, 0, 1), Math.PI);

            // Finish Building
            _ship = new BallBlip(newBall, CollisionStyle.Standard, blipQual, _blipToken);
            _map.Add(_ship);

            #endregion

            if (this.CreateNewTractorBeams != null)
            {
                this.CreateNewTractorBeams(this, new EventArgs());
            }

            #region Guns

            _cannon = new ProjectileWeapon(300, 150, UtilityCore.GetMassForRadius(150, 1d), 25, true, _ignoreOtherProjectiles, RadarBlipQual.Projectile, false, _map, _boundryLower, _boundryUpper);
            _cannon.AddBarrel(_ship.Ball.OriginalDirectionFacing.Standard.Clone());
            _cannon.AddFiringMode(20);
            _cannon.SetProjectileExplosion(450, 2, 10000);
            _cannon.SeProjectileFuse(500);
            _cannon.SetShip(_ship);

            for (int cntr = 0; cntr < 2; cntr++)
            {
                ProjectileWeapon weapon = new ProjectileWeapon(30, 20, UtilityCore.GetMassForRadius(20, 1d), 100, true, _ignoreOtherProjectiles, RadarBlipQual.Projectile, false, _map, _boundryLower, _boundryUpper);
                weapon.AddBarrel(new MyVector(), new MyQuaternion());
                weapon.AddFiringMode(2);
                weapon.SetProjectileExplosion(40, 2, 300);
                weapon.SeProjectileFuse(500);
                weapon.SetShip(_ship);

                _machineGuns.Add(weapon);
            }

            #endregion
        }
示例#28
0
文件: Main.cs 项目: Ongoza/pTest2
    private GameObject modalWindow; // a modal window object

    void Start()
    {
        int checkGyro = 0; trDirect = false;

        // pass gyroscope cheking in editor mode
        #if UNITY_EDITOR
        checkGyro = 1;
        #else
        if (SystemInfo.supportsGyroscope)
        {
            checkGyro = 1;
        }
        #endif

        GameObject ObjEventSystem = GameObject.Find("GvrEventSystem");
        runText = GameObject.Find("run").GetComponent <Text>();
        if (ObjEventSystem)
        {
            SceneEventSystem = ObjEventSystem.GetComponent <EventSystem>();
            // if (SceneEventSystem) { SceneEventSystem.enabled = false; }
        }
        else
        {
            Debug.Log("Can not find Event System");
        }
        // Camera.main.GetComponent<GvrPointerPhysicsRaycaster>().enabled = false;
        GameObject camTimedPointer = GameObject.Find("GvrReticlePointer");
        timedPointer = camTimedPointer.GetComponent <Renderer>().material;
        string lng = Application.systemLanguage.ToString();
        if (Data.isLanguge(lng))
        {
            userLang = lng;
        }
        //userLang = "Spanish";
        utility    = new Utility(this, isDebug);
        utility3D  = new Utility3D(this, utility);
        colorTest  = new ColorTest(this, utility);
        camFade    = GameObject.Find("camProtector");
        connection = new Connection(Data.getConnectionData()["ServerIP"] + ":" + Data.getConnectionData()["ServerPort"], isNet, utility);
        string deviceDesc = "";

        try
        { deviceDesc = "#_" + SystemInfo.deviceModel + ",#_" + SystemInfo.deviceType + ",#_" + SystemInfo.deviceName + ",#_" + SystemInfo.operatingSystem; }catch (System.Exception e) { Debug.Log(e); }
        //Debug.Log("deviceDesc: " + deviceDesc + connection.deviceUUID);
        //utility.logDebug("Init");
        userData = new UserData()
        {
            name       = "", email = "", birth = "", gender = "",
            input      = Input.touchSupported.ToString(),
            zone       = System.TimeZoneInfo.Local.ToString(),
            deviceID   = connection.deviceUUID,
            lang       = userLang, ip = "",
            txtVersion = Data.getVersion(),
            gyro       = checkGyro,
            deviceInfo = deviceDesc
        };
        gmArrow = GameObject.Find("Arrow");
        if (gmArrow)
        {
            gmArrow.GetComponent <Image>().enabled = true;
            gmArrow.SetActive(false);
        }
        initTestData();
        if (sendDatafromFile)
        {
            testConnection();
        }
        //Debug.Log("start "+trDirect);
        if (checkGyro > 0)
        {
            StartCoroutine(utility.FadeScene(1f, true, new Color(0.2f, 0.2f, 0.2f, 1), checkGyro));
        }
        else
        {
            //StartCoroutine(utility.PauseInit(7,0));
            if (SceneEventSystem)
            {
                SceneEventSystem.enabled = true;
            }
            rootObj         = utility.CreateCanvas("rootMenu", new Vector3(0, -2, 4), new Vector2(400, 100));
            runText.enabled = true;
            runText.text    = Data.getMessage(userLang, "gyroWarn");
            utility.CreateButton(rootObj.transform, "Start", Data.getMessage(userLang, "btnNext"), "StartGyro", "", new Vector3(0, 0, 0), new Vector2(200, 60));
            //rootObj = utility.ShowMessage(Data.getMessage(userLang, "gyroWarn"), "Next", Data.getMessage(userLang, "btnStart"), new Vector2(1200, 400), TextAnchor.MiddleCenter, new Vector2(0, 40));
            //Camera.main.GetComponent<GvrPointerPhysicsRaycaster>().enabled = true;
            SceneEventSystem.enabled = true;
            curScene = -1;
        }
    }
示例#29
0
        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == displayItem1)
            {
                // Do nothing
            }
            else if (e.ClickedItem == btnNormalize)
            {
                #region Normalize

                if (_vector.IsZero)
                {
                    MessageBox.Show("The vector is zero length.  It can't be normalized.", "Context Menu Click", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    StoreNewValue(MyVector.BecomeUnitVector(_vector));
                }

                #endregion
            }
            else if (e.ClickedItem == btnMaximize)
            {
                #region Maximize

                if (_vector.IsZero)
                {
                    MessageBox.Show("The vector is zero length.  It can't be maximized.", "Context Menu Click", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    MyVector newVect = MyVector.BecomeUnitVector(_vector);
                    newVect.Multiply(_multiplier);

                    StoreNewValue(newVect);
                }

                #endregion
            }
            else if (e.ClickedItem == btnRandom)
            {
                StoreNewValue(Utility3D.GetRandomVectorSpherical2D(_multiplier * SAFEPERCENT));         // go under just to be safe
            }
            else if (e.ClickedItem == btnNegate)
            {
                StoreNewValue(_vector.X * -1d, _vector.Y * -1d, _vector.Z * -1d);
            }
            else if (e.ClickedItem == btnZero)
            {
                StoreNewValue(0, 0, 0);
            }
            else if (e.ClickedItem == btnZeroX)
            {
                StoreNewValue(0, _vector.Y, _vector.Z);
            }
            else if (e.ClickedItem == btnZeroY)
            {
                StoreNewValue(_vector.X, 0, _vector.Z);
            }
            else if (e.ClickedItem == btnZeroZ)
            {
                StoreNewValue(_vector.X, _vector.Y, 0);
            }
            else if (e.ClickedItem == btnShowToolTip)
            {
                this.ShowToolTip = !btnShowToolTip.Checked;             // note: I turned off CheckOnClick (with that on, I got a feedback loop, and it kept negating itself)
            }
            else if (e.ClickedItem is ToolStripSeparator)
            {
                // Do Nothing
            }
            else
            {
                MessageBox.Show("Menu item is unknown", "Context Menu Click", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
示例#30
0
        private void DrawVelocity(PieMenuDrawButtonArgs e)
        {
            const double MINLENGTHPERCENT = 0d;
            const double MAXLENGTHPERCENT = 1d;
            const double MINTARGET        = 10d;
            const double MAXTARGET        = 250d;

            #region Figure out the length

            // Figure out how long the real velocity will be
            double realVelocity = 0d;

            if (this.ExposedProps.RandomVelocity)
            {
                realVelocity = this.ExposedProps.MaxVelocity * .75d;
            }
            else
            {
                if (this.ExposedProps.Velocity != null && !this.ExposedProps.Velocity.IsZero)
                {
                    realVelocity = this.ExposedProps.Velocity.GetMagnitude();
                }
            }

            // Figure out the velocity to draw
            double velocityPercent = 0d;
            if (realVelocity >= MINLENGTHPERCENT)
            {
                velocityPercent = UtilityCore.GetScaledValue_Capped(MINLENGTHPERCENT, MAXLENGTHPERCENT, MINTARGET, MAXTARGET, realVelocity);
            }

            #endregion

            // Figure out the color
            Color velocityColor = GetGreenRedColor(MINTARGET, MAXTARGET, realVelocity, velocityPercent);

            float halfSize = e.ButtonSize * .5f;

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            if (velocityPercent > 0d)
            {
                #region Draw Vector

                double drawLength = (e.ButtonSize / 2d) * velocityPercent;

                // Draw Vector
                using (Pen vectorPen = new Pen(velocityColor, 2f))
                {
                    vectorPen.StartCap = LineCap.Round; // LineCap.RoundAnchor;
                    vectorPen.EndCap   = LineCap.ArrowAnchor;

                    MyVector vectorLine;
                    if (this.ExposedProps.RandomVelocity)
                    {
                        // Draw a circle underneath
                        using (Pen circlePen = new Pen(SystemColors.ControlDark, 1f))
                        {
                            e.Graphics.DrawEllipse(circlePen, Convert.ToSingle(halfSize - drawLength), Convert.ToSingle(halfSize - drawLength), Convert.ToSingle(drawLength * 2d), Convert.ToSingle(drawLength * 2d));
                        }

                        vectorLine = new MyVector(drawLength, 0, 0);

                        vectorLine.RotateAroundAxis(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(-60d));
                        e.Graphics.DrawLine(vectorPen, halfSize, halfSize, Convert.ToSingle(halfSize + vectorLine.X), Convert.ToSingle(halfSize + vectorLine.Y));

                        vectorLine.RotateAroundAxis(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(-85d));
                        e.Graphics.DrawLine(vectorPen, halfSize, halfSize, Convert.ToSingle(halfSize + vectorLine.X), Convert.ToSingle(halfSize + vectorLine.Y));

                        vectorLine.RotateAroundAxis(new MyVector(0, 0, 1), Utility3D.GetDegreesToRadians(-150d));
                        e.Graphics.DrawLine(vectorPen, halfSize, halfSize, Convert.ToSingle(halfSize + vectorLine.X), Convert.ToSingle(halfSize + vectorLine.Y));
                    }
                    else
                    {
                        vectorLine = this.ExposedProps.Velocity.Clone();
                        vectorLine.BecomeUnitVector();
                        vectorLine.Multiply(drawLength);

                        e.Graphics.DrawLine(vectorPen, halfSize, halfSize, Convert.ToSingle(halfSize + vectorLine.X), Convert.ToSingle(halfSize + vectorLine.Y));
                    }
                }

                #endregion
            }
            else
            {
                e.Graphics.DrawString("Velocity", new Font("Arial", 8), Brushes.Black, 0, e.ButtonSize - 13);
            }
        }