Пример #1
0
        protected Vector3D GetDirection_StraightToTarget_VelocityAware2_DebugVisuals(Point3D targetPointWorld, double maxAcceleration)
        {
            if (_shouldShowDebugVisuals && _pointVisualizer_VelAware2 == null)
            {
                #region Visualizer

                // This method has it's own visualizer

                _pointVisualizer_VelAware2 = new PointVisualizer(_viewport, _sharedVisuals, 8);

                _pointVisualizer_VelAware2.SetCustomItemProperties(0, true, Colors.HotPink, .03d);		// chase point
                _pointVisualizer_VelAware2.SetCustomItemProperties(1, false, Colors.Black, 1d);		// direction to go
                _pointVisualizer_VelAware2.SetCustomItemProperties(2, false, Colors.Red, 1d);		// the return vector away
                _pointVisualizer_VelAware2.SetCustomItemProperties(3, false, Colors.Green, .05d);		// velocity along direction to go (the other visualizer's velocity is scaled the same)
                _pointVisualizer_VelAware2.SetCustomItemProperties(4, false, Colors.DarkGoldenrod, .05d);		// this is my max acceleration
                _pointVisualizer_VelAware2.SetCustomItemProperties(5, false, Colors.Cyan, 1d);		// the return vector toward
                _pointVisualizer_VelAware2.SetCustomItemProperties(6, false, Colors.DarkOrchid, 1d);		// distance to stop
                _pointVisualizer_VelAware2.SetCustomItemProperties(7, false, Colors.DarkCyan, 1d);		// attempted turn direction

                #endregion
            }

            // clear off intermitent visuals (the ones that don't update every frame will appear to hang if I don't clean them up)
            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(2, new Point3D(), new Vector3D());
                _pointVisualizer_VelAware2.Update(4, new Point3D(), new Vector3D());
                _pointVisualizer_VelAware2.Update(5, new Point3D(), new Vector3D());
                _pointVisualizer_VelAware2.Update(6, new Point3D(), new Vector3D());
                _pointVisualizer_VelAware2.Update(7, new Point3D(), new Vector3D());
            }

            Point3D positionWorld = _physicsBody.PositionToWorld(_physicsBody.CenterOfMass);

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(0, targetPointWorld);
                if (Ship.DEBUGSHOWSACCELERATION)
                {
                    _pointVisualizer_VelAware2.Update(4, positionWorld, _physicsBody.DirectionToWorld(new Vector3D(maxAcceleration, 0, 0)));
                }
            }

            // Convert everything to local coords
            Point3D position = _physicsBody.CenterOfMass;
            Point3D targetPointLocal = _physicsBody.PositionFromWorld(targetPointWorld);

            Vector3D directionToGo = targetPointLocal.ToVector() - position.ToVector();
            double distanceToGo = directionToGo.Length;

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(1, positionWorld, _physicsBody.DirectionToWorld(directionToGo));
            }

            if (Math3D.IsNearZero(directionToGo))
            {
                // Just sit here
                return new Vector3D(0, 0, 0);
            }

            Vector3D currentVelocity = this.VelocityWorld;

            if (Math1D.IsNearZero(currentVelocity.LengthSquared))
            {
                #region Currently Stopped

                if (Math1D.IsNearZero(directionToGo.LengthSquared))
                {
                    // Already sitting on the target.  STAY!!!
                    return new Vector3D(0, 0, 0);
                }
                else
                {
                    // I'm currently stopped.  Gun it straight toward the target
                    return directionToGo.ToUnit();
                }

                #endregion
            }

            #region Adjust for current velocity

            // I think this description is too complex

            // I need to a few things:
            //     Figure out how fast I can be approaching the point, and still be able to stop on it
            //         if too fast, negate the velocity that is along the direction of the target
            //
            //     If there is left over thrust, remove as much velocity as possible that is not in the direction to the target
            //
            //     If there is left over thrust, use the remainder to speed up (unless I'm already at the max velocity, then just coast)


            // Turn this into local coords
            currentVelocity = _physicsBody.DirectionFromWorld(currentVelocity);

            Vector3D currentVelocityAlongDirectionLine = currentVelocity.GetProjectedVector(directionToGo);

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(3, positionWorld, _physicsBody.DirectionToWorld(currentVelocityAlongDirectionLine));
            }

            double currentSpeed = currentVelocityAlongDirectionLine.Length;

            // If going away from the target, then there is no need to slow down
            double distanceToStop = -1d;
            if (Vector3D.DotProduct(currentVelocityAlongDirectionLine, directionToGo) > 0)
            {
                // Calculate max velocity
                // t = (v1 - v0) / a
                // v1 will need to be zero, v0 is the current velocity, a is negative.  so I can just take initial velocity / acceleration
                double timeToStop = currentSpeed / maxAcceleration;

                // Now that I know how long it will take to stop, figure out how far I'll go in that time under constant acceleration
                // d = vt + 1/2 at^2
                // I'll let the vt be zero and acceleration be positive to make things cleaner
                distanceToStop = .5 * maxAcceleration * timeToStop * timeToStop;

                if (_shouldShowDebugVisuals)
                {
                    Vector3D vectToStop = directionToGo;
                    vectToStop.Normalize();
                    vectToStop *= distanceToStop;
                    _pointVisualizer_VelAware2.Update(6, positionWorld, _physicsBody.DirectionToWorld(vectToStop));
                }
            }

            bool suppress5 = false;

            if (distanceToStop > distanceToGo)
            {
                #region Brakes directly away from the target

                //TODO:  Take in the magnitude to use

                //directionToGo *= -3d;   // I'll give this a higher than normal priority (I still want to keep the highest priority with obstacle avoidance)
                //directionToGo *= -.25d;

                // If the difference between stop distance and distance to go is very small, then don't use full thrust.  It causes the bot to jitter back and forth
                double brakesPercent = GetEdgePercentAcceleration(distanceToStop - distanceToGo, maxAcceleration);

                // Reverse the thrust
                directionToGo.Normalize();
                directionToGo *= -1d * brakesPercent;

                if (_shouldShowDebugVisuals)
                {
                    suppress5 = true;
                    _pointVisualizer_VelAware2.Update(2, positionWorld, _physicsBody.DirectionToWorld(directionToGo));
                }

                #endregion
            }
            else
            {
                #region Accelrate toward target (negating tangent speed)

                // Figure out how fast I could safely be going toward the target
                // If I accelerate full force, will I exceed that?  (who cares, speed up, and let the next frame handle that)

                Vector3D axis;
                double radians;
                Math3D.GetRotation(out axis, out radians, directionToGo, currentVelocity);

                // This is how much to rotate direction to align with current velocity, I want to go against the current velocity (if aligned,
                // the angle will be zero, so negating won't make a difference)
                radians *= -1;

                //if (Math3D.IsNearZero(radians) || Math3D.IsNearValue(radians, PI_DIV_TWO) || Math3D.IsNearValue(radians, Math.PI))
                //{
                //    // No modification needed (I don't think this if statement is really needed)
                //}

                if (Math1D.IsNearValue(radians, Math.PI))
                {
                    // Flying directly away from the target.  Turn around
                    directionToGo = currentVelocity * -1d;
                }
                //else if (Math.Abs(radians) < PI_DIV_TWO)
                //else if (Math.Abs(radians) < PI_DIV_FOUR)		// between 45 and 90 gets too extreme
                else if (Math.Abs(radians) < RADIANS_60DEG)
                {
                    // Change the direction by the angle
                    directionToGo = directionToGo.GetRotatedVector(axis, Math1D.RadiansToDegrees(radians));
                }
                else
                {
                    if (_shouldShowDebugVisuals)
                    {
                        Vector3D vectTryTurn = directionToGo.GetRotatedVector(axis, Math1D.RadiansToDegrees(radians));
                        vectTryTurn.Normalize();
                        _pointVisualizer_VelAware2.Update(7, positionWorld, _physicsBody.DirectionToWorld(vectTryTurn));
                    }

                    //double actualRadians = PI_DIV_FOUR;
                    double actualRadians = RADIANS_60DEG;
                    if (radians < 0)
                    {
                        actualRadians *= -1d;
                    }

                    directionToGo = directionToGo.GetRotatedVector(axis, Math1D.RadiansToDegrees(actualRadians));
                }


                //else if (Math.Abs(radians) >= PI_DIV_TWO)
                //{
                //    // I used to stop in this case.  It is most efficient, but looks really odd (I want the swarmbot to flow more instead of stalling out,
                //    // and then charging off).  So I'll try rotating by 90 degrees

                //    if (_shouldShowDebugVisuals)
                //    {
                //        Vector3D vectTryTurn = directionToGo.GetRotatedVector(axis, Math3D.RadiansToDegrees(radians));
                //        vectTryTurn.Normalize();
                //        _pointVisualizer_VelAware2.Update(7, positionWorld, _physicsBody.DirectionToWorld(vectTryTurn));

                //    }


                //    directionToGo = currentVelocity * -1d;

                //}


                //else if (Math.Abs(radians) >= PI_DIV_TWO)
                //{
                //    // The velocity is more than 90 degrees from where I want to go.  By applying a force exactly opposite of the current
                //    // velocity, I will negate the velocity that orthogonal to the desired direction, as well as slow down the bot

                //    //TODO:  This gives an unnatural flight.  Don't fully stop before charging toward the chase point

                //    directionToGo = currentVelocity * -1d;
                //}


                double percentThrust = GetEdgePercentAcceleration(distanceToGo - distanceToStop, maxAcceleration);

                //TODO:  Do partial thrust similar to the fly away logic

                directionToGo.Normalize();
                directionToGo *= percentThrust;

                #endregion
            }

            #endregion

            if (_shouldShowDebugVisuals && !suppress5)
            {
                _pointVisualizer_VelAware2.Update(5, positionWorld, _physicsBody.DirectionToWorld(directionToGo));
            }

            // Exit Function
            return directionToGo;
        }
Пример #2
0
        /// <summary>
        /// The derived class should modify the thruster settings before calling base.WorldUpdating
        /// </summary>
        public virtual void WorldUpdating()
        {
            #region Visuals

            _core.Transform = _physicsBody.Transform;

            #endregion

            #region Thrust Line

            if (_shouldDrawThrustLine)
            {
                _thruster.DrawVisual(_thrustPercent, _physicsBody.Transform, _thrustTransform);
            }

            #endregion

            #region Debug Visuals

            if (_shouldShowDebugVisuals)
            {
                if (_pointVisualizer == null)
                {
                    _pointVisualizer = new PointVisualizer(_viewport, _sharedVisuals, _physicsBody);
                    _pointVisualizer.ShowPosition = false;
                    _pointVisualizer.ShowVelocity = true;
                    _pointVisualizer.ShowAcceleration = Ship.DEBUGSHOWSACCELERATION;
                    _pointVisualizer.VelocityAccelerationLengthMultiplier = .05d;		// this is the same as the ship's
                }

                _pointVisualizer.Update();
            }

            #endregion
        }
Пример #3
0
        /// <summary>
        /// This one won't let the bot come at the target too fast (and tries to match the target's velocity)
        /// </summary>
        protected Vector3D GetDirection_InterceptTarget_VelocityAware(Point3D targetPointWorld, Vector3D targetVelocityWorld, double maxAcceleration)
        {
            const double DOT_POSTOTHESIDE = .5d;
            const double DOT_VELORTH = .5d;
            const double TOOFARTIME = 4d;		// if it takes longer than this to get to the point, then just chase it directly
            const bool SHOULDREVERSETHRUSTWHENAPPROPRIATE = true;		// true:  just reverse thrust, false: turn toward chase point (not as efficient, but looks more like flight)

            if (_shouldShowDebugVisuals && _pointVisualizer_VelAware3 == null)
            {
                #region Visualizer

                // This method has it's own visualizer

                _pointVisualizer_VelAware3 = new PointVisualizer(_viewport, _sharedVisuals, 5);

                _pointVisualizer_VelAware3.SetCustomItemProperties(0, true, Colors.HotPink, .03d);		// chase point
                _pointVisualizer_VelAware3.SetCustomItemProperties(1, false, Colors.DarkGoldenrod, .05d);		// this is my max acceleration
                _pointVisualizer_VelAware3.SetCustomItemProperties(2, false, Colors.DarkOrchid, 1d);		// projected chase point1
                _pointVisualizer_VelAware3.SetCustomItemProperties(3, false, Colors.Orchid, 1d);		// projected chase point2
                _pointVisualizer_VelAware3.SetCustomItemProperties(4, true, Colors.Red, .1d);		// unchased point

                #endregion
            }

            // clear off intermitent visuals (the ones that don't update every frame will appear to hang if I don't clean them up)
            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware3.Update(1, new Point3D(), new Vector3D());
                _pointVisualizer_VelAware3.Update(4, new Point3D());
            }

            Point3D positionLocal = _physicsBody.CenterOfMass;
            Point3D positionWorld = _physicsBody.PositionToWorld(positionLocal);

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware3.Update(0, targetPointWorld);
                if (Ship.DEBUGSHOWSACCELERATION)
                {
                    _pointVisualizer_VelAware3.Update(1, positionWorld, _physicsBody.DirectionToWorld(new Vector3D(maxAcceleration, 0, 0)));
                }
            }

            // Get some general vectors
            Point3D targetPointLocal = _physicsBody.PositionFromWorld(targetPointWorld);
            Vector3D targetVelocityLocal = _physicsBody.DirectionFromWorld(targetVelocityWorld);

            Vector3D directionToGo = targetPointLocal.ToVector() - positionLocal.ToVector();
            double distanceToGo = directionToGo.Length;

            Vector3D velocityLocal = _physicsBody.DirectionFromWorld(_physicsBody.VelocityCached);

            #region Get approximate intercept point

            // Get time to point
            double interceptTime1 = GetInterceptTime(targetPointWorld, positionWorld, _physicsBody.VelocityCached, maxAcceleration);

            // Project where the chase point will be at that time
            Point3D targetPointWorld1 = targetPointWorld + (targetVelocityWorld * interceptTime1);

            // Get the intercept time for this second point
            double interceptTime2 = GetInterceptTime(targetPointWorld1, positionWorld, _physicsBody.VelocityCached, maxAcceleration);

            // Project again
            Point3D targetPointWorld2 = targetPointWorld + (targetVelocityWorld * interceptTime2);

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware3.Update(2, positionWorld, targetPointWorld1 - positionWorld);
                _pointVisualizer_VelAware3.Update(3, positionWorld, targetPointWorld2 - positionWorld);
            }

            #endregion

            if (interceptTime1 > TOOFARTIME)
            {
                // Simplifying if too far away
                return GetDirection_StraightToTarget_VelocityAware2(targetPointWorld2, maxAcceleration);
            }

            #region Determine relative positions/velocities

            // Dot product of my velocity with chase point location
            Vector3D velocityLocalUnit = velocityLocal.ToUnit();
            Vector3D directionToGoUnit = directionToGo.ToUnit();
            double velDotDir = Vector3D.DotProduct(velocityLocalUnit, directionToGoUnit);

            // Dot product of my velocity with chase velocity
            Vector3D targetVelocityLocalUnit = targetVelocityLocal.ToUnit();
            double velDotVel = Vector3D.DotProduct(velocityLocalUnit, targetVelocityLocalUnit);

            //NOTE:  In several conditions, it's a toss up whether the swarm bot should turn around, or reverse thrust.  This should be a member
            // level boolean

            if (velDotDir > DOT_POSTOTHESIDE)
            {
                if (velDotVel > DOT_POSTOTHESIDE)
                {
                    #region Point is in front & Traveling in the same direction

                    // Make a modified version of speed aware 2, and head directly for the chase point, trying to match velocity
                    //
                    // Also may want to try to shoot for a bit in front of them

                    #endregion
                }
                else if (velDotVel > -DOT_POSTOTHESIDE)
                {
                    #region Point is in front & Traveling orthoganal

                    // I've found when dogfighting, that I don't want to go to where they are now, I want to follow the path they've taken so I can
                    // run up their rear.
                    //
                    // So project a point behind them and go for that
                    //
                    // I probably want to do a hybrid between going directly behind them, and going for the chase point


                    #endregion
                }
                else
                {
                    #region Point is in front & Traveling in opposite directions

                    // Go straight for them, then reverse thrust in time so they run into me (sort of playing chicken)

                    #endregion
                }
            }
            else if (velDotDir > -DOT_POSTOTHESIDE)
            {
                if (velDotVel > DOT_POSTOTHESIDE)
                {
                    #region Point is to the side & Traveling in the same direction

                    // Don't turn toward them, just slide over to them (match the velocity along their direction of travel, and use the remaining
                    // thrust to shoot to the side

                    #endregion
                }
                else if (velDotVel > -DOT_POSTOTHESIDE)
                {
                    #region Point is to the side & Traveling orthoganal

                    // Turn toward them (call speed aware 2 going straight for the chase point)

                    #endregion
                }
                else
                {
                    #region Point is to the side & Traveling in opposite directions

                    // Either:
                    //		turn toward it
                    //		or reverse thrust and eventually get to the point where you can slide up to it

                    #endregion
                }
            }
            else
            {
                if (velDotVel > DOT_POSTOTHESIDE)
                {
                    #region Point is behind & Traveling in the same direction

                    // Get in front of them, then either just slow down, or reverse thrust toward them until they're close enough to reverse thrust again

                    #endregion
                }
                else if (velDotVel > -DOT_POSTOTHESIDE)
                {
                    #region Point is behind & Traveling orthoganal

                    // Turn toward them (similar case with "Point is to the side & Traveling orthoganal"?)

                    #endregion
                }
                else
                {
                    #region Point is behind & Traveling in opposite directions

                    // Reverse thrust

                    #endregion
                }
            }

            #endregion







            return GetDirection_StraightToTarget_VelocityAware2(targetPointWorld2, maxAcceleration);








            _pointVisualizer_VelAware3.Update(4, targetPointWorld);
            return new Vector3D();
        }
Пример #4
0
        /// <summary>
        /// This goes straight for the chase point, and tries to be going at the target's velocity when it's at the target point
        /// </summary>
        /// <remarks>
        /// The difference between this method and intercept is that this always goes straight for the point it's told to, fully
        /// turning if nessassary.  Intercept tries to calculate the best way to intercept, possibly chasing after a derived point.
        /// </remarks>
        protected Vector3D GetDirection_StraightToTarget_VelocityAware2(Point3D targetPointWorld, Vector3D targetVelocityWorld, double maxAcceleration)
        {
            if (_shouldShowDebugVisuals && _pointVisualizer_VelAware2 == null)
            {
                #region Visualizer

                // This method has it's own visualizer

                _pointVisualizer_VelAware2 = new PointVisualizer(_viewport, _sharedVisuals, 4);

                _pointVisualizer_VelAware2.SetCustomItemProperties(0, true, Colors.HotPink, .03d);		// chase point
                _pointVisualizer_VelAware2.SetCustomItemProperties(1, false, Colors.Black, 1d);		// direction to go
                _pointVisualizer_VelAware2.SetCustomItemProperties(2, false, Colors.Green, .05d);		// velocity along direction to go (the other visualizer's velocity is scaled the same)
                _pointVisualizer_VelAware2.SetCustomItemProperties(3, false, Colors.DarkOrchid, 1d);		// distance to stop

                #endregion
            }

            if (_shouldShowDebugVisuals)
            {
                // clear intermittant lines
                _pointVisualizer_VelAware2.Update(3, new Point3D(), new Vector3D());

                _pointVisualizer_VelAware2.Update(0, targetPointWorld);
            }

            // Convert everything to local coords
            Point3D position = _physicsBody.CenterOfMass;
            Point3D targetPointLocal = _physicsBody.PositionFromWorld(targetPointWorld);
            Vector3D targetVelocityLocal = _physicsBody.DirectionFromWorld(targetVelocityWorld);

            Vector3D directionToGo = targetPointLocal.ToVector() - position.ToVector();
            double distanceToGo = directionToGo.Length;

            Vector3D currentVelocity = _physicsBody.DirectionFromWorld(this.VelocityWorld);

            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(1, PositionWorld, _physicsBody.DirectionToWorld(directionToGo));
            }

            if (Math3D.IsNearZero(directionToGo) && Math3D.IsNearZero(currentVelocity - targetVelocityLocal))
            {
                // Already on the point, moving along the same vector
                return new Vector3D(0, 0, 0);
            }

            // I think this description is too complex

            // I need to a few things:
            //     Figure out how fast I can be approaching the point, and still be able to stop on it
            //         if too fast, negate the velocity that is along the direction of the target
            //
            //     If there is left over thrust, remove as much velocity as possible that is not in the direction to the target
            //
            //     If there is left over thrust, use the remainder to speed up (unless I'm already at the max velocity, then just coast)



            //directionToGo += targetVelocityLocal;		// try adding the two, and see if that's good - this doesn't work, they units are far too different


            Vector3D currentVelocityAlongDirectionLine = currentVelocity.GetProjectedVector(directionToGo);
            double currentSpeedAlongDirectionLine = currentVelocityAlongDirectionLine.Length;

            //Vector3D currentVelocityAlongTargetVelocity = currentVelocity.GetProjectedVector(targetVelocityLocal);		// I don't see how this helps
            //double currentSpeedAlongTargetVelocity = currentVelocityAlongTargetVelocity.Length;

            Vector3D targetVelocityAlongDirectionLine = targetVelocityLocal.GetProjectedVector(directionToGo);
            double targetSpeedAlongDirectionLine = targetVelocityAlongDirectionLine.Length;


            if (_shouldShowDebugVisuals)
            {
                _pointVisualizer_VelAware2.Update(2, PositionWorld, _physicsBody.DirectionToWorld(currentVelocityAlongDirectionLine));
            }


            // If going away from the target, then there is no need to slow down
            double distanceToStop = -1d;
            if (Vector3D.DotProduct(currentVelocityAlongDirectionLine, directionToGo) > 0)
            {
                // Calculate max velocity
                // t = (v1 - v0) / a
                // v1 will need to be zero, v0 is the current velocity, a is negative.  so I can just take initial velocity / acceleration
                double timeToStop = currentSpeedAlongDirectionLine / maxAcceleration;

                // Now including the portion of the target's velocity along the direction
                //double timeToStop = (currentSpeedAlongDirectionLine + targetSpeedAlongDirectionLine) / maxAcceleration;		// this fails pretty badly too (try taking the greater of the two speeds?)

                // Now that I know how long it will take to stop, figure out how far I'll go in that time under constant acceleration
                // d = vt + 1/2 at^2
                // I'll let the vt be zero and acceleration be positive to make things cleaner
                distanceToStop = .5 * maxAcceleration * timeToStop * timeToStop;

                if (_shouldShowDebugVisuals)
                {
                    Vector3D vectToStop = directionToGo;
                    vectToStop.Normalize();
                    vectToStop *= distanceToStop;
                    _pointVisualizer_VelAware2.Update(3, PositionWorld, _physicsBody.DirectionToWorld(vectToStop));
                }
            }


            // distance and time to stop are to get stopped.  Now I have to leave some leeway for target velocity???


            if (distanceToStop > distanceToGo)
            {
                #region Brakes directly away from the target

                //TODO:  Take in the magnitude to use

                //directionToGo *= -3d;   // I'll give this a higher than normal priority (I still want to keep the highest priority with obstacle avoidance)
                //directionToGo *= -.25d;

                // If the difference between stop distance and distance to go is very small, then don't use full thrust.  It causes the bot to jitter back and forth
                double brakesPercent = GetEdgePercentAcceleration(distanceToStop - distanceToGo, maxAcceleration);

                // Reverse the thrust
                directionToGo.Normalize();
                directionToGo *= -1d * brakesPercent;

                #endregion
            }
            else
            {
                #region Accelrate toward target (negating tangent speed)

                // Figure out how fast I could safely be going toward the target
                // If I accelerate full force, will I exceed that?  (who cares, speed up, and let the next frame handle that)

                Vector3D axis;
                double radians;
                Math3D.GetRotation(out axis, out radians, directionToGo, currentVelocity);

                // This is how much to rotate direction to align with current velocity, I want to go against the current velocity (if aligned,
                // the angle will be zero, so negating won't make a difference)
                radians *= -1;

                //if (Math3D.IsNearZero(radians) || Math3D.IsNearValue(radians, PI_DIV_TWO) || Math3D.IsNearValue(radians, Math.PI))
                //{
                //    // No modification needed (I don't think this if statement is really needed)
                //}

                if (Math1D.IsNearValue(radians, Math.PI))
                {
                    // Flying directly away from the target.  Turn around
                    directionToGo = currentVelocity * -1d;
                }
                else if (Math.Abs(radians) < RADIANS_60DEG)		// PI_DIV_TWO is waiting too long, PI_DIV_FOUR is capping off too early
                {
                    // Change the direction by the angle
                    directionToGo = directionToGo.GetRotatedVector(axis, Math1D.RadiansToDegrees(radians));
                }
                //else if (Math.Abs(radians) >= PI_DIV_TWO)
                //{
                //    // The velocity is more than 90 degrees from where I want to go.  By applying a force exactly opposite of the current
                //    // velocity, I will negate the velocity that's orthogonal to the desired direction, as well as slow down the bot
                //
                //    // I used to stop in this case.  It is most efficient, but looks really odd (I want the swarmbot to flow more instead of stalling out,
                //    // and then charging off).  So I don't rotate more than 60 degrees now
                //    directionToGo = currentVelocity * -1d;
                //}
                else
                {
                    double actualRadians = RADIANS_60DEG;
                    if (radians < 0)
                    {
                        actualRadians *= -1d;
                    }

                    directionToGo = directionToGo.GetRotatedVector(axis, Math1D.RadiansToDegrees(actualRadians));
                }

                // Don't jitter back and forth at full throttle when at the boundry
                double percentThrust = GetEdgePercentAcceleration(distanceToGo - distanceToStop, maxAcceleration);

                directionToGo.Normalize();
                directionToGo *= percentThrust;

                #endregion
            }

            // Exit Function
            return directionToGo;
        }
Пример #5
0
        private void ChangeSwarmBots(SwarmFormation formation)
        {
            ChangeSwarmBotsSprtRemoveAll();

            if (formation == SwarmFormation.None)
            {
                _swarmbotFormation = SwarmFormation.None;
                return;
            }

            double startAngle, stepAngle;       // 0 is straight in front of the ship
            int numBots;
            double distanceMult;

            switch (formation)
            {
                case SwarmFormation.AllFront:
                    #region AllFront

                    startAngle = 0d;
                    stepAngle = 360d;

                    //numBots = 20;
                    numBots = _numSwarmbots;

                    distanceMult = 8d;

                    #endregion
                    break;

                case SwarmFormation.AllRear:
                    #region AllRear

                    startAngle = 180d;
                    stepAngle = 360d;

                    //numBots = 20;
                    numBots = _numSwarmbots;

                    distanceMult = 8d;

                    #endregion
                    break;

                case SwarmFormation.Triangle:
                    #region Triangle

                    startAngle = 0d;
                    stepAngle = 120d;

                    //numBots = 10;
                    numBots = _numSwarmbots / 3;
                    if (numBots % 3 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.ReverseTriangle:
                    #region ReverseTriangle

                    startAngle = 180d;
                    stepAngle = 120d;

                    //numBots = 10;
                    numBots = _numSwarmbots / 3;
                    if (numBots % 3 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.Pentagon:
                    #region Pentagon

                    startAngle = 0d;
                    stepAngle = 72d;

                    //numBots = 7;
                    numBots = _numSwarmbots / 5;
                    if (numBots % 5 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.ReversePentagon:
                    #region ReversePentagon

                    startAngle = 180d;
                    stepAngle = 72d;

                    //numBots = 7;
                    numBots = _numSwarmbots / 5;
                    if (numBots % 5 != 0 || numBots == 0)
                    {
                        numBots++;
                    }

                    distanceMult = 9d;

                    #endregion
                    break;

                case SwarmFormation.SurroundShip:
                    #region SurroundShip

                    startAngle = 0d;
                    stepAngle = 360d;

                    //numBots = 30;
                    numBots = _numSwarmbots;

                    distanceMult = 0d;

                    #endregion
                    break;

                default:
                    throw new ApplicationException("Unknown SwarmFormation: " + formation.ToString());
            }

            // Figure out how far away from the ship the bots should be
            double chaseOffsetDistance = (_radiusX + _radiusY) / 2d;
            chaseOffsetDistance *= distanceMult;

            // Build the swarms
            double angle = startAngle;
            while (angle < startAngle + 360d)
            {
                Vector3D chasePoint = new Vector3D(0, chaseOffsetDistance, 0);
                chasePoint = chasePoint.GetRotatedVector(new Vector3D(0, 0, 1), angle);

                _swarmBots.Add(ChangeSwarmBotsSprtSwarm(numBots, chasePoint));
                _swarmbotChasePoints.Add(chasePoint.ToPoint());

                PointVisualizer chasePointSprite = new PointVisualizer(_map.Viewport, _sharedVisuals);
                chasePointSprite.PositionRadius = .1d;
                chasePointSprite.VelocityAccelerationLengthMultiplier = .05d;
                chasePointSprite.ShowPosition = _showDebugVisuals;
                chasePointSprite.ShowVelocity = _showDebugVisuals;
                chasePointSprite.ShowAcceleration = _showDebugVisuals && DEBUGSHOWSACCELERATION;
                _swarmbotChasePointSprites.Add(chasePointSprite);

                angle += stepAngle;
            }

            _swarmbotFormation = formation;
        }
Пример #6
0
        private void ChangeSwarmBots(SwarmFormation formation)
        {
            ChangeSwarmBotsSprtRemoveAll();

            if (formation == SwarmFormation.None)
            {
                _swarmbotFormation = SwarmFormation.None;
                return;
            }

            double startAngle, stepAngle;       // 0 is straight in front of the ship
            int    numBots;
            double distanceMult;

            switch (formation)
            {
            case SwarmFormation.AllFront:
                #region AllFront

                startAngle = 0d;
                stepAngle  = 360d;

                //numBots = 20;
                numBots = _numSwarmbots;

                distanceMult = 8d;

                #endregion
                break;

            case SwarmFormation.AllRear:
                #region AllRear

                startAngle = 180d;
                stepAngle  = 360d;

                //numBots = 20;
                numBots = _numSwarmbots;

                distanceMult = 8d;

                #endregion
                break;

            case SwarmFormation.Triangle:
                #region Triangle

                startAngle = 0d;
                stepAngle  = 120d;

                //numBots = 10;
                numBots = _numSwarmbots / 3;
                if (numBots % 3 != 0 || numBots == 0)
                {
                    numBots++;
                }

                distanceMult = 9d;

                #endregion
                break;

            case SwarmFormation.ReverseTriangle:
                #region ReverseTriangle

                startAngle = 180d;
                stepAngle  = 120d;

                //numBots = 10;
                numBots = _numSwarmbots / 3;
                if (numBots % 3 != 0 || numBots == 0)
                {
                    numBots++;
                }

                distanceMult = 9d;

                #endregion
                break;

            case SwarmFormation.Pentagon:
                #region Pentagon

                startAngle = 0d;
                stepAngle  = 72d;

                //numBots = 7;
                numBots = _numSwarmbots / 5;
                if (numBots % 5 != 0 || numBots == 0)
                {
                    numBots++;
                }

                distanceMult = 9d;

                #endregion
                break;

            case SwarmFormation.ReversePentagon:
                #region ReversePentagon

                startAngle = 180d;
                stepAngle  = 72d;

                //numBots = 7;
                numBots = _numSwarmbots / 5;
                if (numBots % 5 != 0 || numBots == 0)
                {
                    numBots++;
                }

                distanceMult = 9d;

                #endregion
                break;

            case SwarmFormation.SurroundShip:
                #region SurroundShip

                startAngle = 0d;
                stepAngle  = 360d;

                //numBots = 30;
                numBots = _numSwarmbots;

                distanceMult = 0d;

                #endregion
                break;

            default:
                throw new ApplicationException("Unknown SwarmFormation: " + formation.ToString());
            }

            // Figure out how far away from the ship the bots should be
            double chaseOffsetDistance = (_radiusX + _radiusY) / 2d;
            chaseOffsetDistance *= distanceMult;

            // Build the swarms
            double angle = startAngle;
            while (angle < startAngle + 360d)
            {
                Vector3D chasePoint = new Vector3D(0, chaseOffsetDistance, 0);
                chasePoint = chasePoint.GetRotatedVector(new Vector3D(0, 0, 1), angle);

                _swarmBots.Add(ChangeSwarmBotsSprtSwarm(numBots, chasePoint));
                _swarmbotChasePoints.Add(chasePoint.ToPoint());

                PointVisualizer chasePointSprite = new PointVisualizer(_map.Viewport, _sharedVisuals);
                chasePointSprite.PositionRadius = .1d;
                chasePointSprite.VelocityAccelerationLengthMultiplier = .05d;
                chasePointSprite.ShowPosition     = _showDebugVisuals;
                chasePointSprite.ShowVelocity     = _showDebugVisuals;
                chasePointSprite.ShowAcceleration = _showDebugVisuals && DEBUGSHOWSACCELERATION;
                _swarmbotChasePointSprites.Add(chasePointSprite);

                angle += stepAngle;
            }

            _swarmbotFormation = formation;
        }