示例#1
0
        public Vector Turn(ClockDirections direction, int degrees)
        {
            if (degrees <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(degrees));
            }

            degrees %= 360;

            var heading = this.Heading;

            switch (direction)
            {
            case ClockDirections.Clockwise:
                heading += degrees;
                if (heading >= 360)
                {
                    heading -= 360;
                }

                break;

            case ClockDirections.CounterClockwise:
                heading -= degrees;
                if (heading < 360)
                {
                    heading += 360;
                }

                break;
            }

            return(new Vector(heading, this.X, this.Y));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sides">3 to 15.</param>
        /// <param name="length">length of each side. 20 to 500 in cm.</param>
        /// <param name="speed">cm/s 10 to 100.</param>
        /// /// <param name="clockDirection">Clock direction.</param>
        public void FlyPolygon(int sides, int length, int speed, ClockDirections clockDirection)
        {
            if (!this.CanManeuver)
            {
                return;
            }

            if (sides < 3 || sides > 15)
            {
                throw new ArgumentOutOfRangeException($"{nameof(sides)} allowed values: 3 to 15");
            }

            this.SetSpeed(speed);

            var turnMethod = default(Action <int>);

            switch (clockDirection)
            {
            case ClockDirections.Clockwise:
                turnMethod = this.TurnClockwise;
                break;

            case ClockDirections.CounterClockwise:
                turnMethod = this.TurnCounterClockwise;
                break;
            }

            var angle = (int)Math.Round(360.0 / sides);

            for (var i = 0; i < sides; ++i)
            {
                this.GoForward(length);
                turnMethod(angle);
            }
        }
示例#3
0
        private static ClockDirections GetGeneralDir(Vector bondVector)
        {
            double bondAngle = Vector.AngleBetween(BasicGeometry.ScreenNorth, bondVector);

            ClockDirections hour = (ClockDirections)BasicGeometry.SnapToClock(bondAngle);

            return(hour);
        }
示例#4
0
        private static ClockDirections GetNewSproutDirection(ClockDirections hour)
        {
            ClockDirections newTag;

            switch (hour)
            {
            case ClockDirections.I:
                newTag = ClockDirections.III;
                break;

            case ClockDirections.II:
                newTag = ClockDirections.IV;
                break;

            case ClockDirections.III:
                newTag = ClockDirections.II;
                break;

            case ClockDirections.IV:
                newTag = ClockDirections.II;
                break;

            case ClockDirections.V:
                newTag = ClockDirections.III;
                break;

            case ClockDirections.VI:
                newTag = ClockDirections.VIII;
                break;

            case ClockDirections.VII:
                newTag = ClockDirections.IX;
                break;

            case ClockDirections.VIII:
                newTag = ClockDirections.X;
                break;

            case ClockDirections.IX:
                newTag = ClockDirections.XI;
                break;

            case ClockDirections.X:
                newTag = ClockDirections.VIII;
                break;

            case ClockDirections.XII:
                newTag = ClockDirections.I;
                break;

            default:
                newTag = ClockDirections.II;
                break;
            }
            return(newTag);
        }
示例#5
0
        /// <summary>
        /// tells you where to put a new atom
        /// </summary>
        /// <param name="lastAtomVisual"></param>
        /// <param name="congestedPositions">Places to avoid dumping the new atom</param>
        /// <returns></returns>
        private (Point NewPos, ClockDirections sproutDir) GetNewChainEndPos(AtomVisual lastAtomVisual)
        {
            ClockDirections GetGeneralDir(Vector bondVector)
            {
                double bondAngle = Vector.AngleBetween(BasicGeometry.ScreenNorth, bondVector);

                ClockDirections hour = (ClockDirections)BasicGeometry.SnapToClock(bondAngle);

                return(hour);
            }

            var    lastAtom = lastAtomVisual.ParentAtom;
            Vector newDirection;

            ClockDirections newTag;

            if (lastAtom.Degree == 0) //isolated atom
            {
                newDirection = ClockDirections.II.ToVector() * EditViewModel.Model.XamlBondLength;
                newTag       = ClockDirections.II;
            }
            else if (lastAtom.Degree == 1)
            {
                Vector bondVector = lastAtom.Position - lastAtom.Neighbours.First().Position;

                var hour = GetGeneralDir(bondVector);

                if (VirginAtom(lastAtom)) //it hasn't yet sprouted
                {
                    //Tag is used to store the direction the atom sprouted from its previous atom
                    newTag       = GetNewSproutDirection(hour);
                    newDirection = newTag.ToVector() * EditViewModel.Model.XamlBondLength;
                }
                else //it has sprouted, so where to put the new branch?
                {
                    var vecA = ((ClockDirections)lastAtom.Tag).ToVector();
                    vecA.Normalize();
                    var vecB = -bondVector;
                    vecB.Normalize();

                    var balancingVector = -(vecA + vecB);
                    balancingVector.Normalize();
                    newTag       = GetGeneralDir(balancingVector);
                    newDirection = balancingVector * EditViewModel.Model.XamlBondLength;
                }
            }
            else if (lastAtom.Degree == 2)
            {
                var balancingVector = lastAtom.BalancingVector();
                balancingVector.Normalize();
                newDirection = balancingVector * EditViewModel.Model.XamlBondLength;
                newTag       = GetGeneralDir(balancingVector);
            }
            else //lastAtom.Degree >= 2:  could get congested
            {
                FindOpenSpace(lastAtom, EditViewModel.Model.XamlBondLength, out newDirection);
                newTag = GetGeneralDir(newDirection);
            }

            return(newDirection + lastAtom.Position, newTag);
        }